vendor: OpenCV 5.0.0 snapshot at 40738fb16ceddb5fb3fea747585f7ce6abb0605b

This commit is contained in:
Gitea Mirror Bot
2026-08-22 00:10:33 +08:00
commit f7f077da11
6933 changed files with 2335208 additions and 0 deletions
+103
View File
@@ -0,0 +1,103 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
//
// Copyright (C) 2017, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
#include "test_precomp.hpp"
#include "npy_blob.hpp"
namespace cv
{
static std::string getType(const std::string& header)
{
std::string field = "'descr':";
int idx = header.find(field);
CV_Assert(idx != -1);
int from = header.find('\'', idx + field.size()) + 1;
int to = header.find('\'', from);
return header.substr(from, to - from);
}
static std::string getFortranOrder(const std::string& header)
{
std::string field = "'fortran_order':";
int idx = header.find(field);
CV_Assert(idx != -1);
int from = header.find_last_of(' ', idx + field.size()) + 1;
int to = header.find(',', from);
return header.substr(from, to - from);
}
static std::vector<int> getShape(const std::string& header)
{
std::string field = "'shape':";
int idx = header.find(field);
CV_Assert(idx != -1);
int from = header.find('(', idx + field.size()) + 1;
int to = header.find(')', from);
std::string shapeStr = header.substr(from, to - from);
if (shapeStr.empty())
return std::vector<int>(1, 1);
// Remove all commas.
shapeStr.erase(std::remove(shapeStr.begin(), shapeStr.end(), ','),
shapeStr.end());
std::istringstream ss(shapeStr);
int value;
std::vector<int> shape;
while (ss >> value)
{
shape.push_back(value);
}
return shape;
}
Mat blobFromNPY(const std::string& path)
{
std::ifstream ifs(path.c_str(), std::ios::binary);
CV_Assert(ifs.is_open());
std::string magic(6, '*');
ifs.read(&magic[0], magic.size());
CV_Assert(magic == "\x93NUMPY");
ifs.ignore(1); // Skip major version byte.
ifs.ignore(1); // Skip minor version byte.
unsigned short headerSize;
ifs.read((char*)&headerSize, sizeof(headerSize));
std::string header(headerSize, '*');
ifs.read(&header[0], header.size());
// Extract data type.
int matType;
if (getType(header) == "<f4")
matType = CV_32F;
else if (getType(header) == "<i4")
matType = CV_32S;
else if (getType(header) == "<i8")
matType = CV_64S;
else
CV_Error(Error::BadDepth, "Unsupported numpy type");
CV_Assert(getFortranOrder(header) == "False");
std::vector<int> shape = getShape(header);
Mat blob(shape, matType);
ifs.read((char*)blob.data, blob.total() * blob.elemSize());
CV_Assert((size_t)ifs.gcount() == blob.total() * blob.elemSize());
return blob;
}
} // namespace cv
+20
View File
@@ -0,0 +1,20 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
//
// Copyright (C) 2017, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
#ifndef __OPENCV_DNN_TEST_NPY_BLOB_HPP__
#define __OPENCV_DNN_TEST_NPY_BLOB_HPP__
namespace cv
{
// Parse serialized NumPy array by np.save(...)
// Based on specification of .npy data format.
Mat blobFromNPY(const std::string& path);
}
#endif
File diff suppressed because it is too large Load Diff
+153
View File
@@ -0,0 +1,153 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "test_precomp.hpp"
#include "npy_blob.hpp"
#include <opencv2/dnn/shape_utils.hpp>
#include <set>
namespace opencv_test { namespace {
template<typename TString>
static std::string _tf(TString filename)
{
return findDataFile(std::string("dnn/") + filename);
}
class Test_Caffe_nets : public DNNTestLayer
{
public:
void testFaster(const std::string& proto, const std::string& model, const Mat& ref,
double scoreDiff = 0.0, double iouDiff = 0.0)
{
checkBackend();
Net net = readNet(findDataFile("dnn/" + proto),
findDataFile("dnn/" + model, false));
net.setPreferableBackend(backend);
net.setPreferableTarget(target);
if (target == DNN_TARGET_CPU_FP16)
net.enableWinograd(false);
Mat img = imread(findDataFile("dnn/dog416.png"));
resize(img, img, Size(800, 600));
Mat blob = blobFromImage(img, 1.0, Size(), Scalar(102.9801, 115.9465, 122.7717), false, false);
Mat imInfo = (Mat_<float>(1, 3) << img.rows, img.cols, 1.6f);
net.setInput(blob);
net.setInput(imInfo, "im_info");
// Output has shape 1x1xNx7 where N - number of detections.
// An every detection is a vector of values [id, classId, confidence, left, top, right, bottom]
Mat out = net.forward();
scoreDiff = scoreDiff ? scoreDiff : default_l1;
iouDiff = iouDiff ? iouDiff : default_lInf;
normAssertDetections(ref, out, ("model name: " + model).c_str(), 0.8, scoreDiff, iouDiff);
}
};
TEST(Reproducibility_SSD, Accuracy)
{
applyTestTag(
CV_TEST_TAG_MEMORY_512MB,
CV_TEST_TAG_DEBUG_VERYLONG
);
// The classic engine importer no longer carries the Caffe-SSD specific
// handling (LpNormalization/DetectionOutput); this model is supported on
// the new engine only.
auto engine_forced = static_cast<cv::dnn::EngineType>(
cv::utils::getConfigurationParameterSizeT("OPENCV_FORCE_DNN_ENGINE", cv::dnn::ENGINE_AUTO));
if (engine_forced == cv::dnn::ENGINE_CLASSIC)
{
applyTestTag(CV_TEST_TAG_DNN_SKIP_PARSER);
return;
}
Net net = readNetFromONNX(findDataFile("dnn/onnx/models/ssd_vgg16.onnx", false));
ASSERT_FALSE(net.empty());
net.setPreferableBackend(DNN_BACKEND_OPENCV);
Mat sample = imread(_tf("street.png"));
ASSERT_TRUE(!sample.empty());
if (sample.channels() == 4)
cvtColor(sample, sample, COLOR_BGRA2BGR);
Mat in_blob = blobFromImage(sample, 1.0f, Size(300, 300), Scalar(), false);
net.setInput(in_blob);
Mat out = net.forward();
Mat ref = blobFromNPY(_tf("ssd_out.npy"));
normAssertDetections(ref, out, "", 0.06, 1e-4, 0.18);
}
TEST(Test_Caffe, multiple_inputs)
{
const string model = findDataFile("dnn/layers/net_input.onnx");
Net net = readNetFromONNX(model);
net.setPreferableBackend(DNN_BACKEND_OPENCV);
Mat first_image(10, 11, CV_32FC3);
Mat second_image(10, 11, CV_32FC3);
randu(first_image, -1, 1);
randu(second_image, -1, 1);
first_image = blobFromImage(first_image);
second_image = blobFromImage(second_image);
Mat first_image_blue_green = slice(first_image, Range::all(), Range(0, 2), Range::all(), Range::all());
Mat first_image_red = slice(first_image, Range::all(), Range(2, 3), Range::all(), Range::all());
Mat second_image_blue_green = slice(second_image, Range::all(), Range(0, 2), Range::all(), Range::all());
Mat second_image_red = slice(second_image, Range::all(), Range(2, 3), Range::all(), Range::all());
net.setInput(first_image_blue_green, "old_style_input_blue_green");
net.setInput(first_image_red, "different_name_for_red");
net.setInput(second_image_blue_green, "input_layer_blue_green");
net.setInput(second_image_red, "old_style_input_red");
Mat out = net.forward();
normAssert(out, first_image + second_image);
}
INSTANTIATE_TEST_CASE_P(/**/, Test_Caffe_nets, dnnBackendsAndTargets());
}} // namespace
+44
View File
@@ -0,0 +1,44 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#include "test_precomp.hpp"
#include "test_common.impl.hpp" // shared with perf tests
#include <opencv2/dnn/shape_utils.hpp>
namespace opencv_test {
void runLayer(cv::Ptr<cv::dnn::Layer> layer, std::vector<cv::Mat> &inpBlobs, std::vector<cv::Mat> &outBlobs)
{
size_t ninputs = inpBlobs.size();
std::vector<cv::Mat> inp(ninputs), outp, intp;
std::vector<cv::MatShape> inputs, outputs, internals;
std::vector<cv::dnn::MatType> inputs_types, outputs_types, internals_types;
for (size_t i = 0; i < ninputs; i++)
{
inp[i] = inpBlobs[i].clone();
inputs.push_back(cv::dnn::shape(inp[i]));
inputs_types.push_back(cv::dnn::MatType(inp[i].type()));
}
layer->getMemoryShapes(inputs, 0, outputs, internals);
layer->getTypes(inputs_types, outputs.size(), internals.size(), outputs_types, internals_types);
for (size_t i = 0; i < outputs.size(); i++)
{
outp.push_back(cv::Mat(outputs[i], outputs_types[i]));
}
for (size_t i = 0; i < internals.size(); i++)
{
intp.push_back(cv::Mat(internals[i], internals_types[i]));
}
layer->finalize(inp, outp);
layer->forward(inp, outp, intp);
size_t noutputs = outp.size();
outBlobs.resize(noutputs);
for (size_t i = 0; i < noutputs; i++)
outBlobs[i] = outp[i];
}
}
+270
View File
@@ -0,0 +1,270 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#ifndef __OPENCV_TEST_COMMON_HPP__
#define __OPENCV_TEST_COMMON_HPP__
#include "opencv2/dnn/utils/inference_engine.hpp"
#include <string>
#ifdef HAVE_OPENCL
#include "opencv2/core/ocl.hpp"
#endif
// src/op_inf_engine.hpp
#define INF_ENGINE_VER_MAJOR_GT(ver) (((INF_ENGINE_RELEASE) / 10000) > ((ver) / 10000))
#define INF_ENGINE_VER_MAJOR_GE(ver) (((INF_ENGINE_RELEASE) / 10000) >= ((ver) / 10000))
#define INF_ENGINE_VER_MAJOR_LT(ver) (((INF_ENGINE_RELEASE) / 10000) < ((ver) / 10000))
#define INF_ENGINE_VER_MAJOR_LE(ver) (((INF_ENGINE_RELEASE) / 10000) <= ((ver) / 10000))
#define INF_ENGINE_VER_MAJOR_EQ(ver) (((INF_ENGINE_RELEASE) / 10000) == ((ver) / 10000))
#define CV_TEST_TAG_DNN_SKIP_OPENCV_BACKEND "dnn_skip_opencv_backend"
#define CV_TEST_TAG_DNN_SKIP_CPU "dnn_skip_cpu"
#define CV_TEST_TAG_DNN_SKIP_CPU_FP16 "dnn_skip_cpu_fp16"
#define CV_TEST_TAG_DNN_SKIP_OPENCL "dnn_skip_ocl"
#define CV_TEST_TAG_DNN_SKIP_OPENCL_FP16 "dnn_skip_ocl_fp16"
#define CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER "dnn_skip_ie_nn_builder"
#define CV_TEST_TAG_DNN_SKIP_IE_NGRAPH "dnn_skip_ie_ngraph"
#define CV_TEST_TAG_DNN_SKIP_IE "dnn_skip_ie"
#define CV_TEST_TAG_DNN_SKIP_IE_2018R5 "dnn_skip_ie_2018r5"
#define CV_TEST_TAG_DNN_SKIP_IE_2019R1 "dnn_skip_ie_2019r1"
#define CV_TEST_TAG_DNN_SKIP_IE_2019R1_1 "dnn_skip_ie_2019r1_1"
#define CV_TEST_TAG_DNN_SKIP_IE_2019R2 "dnn_skip_ie_2019r2"
#define CV_TEST_TAG_DNN_SKIP_IE_2019R3 "dnn_skip_ie_2019r3"
#define CV_TEST_TAG_DNN_SKIP_IE_CPU "dnn_skip_ie_cpu"
#define CV_TEST_TAG_DNN_SKIP_IE_OPENCL "dnn_skip_ie_ocl"
#define CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16 "dnn_skip_ie_ocl_fp16"
#define CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_2 "dnn_skip_ie_myriad2"
#define CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_X "dnn_skip_ie_myriadx"
#define CV_TEST_TAG_DNN_SKIP_IE_MYRIAD CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_2, CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_X
#define CV_TEST_TAG_DNN_SKIP_IE_ARM_CPU "dnn_skip_ie_arm_cpu"
#define CV_TEST_TAG_DNN_SKIP_VULKAN "dnn_skip_vulkan"
#define CV_TEST_TAG_DNN_SKIP_CUDA "dnn_skip_cuda"
#define CV_TEST_TAG_DNN_SKIP_CUDA_FP16 "dnn_skip_cuda_fp16"
#define CV_TEST_TAG_DNN_SKIP_CUDA_FP32 "dnn_skip_cuda_fp32"
#define CV_TEST_TAG_DNN_SKIP_ONNX_CONFORMANCE "dnn_skip_onnx_conformance"
#define CV_TEST_TAG_DNN_SKIP_PARSER "dnn_skip_parser"
#define CV_TEST_TAG_DNN_SKIP_GLOBAL "dnn_skip_global"
#define CV_TEST_TAG_DNN_SKIP_TIMVX "dnn_skip_timvx"
#define CV_TEST_TAG_DNN_SKIP_CANN "dnn_skip_cann"
#ifdef HAVE_INF_ENGINE
#if INF_ENGINE_VER_MAJOR_EQ(2018050000)
# define CV_TEST_TAG_DNN_SKIP_IE_VERSION CV_TEST_TAG_DNN_SKIP_IE, CV_TEST_TAG_DNN_SKIP_IE_2018R5
#elif INF_ENGINE_VER_MAJOR_EQ(2019010000)
# if INF_ENGINE_RELEASE < 2019010100
# define CV_TEST_TAG_DNN_SKIP_IE_VERSION CV_TEST_TAG_DNN_SKIP_IE, CV_TEST_TAG_DNN_SKIP_IE_2019R1
# else
# define CV_TEST_TAG_DNN_SKIP_IE_VERSION CV_TEST_TAG_DNN_SKIP_IE, CV_TEST_TAG_DNN_SKIP_IE_2019R1_1
# endif
#elif INF_ENGINE_VER_MAJOR_EQ(2019020000)
# define CV_TEST_TAG_DNN_SKIP_IE_VERSION CV_TEST_TAG_DNN_SKIP_IE, CV_TEST_TAG_DNN_SKIP_IE_2019R2
#elif INF_ENGINE_VER_MAJOR_EQ(2019030000)
# define CV_TEST_TAG_DNN_SKIP_IE_VERSION CV_TEST_TAG_DNN_SKIP_IE, CV_TEST_TAG_DNN_SKIP_IE_2019R3
#endif
#endif // HAVE_INF_ENGINE
#ifndef CV_TEST_TAG_DNN_SKIP_IE_VERSION
# define CV_TEST_TAG_DNN_SKIP_IE_VERSION CV_TEST_TAG_DNN_SKIP_IE
#endif
namespace cv { namespace dnn {
CV__DNN_INLINE_NS_BEGIN
void PrintTo(const cv::dnn::Backend& v, std::ostream* os);
void PrintTo(const cv::dnn::Target& v, std::ostream* os);
using opencv_test::tuple;
using opencv_test::get;
void PrintTo(const tuple<cv::dnn::Backend, cv::dnn::Target> v, std::ostream* os);
CV__DNN_INLINE_NS_END
}} // namespace cv::dnn
namespace opencv_test {
void initDNNTests();
using namespace cv::dnn;
static inline const std::string &getOpenCVExtraDir()
{
return cvtest::TS::ptr()->get_data_path();
}
void normAssert(
cv::InputArray ref, cv::InputArray test, const char *comment = "",
double l1 = 0.00001, double lInf = 0.0001);
std::vector<cv::Rect2d> matToBoxes(const cv::Mat& m);
void normAssertDetections(
const std::vector<int>& refClassIds,
const std::vector<float>& refScores,
const std::vector<cv::Rect2d>& refBoxes,
const std::vector<int>& testClassIds,
const std::vector<float>& testScores,
const std::vector<cv::Rect2d>& testBoxes,
const char *comment = "", double confThreshold = 0.0,
double scores_diff = 1e-5, double boxes_iou_diff = 1e-4);
// For SSD-based object detection networks which produce output of shape 1x1xNx7
// where N is a number of detections and an every detection is represented by
// a vector [batchId, classId, confidence, left, top, right, bottom].
void normAssertDetections(
cv::Mat ref, cv::Mat out, const char *comment = "",
double confThreshold = 0.0, double scores_diff = 1e-5,
double boxes_iou_diff = 1e-4);
// For text detection networks
// Curved text polygon is not supported in the current version.
// (concave polygon is invalid input to intersectConvexConvex)
void normAssertTextDetections(
const std::vector<std::vector<Point>>& gtPolys,
const std::vector<std::vector<Point>>& testPolys,
const char *comment = "", double boxes_iou_diff = 1e-4);
void readFileContent(const std::string& filename, CV_OUT std::vector<char>& content);
bool validateVPUType();
testing::internal::ParamGenerator< tuple<Backend, Target> > dnnBackendsAndTargets(
bool withInferenceEngine = true,
bool obsolete_withHalide = false, // this is kept for compatibility
bool withCpuOCV = true,
bool withVkCom = true,
bool withCUDA = true,
bool withNgraph = true,
bool withWebnn = true,
bool withCann = true
);
testing::internal::ParamGenerator< tuple<Backend, Target> > dnnBackendsAndTargetsIE();
class DNNTestLayer : public TestWithParam<tuple<Backend, Target> >
{
public:
dnn::Backend backend;
dnn::Target target;
double default_l1, default_lInf;
DNNTestLayer()
{
backend = (dnn::Backend)(int)get<0>(GetParam());
target = (dnn::Target)(int)get<1>(GetParam());
getDefaultThresholds(backend, target, &default_l1, &default_lInf);
}
static void getDefaultThresholds(int backend, int target, double* l1, double* lInf)
{
if (target == DNN_TARGET_CPU_FP16 || target == DNN_TARGET_CUDA_FP16 || target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD)
{
*l1 = 4e-3;
*lInf = 2e-2;
}
else
{
*l1 = 1e-5;
*lInf = 1e-4;
}
}
static void checkBackend(int backend, int target, Mat* inp = 0, Mat* ref = 0)
{
CV_UNUSED(backend); CV_UNUSED(target); CV_UNUSED(inp); CV_UNUSED(ref);
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LT(2021000000)
if ((backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 || backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
&& target == DNN_TARGET_MYRIAD)
{
if (inp && ref && inp->dims == 4 && ref->dims == 4 &&
inp->size[0] != 1 && inp->size[0] != ref->size[0])
{
std::cout << "Inconsistent batch size of input and output blobs for Myriad plugin" << std::endl;
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD);
}
}
#endif
}
void expectNoFallbacks(Net& net, bool raiseError = true)
{
// The new DNN engine does not support back-ends for now
// bug: https://github.com/opencv/opencv/issues/26198
if (net.getMainGraph())
return;
// Check if all the layers are supported with current backend and target.
// Some layers might be fused so their timings equal to zero.
std::vector<double> timings;
net.getPerfProfile(timings);
std::vector<String> names = net.getLayerNames();
CV_Assert(names.size() == timings.size());
bool hasFallbacks = false;
for (int i = 0; i < names.size(); ++i)
{
Ptr<dnn::Layer> l = net.getLayer(net.getLayerId(names[i]));
bool fused = !timings[i];
if ((!l->supportBackend(backend) || l->preferableTarget != target) && !fused)
{
hasFallbacks = true;
std::cout << "FALLBACK: Layer [" << l->type << "]:[" << l->name << "] is expected to have backend implementation" << endl;
}
}
if (hasFallbacks && raiseError)
CV_Error(Error::StsNotImplemented, "Implementation fallbacks are not expected in this test");
}
void expectNoFallbacksFromIE(Net& net)
{
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019)
expectNoFallbacks(net);
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
expectNoFallbacks(net, false);
}
void expectNoFallbacksFromCUDA(Net& net)
{
if (backend == DNN_BACKEND_CUDA)
expectNoFallbacks(net);
}
size_t getTopMemoryUsageMB();
protected:
void checkBackend(Mat* inp = 0, Mat* ref = 0)
{
checkBackend(backend, target, inp, ref);
}
};
void runLayer(cv::Ptr<cv::dnn::Layer> layer, std::vector<cv::Mat> &inpBlobs, std::vector<cv::Mat> &outBlobs);
inline std::string getCurrentTestNameNoParams()
{
const ::testing::TestInfo* const test_info =
::testing::UnitTest::GetInstance()->current_test_info();
if (!test_info)
return std::string();
std::string suite = test_info->test_case_name();
std::string name = test_info->name();
const auto suite_slash = suite.find('/');
if (suite_slash != std::string::npos)
suite = suite.substr(0, suite_slash);
const auto name_slash = name.find('/');
if (name_slash != std::string::npos)
name = name.substr(0, name_slash);
return suite + "." + name;
}
} // namespace
#endif
+546
View File
@@ -0,0 +1,546 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
// Used in accuracy and perf tests as a content of .cpp file
// Note: don't use "precomp.hpp" here
#include "opencv2/ts.hpp"
#include "opencv2/ts/ts_perf.hpp"
#include "opencv2/core/utility.hpp"
#include "opencv2/core/ocl.hpp"
#include "opencv2/dnn.hpp"
#include "test_common.hpp"
#include <opencv2/core/utils/configuration.private.hpp>
#include <opencv2/core/utils/logger.hpp>
#include <opencv2/geometry.hpp>
#ifdef _WIN32
#ifndef NOMINMAX
#define NOMINMAX
#endif
#include <windows.h>
#include <psapi.h>
#endif // _WIN32
namespace cv { namespace dnn {
CV__DNN_INLINE_NS_BEGIN
void PrintTo(const cv::dnn::Backend& v, std::ostream* os)
{
switch (v) {
case DNN_BACKEND_DEFAULT: *os << "DEFAULT"; return;
case DNN_BACKEND_INFERENCE_ENGINE: *os << "DLIE*"; return;
case DNN_BACKEND_VKCOM: *os << "VKCOM"; return;
case DNN_BACKEND_OPENCV: *os << "OCV"; return;
case DNN_BACKEND_CUDA: *os << "CUDA"; return;
case DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019: *os << "DLIE"; return;
case DNN_BACKEND_INFERENCE_ENGINE_NGRAPH: *os << "NGRAPH"; return;
case DNN_BACKEND_WEBNN: *os << "WEBNN"; return;
case DNN_BACKEND_TIMVX: *os << "TIMVX"; return;
case DNN_BACKEND_CANN: *os << "CANN"; return;
} // don't use "default:" to emit compiler warnings
*os << "DNN_BACKEND_UNKNOWN(" << (int)v << ")";
}
void PrintTo(const cv::dnn::Target& v, std::ostream* os)
{
switch (v) {
case DNN_TARGET_CPU: *os << "CPU"; return;
case DNN_TARGET_OPENCL: *os << "OCL"; return;
case DNN_TARGET_OPENCL_FP16: *os << "OCL_FP16"; return;
case DNN_TARGET_MYRIAD: *os << "MYRIAD"; return;
case DNN_TARGET_HDDL: *os << "HDDL"; return;
case DNN_TARGET_VULKAN: *os << "VULKAN"; return;
case DNN_TARGET_FPGA: *os << "FPGA"; return;
case DNN_TARGET_CUDA: *os << "CUDA"; return;
case DNN_TARGET_CUDA_FP16: *os << "CUDA_FP16"; return;
case DNN_TARGET_NPU: *os << "NPU"; return;
case DNN_TARGET_CPU_FP16: *os << "CPU_FP16"; return;
} // don't use "default:" to emit compiler warnings
*os << "DNN_TARGET_UNKNOWN(" << (int)v << ")";
}
void PrintTo(const tuple<cv::dnn::Backend, cv::dnn::Target> v, std::ostream* os)
{
PrintTo(get<0>(v), os);
*os << "/";
PrintTo(get<1>(v), os);
}
CV__DNN_INLINE_NS_END
}} // namespace
namespace opencv_test {
void normAssert(
cv::InputArray ref, cv::InputArray test, const char *comment /*= ""*/,
double l1 /*= 0.00001*/, double lInf /*= 0.0001*/)
{
cv::Mat refMat = ref.getMat();
cv::Mat testMat = test.getMat();
const cv::MatShape refShape = refMat.shape();
const cv::MatShape testShape = testMat.shape();
const bool scalar1dCompatible =
(refShape.isScalar() && testShape.size() == 1 && testShape[0] == 1) ||
(testShape.isScalar() && refShape.size() == 1 && refShape[0] == 1);
if (scalar1dCompatible)
{
const cv::MatShape oneShape{1};
if (refShape.isScalar())
refMat = refMat.reshape(1, oneShape);
if (testShape.isScalar())
testMat = testMat.reshape(1, oneShape);
}
// Empty tensors are valid for ONNX conformance tests. Avoid 0/0 in normL1
// and verify emptiness compatibility directly.
if (refMat.total() == 0 || testMat.total() == 0)
{
EXPECT_EQ(refMat.total(), testMat.total()) << comment;
EXPECT_EQ(refMat.size, testMat.size) << comment;
return;
}
double normL1 = cvtest::norm(refMat, testMat, cv::NORM_L1) / refMat.total();
EXPECT_LE(normL1, l1) << comment << " |ref| = " << cvtest::norm(refMat, cv::NORM_INF);
double normInf = cvtest::norm(refMat, testMat, cv::NORM_INF);
EXPECT_LE(normInf, lInf) << comment << " |ref| = " << cvtest::norm(refMat, cv::NORM_INF);
}
std::vector<cv::Rect2d> matToBoxes(const cv::Mat& m)
{
EXPECT_EQ(m.type(), CV_32FC1);
EXPECT_EQ(m.dims, 2);
EXPECT_EQ(m.cols, 4);
std::vector<cv::Rect2d> boxes(m.rows);
for (int i = 0; i < m.rows; ++i)
{
CV_Assert(m.row(i).isContinuous());
const float* data = m.ptr<float>(i);
double l = data[0], t = data[1], r = data[2], b = data[3];
boxes[i] = cv::Rect2d(l, t, r - l, b - t);
}
return boxes;
}
void normAssertDetections(
const std::vector<int>& refClassIds,
const std::vector<float>& refScores,
const std::vector<cv::Rect2d>& refBoxes,
const std::vector<int>& testClassIds,
const std::vector<float>& testScores,
const std::vector<cv::Rect2d>& testBoxes,
const char *comment /*= ""*/, double confThreshold /*= 0.0*/,
double scores_diff /*= 1e-5*/, double boxes_iou_diff /*= 1e-4*/)
{
scores_diff = std::max(0.022, scores_diff);
boxes_iou_diff = std::max(0.019, boxes_iou_diff);
ASSERT_FALSE(testClassIds.empty()) << "No detections";
std::vector<bool> matchedRefBoxes(refBoxes.size(), false);
std::vector<double> refBoxesIoUDiff(refBoxes.size(), 1.0);
for (int i = 0; i < testBoxes.size(); ++i)
{
//cout << "Test[i=" << i << "]: score=" << testScores[i] << " id=" << testClassIds[i] << " box " << testBoxes[i] << endl;
double testScore = testScores[i];
if (testScore < confThreshold)
continue;
int testClassId = testClassIds[i];
const cv::Rect2d& testBox = testBoxes[i];
bool matched = false;
double topIoU = 0;
for (int j = 0; j < refBoxes.size() && !matched; ++j)
{
if (!matchedRefBoxes[j] && testClassId == refClassIds[j] &&
std::abs(testScore - refScores[j]) < scores_diff)
{
double interArea = (testBox & refBoxes[j]).area();
double iou = interArea / (testBox.area() + refBoxes[j].area() - interArea);
topIoU = std::max(topIoU, iou);
refBoxesIoUDiff[j] = std::min(refBoxesIoUDiff[j], 1.0f - iou);
if (1.0 - iou < boxes_iou_diff)
{
matched = true;
matchedRefBoxes[j] = true;
}
}
}
if (!matched)
{
std::cout << cv::format("Unmatched prediction: class %d score %f box ",
testClassId, testScore) << testBox << std::endl;
std::cout << "Highest IoU: " << topIoU << std::endl;
}
EXPECT_TRUE(matched) << comment;
}
// Check unmatched reference detections.
for (int i = 0; i < refBoxes.size(); ++i)
{
if (!matchedRefBoxes[i] && refScores[i] > confThreshold)
{
std::cout << cv::format("Unmatched reference: class %d score %f box ",
refClassIds[i], refScores[i]) << refBoxes[i]
<< " IoU diff: " << refBoxesIoUDiff[i]
<< std::endl;
EXPECT_LE(refScores[i], confThreshold) << comment;
}
}
}
// For SSD-based object detection networks which produce output of shape 1x1xNx7
// where N is a number of detections and an every detection is represented by
// a vector [batchId, classId, confidence, left, top, right, bottom].
void normAssertDetections(
cv::Mat ref, cv::Mat out, const char *comment /*= ""*/,
double confThreshold /*= 0.0*/, double scores_diff /*= 1e-5*/,
double boxes_iou_diff /*= 1e-4*/)
{
CV_Assert(ref.total() % 7 == 0);
CV_Assert(out.total() % 7 == 0);
ref = ref.reshape(1, ref.total() / 7);
out = out.reshape(1, out.total() / 7);
cv::Mat refClassIds, testClassIds;
ref.col(1).convertTo(refClassIds, CV_32SC1);
out.col(1).convertTo(testClassIds, CV_32SC1);
std::vector<float> refScores(ref.col(2)), testScores(out.col(2));
std::vector<cv::Rect2d> refBoxes = matToBoxes(ref.colRange(3, 7));
std::vector<cv::Rect2d> testBoxes = matToBoxes(out.colRange(3, 7));
normAssertDetections(refClassIds, refScores, refBoxes, testClassIds, testScores,
testBoxes, comment, confThreshold, scores_diff, boxes_iou_diff);
}
// For text detection networks
// Curved text polygon is not supported in the current version.
// (concave polygon is invalid input to intersectConvexConvex)
void normAssertTextDetections(
const std::vector<std::vector<Point>>& gtPolys,
const std::vector<std::vector<Point>>& testPolys,
const char *comment /*= ""*/, double boxes_iou_diff /*= 1e-4*/)
{
std::vector<bool> matchedRefBoxes(gtPolys.size(), false);
for (uint i = 0; i < testPolys.size(); ++i)
{
const std::vector<Point>& testPoly = testPolys[i];
bool matched = false;
double topIoU = 0;
for (uint j = 0; j < gtPolys.size() && !matched; ++j)
{
if (!matchedRefBoxes[j])
{
std::vector<Point> intersectionPolygon;
float intersectArea = intersectConvexConvex(testPoly, gtPolys[j], intersectionPolygon, true);
double iou = intersectArea / (contourArea(testPoly) + contourArea(gtPolys[j]) - intersectArea);
topIoU = std::max(topIoU, iou);
if (1.0 - iou < boxes_iou_diff)
{
matched = true;
matchedRefBoxes[j] = true;
}
}
}
if (!matched) {
std::cout << cv::format("Unmatched-det:") << testPoly << std::endl;
std::cout << "Highest IoU: " << topIoU << std::endl;
}
EXPECT_TRUE(matched) << comment;
}
// Check unmatched groundtruth.
for (uint i = 0; i < gtPolys.size(); ++i)
{
if (!matchedRefBoxes[i]) {
std::cout << cv::format("Unmatched-gt:") << gtPolys[i] << std::endl;
}
EXPECT_TRUE(matchedRefBoxes[i]);
}
}
void readFileContent(const std::string& filename, CV_OUT std::vector<char>& content)
{
const std::ios::openmode mode = std::ios::in | std::ios::binary;
std::ifstream ifs(filename.c_str(), mode);
ASSERT_TRUE(ifs.is_open());
content.clear();
ifs.seekg(0, std::ios::end);
const size_t sz = ifs.tellg();
content.resize(sz);
ifs.seekg(0, std::ios::beg);
ifs.read((char*)content.data(), sz);
ASSERT_FALSE(ifs.fail());
}
testing::internal::ParamGenerator< tuple<Backend, Target> > dnnBackendsAndTargets(
bool withInferenceEngine /*= true*/,
bool obsolete_withHalide /*= false*/,
bool withCpuOCV /*= true*/,
bool withVkCom /*= true*/,
bool withCUDA /*= true*/,
bool withNgraph /*= true*/,
bool withWebnn /*= false*/,
bool withCann /*= true*/
)
{
bool withVPU = validateVPUType();
std::vector< tuple<Backend, Target> > targets;
std::vector< Target > available;
if (withInferenceEngine)
{
available = getAvailableTargets(DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019);
for (std::vector< Target >::const_iterator i = available.begin(); i != available.end(); ++i)
{
if ((*i == DNN_TARGET_MYRIAD || *i == DNN_TARGET_HDDL) && !withVPU)
continue;
targets.push_back(make_tuple(DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019, *i));
}
}
if (withNgraph)
{
available = getAvailableTargets(DNN_BACKEND_INFERENCE_ENGINE_NGRAPH);
for (std::vector< Target >::const_iterator i = available.begin(); i != available.end(); ++i)
{
if ((*i == DNN_TARGET_MYRIAD || *i == DNN_TARGET_HDDL) && !withVPU)
continue;
targets.push_back(make_tuple(DNN_BACKEND_INFERENCE_ENGINE_NGRAPH, *i));
}
}
if (withVkCom)
{
available = getAvailableTargets(DNN_BACKEND_VKCOM);
for (std::vector< Target >::const_iterator i = available.begin(); i != available.end(); ++i)
targets.push_back(make_tuple(DNN_BACKEND_VKCOM, *i));
}
#ifdef HAVE_CUDA
if(withCUDA)
{
for (auto target : getAvailableTargets(DNN_BACKEND_CUDA))
targets.push_back(make_tuple(DNN_BACKEND_CUDA, target));
}
#endif
#ifdef HAVE_WEBNN
if (withWebnn)
{
for (auto target : getAvailableTargets(DNN_BACKEND_WEBNN)) {
targets.push_back(make_tuple(DNN_BACKEND_WEBNN, target));
}
}
#else
CV_UNUSED(withWebnn);
#endif
#ifdef HAVE_CANN
if (withCann)
{
for (auto target : getAvailableTargets(DNN_BACKEND_CANN))
targets.push_back(make_tuple(DNN_BACKEND_CANN, target));
}
#else
CV_UNUSED(withCann);
#endif // HAVE_CANN
{
available = getAvailableTargets(DNN_BACKEND_OPENCV);
for (std::vector< Target >::const_iterator i = available.begin(); i != available.end(); ++i)
{
if (!withCpuOCV && *i == DNN_TARGET_CPU)
continue;
targets.push_back(make_tuple(DNN_BACKEND_OPENCV, *i));
}
}
if (targets.empty()) // validate at least CPU mode
targets.push_back(make_tuple(DNN_BACKEND_OPENCV, DNN_TARGET_CPU));
return testing::ValuesIn(targets);
}
testing::internal::ParamGenerator< tuple<Backend, Target> > dnnBackendsAndTargetsIE()
{
#ifdef HAVE_INF_ENGINE
bool withVPU = validateVPUType();
std::vector< tuple<Backend, Target> > targets;
std::vector< Target > available;
{
available = getAvailableTargets(DNN_BACKEND_INFERENCE_ENGINE_NGRAPH);
for (std::vector< Target >::const_iterator i = available.begin(); i != available.end(); ++i)
{
if ((*i == DNN_TARGET_MYRIAD || *i == DNN_TARGET_HDDL) && !withVPU)
continue;
targets.push_back(make_tuple(DNN_BACKEND_INFERENCE_ENGINE_NGRAPH, *i));
}
}
return testing::ValuesIn(targets);
#else
return testing::ValuesIn(std::vector< tuple<Backend, Target> >());
#endif
}
static std::string getTestInferenceEngineVPUType()
{
static std::string param_vpu_type = utils::getConfigurationParameterString("OPENCV_TEST_DNN_IE_VPU_TYPE", "");
return param_vpu_type;
}
static bool validateVPUType_()
{
std::string test_vpu_type = getTestInferenceEngineVPUType();
if (test_vpu_type == "DISABLED" || test_vpu_type == "disabled")
{
return false;
}
std::vector<Target> available = getAvailableTargets(DNN_BACKEND_INFERENCE_ENGINE);
bool have_vpu_target = false;
for (std::vector<Target>::const_iterator i = available.begin(); i != available.end(); ++i)
{
if (*i == DNN_TARGET_MYRIAD || *i == DNN_TARGET_HDDL)
{
have_vpu_target = true;
break;
}
}
if (test_vpu_type.empty())
{
if (have_vpu_target)
{
CV_LOG_INFO(NULL, "OpenCV-DNN-Test: VPU type for testing is not specified via 'OPENCV_TEST_DNN_IE_VPU_TYPE' parameter.")
}
}
else
{
if (!have_vpu_target)
{
CV_LOG_FATAL(NULL, "OpenCV-DNN-Test: 'OPENCV_TEST_DNN_IE_VPU_TYPE' parameter requires VPU of type = '" << test_vpu_type << "', but VPU is not detected. STOP.");
exit(1);
}
std::string dnn_vpu_type = getInferenceEngineVPUType();
if (dnn_vpu_type != test_vpu_type)
{
CV_LOG_FATAL(NULL, "OpenCV-DNN-Test: 'testing' and 'detected' VPU types mismatch: '" << test_vpu_type << "' vs '" << dnn_vpu_type << "'. STOP.");
exit(1);
}
}
if (have_vpu_target)
{
std::string dnn_vpu_type = getInferenceEngineVPUType();
if (dnn_vpu_type == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_2)
registerGlobalSkipTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_2);
if (dnn_vpu_type == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
registerGlobalSkipTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_X);
}
return true;
}
bool validateVPUType()
{
static bool result = validateVPUType_();
return result;
}
void initDNNTests()
{
cvtest::addDataSearchEnv("OPENCV_DNN_TEST_DATA_PATH");
registerGlobalSkipTag(
CV_TEST_TAG_DNN_SKIP_OPENCV_BACKEND,
CV_TEST_TAG_DNN_SKIP_CPU, CV_TEST_TAG_DNN_SKIP_CPU_FP16,
CV_TEST_TAG_DNN_SKIP_OPENCL, CV_TEST_TAG_DNN_SKIP_OPENCL_FP16
);
#if defined(INF_ENGINE_RELEASE)
registerGlobalSkipTag(
CV_TEST_TAG_DNN_SKIP_IE,
#if INF_ENGINE_VER_MAJOR_EQ(2018050000)
CV_TEST_TAG_DNN_SKIP_IE_2018R5,
#elif INF_ENGINE_VER_MAJOR_EQ(2019010000)
CV_TEST_TAG_DNN_SKIP_IE_2019R1,
# if INF_ENGINE_RELEASE == 2019010100
CV_TEST_TAG_DNN_SKIP_IE_2019R1_1,
# endif
#elif INF_ENGINE_VER_MAJOR_EQ(2019020000)
CV_TEST_TAG_DNN_SKIP_IE_2019R2,
#elif INF_ENGINE_VER_MAJOR_EQ(2019030000)
CV_TEST_TAG_DNN_SKIP_IE_2019R3,
#endif
#ifdef HAVE_DNN_NGRAPH
CV_TEST_TAG_DNN_SKIP_IE_NGRAPH,
#endif
#ifdef HAVE_DNN_IE_NN_BUILDER_2019
CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER,
#endif
CV_TEST_TAG_DNN_SKIP_IE_CPU
);
registerGlobalSkipTag(
// see validateVPUType(): CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_2, CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_X
CV_TEST_TAG_DNN_SKIP_IE_OPENCL, CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16
);
#endif
#ifdef HAVE_VULKAN
registerGlobalSkipTag(
CV_TEST_TAG_DNN_SKIP_VULKAN
);
#endif
#ifdef HAVE_CUDA
registerGlobalSkipTag(
CV_TEST_TAG_DNN_SKIP_CUDA, CV_TEST_TAG_DNN_SKIP_CUDA_FP32, CV_TEST_TAG_DNN_SKIP_CUDA_FP16
);
#endif
#ifdef HAVE_TIMVX
registerGlobalSkipTag(
CV_TEST_TAG_DNN_SKIP_TIMVX
);
#endif
#ifdef HAVE_CANN
registerGlobalSkipTag(
CV_TEST_TAG_DNN_SKIP_CANN
);
#endif
registerGlobalSkipTag(
CV_TEST_TAG_DNN_SKIP_ONNX_CONFORMANCE,
CV_TEST_TAG_DNN_SKIP_PARSER
);
}
size_t DNNTestLayer::getTopMemoryUsageMB()
{
#ifdef _WIN32
PROCESS_MEMORY_COUNTERS proc;
GetProcessMemoryInfo(GetCurrentProcess(), &proc, sizeof(proc));
return proc.PeakWorkingSetSize / std::pow(1024, 2); // bytes to megabytes
#else
std::ifstream status("/proc/self/status");
std::string line, title;
while (std::getline(status, line))
{
std::istringstream iss(line);
iss >> title;
if (title == "VmHWM:")
{
size_t mem;
iss >> mem;
return mem / 1024;
}
}
return 0l;
#endif
}
} // namespace
+501
View File
@@ -0,0 +1,501 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
// (3-clause BSD License)
//
// Copyright (C) 2017, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the names of the copyright holders nor the names of the contributors
// may be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall copyright holders or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "test_precomp.hpp"
#include "npy_blob.hpp"
#include <opencv2/dnn/shape_utils.hpp>
namespace opencv_test { namespace {
template<typename TString>
static std::string _tf(TString filename)
{
return (getOpenCVExtraDir() + "/dnn/") + filename;
}
TEST(Test_YOLO, read_yolov4_onnx)
{
auto engine_forced = static_cast<cv::dnn::EngineType>(
cv::utils::getConfigurationParameterSizeT("OPENCV_FORCE_DNN_ENGINE", cv::dnn::ENGINE_AUTO));
if (engine_forced == cv::dnn::ENGINE_CLASSIC)
{
applyTestTag(CV_TEST_TAG_DNN_SKIP_PARSER);
return;
}
Net net = readNet(findDataFile("dnn/yolov4.onnx", false));
ASSERT_FALSE(net.empty());
}
class Test_YOLO_nets : public DNNTestLayer
{
public:
// Test object detection network from ONNX model.
void testYOLOModel(const std::string& model,
const std::vector<std::vector<int> >& refClassIds,
const std::vector<std::vector<float> >& refConfidences,
const std::vector<std::vector<Rect2d> >& refBoxes,
double scoreDiff, double iouDiff, float confThreshold = 0.24,
float nmsThreshold = 0.4, bool useWinograd = true,
int zeroPadW = 0, Size inputSize = Size())
{
auto engine_forced = static_cast<cv::dnn::EngineType>(
cv::utils::getConfigurationParameterSizeT("OPENCV_FORCE_DNN_ENGINE", cv::dnn::ENGINE_AUTO));
if (engine_forced == cv::dnn::ENGINE_CLASSIC)
{
applyTestTag(CV_TEST_TAG_DNN_SKIP_PARSER);
return;
}
checkBackend();
Mat img1 = imread(_tf("dog416.png"));
Mat img2 = imread(_tf("street.png"));
cv::resize(img1, img1, inputSize);
cv::resize(img2, img2, inputSize);
// Pad images by black pixel at the right to test not equal width and height sizes
if (zeroPadW) {
cv::copyMakeBorder(img1, img1, 0, 0, 0, zeroPadW, BORDER_CONSTANT);
cv::copyMakeBorder(img2, img2, 0, 0, 0, zeroPadW, BORDER_CONSTANT);
}
std::vector<Mat> samples(2);
samples[0] = img1; samples[1] = img2;
// determine test type, whether batch or single img
int batch_size = refClassIds.size();
CV_Assert(batch_size == 1 || batch_size == 2);
samples.resize(batch_size);
Mat inp = blobFromImages(samples, 1.0/255, Size(), Scalar(), true, false);
Net net = readNet(findDataFile("dnn/" + model, false));
net.setPreferableBackend(backend);
net.setPreferableTarget(target);
net.enableWinograd(useWinograd);
net.setInput(inp);
std::vector<Mat> outs;
net.forward(outs, net.getUnconnectedOutLayersNames());
// Detect output format: pytorch-YOLOv4 exports "boxes" [batch, N, 1, 4] + "confs" [batch, N, classes]
bool isBoxConfsFormat = (outs.size() == 2 && outs[0].dims == 4 && outs[0].size[outs[0].dims - 1] == 4);
// Detect 3-output format: boxes [batch, N, 4] + scores [batch, N] + class_idx [batch, N]
bool isBoxScoresIdxFormat = (outs.size() == 3 && outs[0].dims == 3 && outs[0].size[2] == 4);
for (int b = 0; b < batch_size; ++b)
{
std::vector<int> classIds;
std::vector<float> confidences;
std::vector<Rect2d> boxes;
if (isBoxScoresIdxFormat)
{
// yolov3-style format: boxes [batch, N, 4] + scores [batch, N] + class_idx [batch, N]
// boxes are [x1, y1, x2, y2] in pixel coords (relative to model input size)
int N = outs[0].size[1];
float* boxesPtr = outs[0].ptr<float>(b);
float* scoresPtr = outs[1].ptr<float>(b);
float* classIdxPtr = outs[2].ptr<float>(b);
float modelW = (float)inp.size[3];
float modelH = (float)inp.size[2];
for (int j = 0; j < N; ++j)
{
float score = scoresPtr[j];
if (score > confThreshold)
{
float x1 = boxesPtr[j * 4 + 0] / modelW;
float y1 = boxesPtr[j * 4 + 1] / modelH;
float x2 = boxesPtr[j * 4 + 2] / modelW;
float y2 = boxesPtr[j * 4 + 3] / modelH;
boxes.push_back(Rect2d(x1, y1, x2 - x1, y2 - y1));
confidences.push_back(score);
classIds.push_back((int)classIdxPtr[j]);
}
}
}
else if (isBoxConfsFormat)
{
// boxes [batch, N, 1, 4] (x1,y1,x2,y2), confs [batch, N, num_classes]
Mat boxesMat = outs[0];
Mat confsMat = outs[1];
if (batch_size > 1)
{
if (boxesMat.dims == 4) {
Range boxRanges[4] = {Range(b, b+1), Range::all(), Range::all(), Range::all()};
boxesMat = boxesMat(boxRanges);
} else {
Range boxRanges[3] = {Range(b, b+1), Range::all(), Range::all()};
boxesMat = boxesMat(boxRanges);
}
Range confRanges[3] = {Range(b, b+1), Range::all(), Range::all()};
confsMat = confsMat(confRanges);
}
int numBoxes = (int)(boxesMat.total() / 4);
boxesMat = boxesMat.reshape(1, numBoxes);
confsMat = confsMat.reshape(1, numBoxes);
for (int j = 0; j < numBoxes; ++j)
{
Mat scores = confsMat.row(j);
double confidence;
Point maxLoc;
minMaxLoc(scores, 0, &confidence, 0, &maxLoc);
if (confidence > confThreshold) {
float* box = boxesMat.ptr<float>(j);
double x1 = box[0];
double y1 = box[1];
double x2 = box[2];
double y2 = box[3];
boxes.push_back(Rect2d(x1, y1, x2 - x1, y2 - y1));
confidences.push_back(confidence);
classIds.push_back(maxLoc.x);
}
}
}
else
{
for (int i = 0; i < (int)outs.size(); ++i)
{
Mat out;
if (batch_size > 1){
Range ranges[3] = {Range(b, b+1), Range::all(), Range::all()};
out = outs[i](ranges).reshape(1, outs[i].size[1]);
}else{
out = outs[i];
}
for (int j = 0; j < out.rows; ++j)
{
float objConf = out.at<float>(j, 4);
Mat scores = out.row(j).colRange(5, out.cols);
double maxClsScore;
Point maxLoc;
minMaxLoc(scores, 0, &maxClsScore, 0, &maxLoc);
double confidence = objConf * maxClsScore;
if (confidence > confThreshold) {
float* detection = out.ptr<float>(j);
double centerX = detection[0];
double centerY = detection[1];
double width = detection[2];
double height = detection[3];
boxes.push_back(Rect2d(centerX - 0.5 * width, centerY - 0.5 * height,
width, height));
confidences.push_back(confidence);
classIds.push_back(maxLoc.x);
}
}
}
}
// here we need NMS of boxes
std::vector<int> indices;
NMSBoxes(boxes, confidences, confThreshold, nmsThreshold, indices);
std::vector<int> nms_classIds;
std::vector<float> nms_confidences;
std::vector<Rect2d> nms_boxes;
for (size_t i = 0; i < indices.size(); ++i)
{
int idx = indices[i];
Rect2d box = boxes[idx];
float conf = confidences[idx];
int class_id = classIds[idx];
nms_boxes.push_back(box);
nms_confidences.push_back(conf);
nms_classIds.push_back(class_id);
if (cvtest::debugLevel > 0)
{
std::cout << b << ", " << class_id << ", " << conf << "f, "
<< box.x << "f, " << box.y << "f, "
<< box.x + box.width << "f, " << box.y + box.height << "f,"
<< std::endl;
}
}
if (cvIsNaN(iouDiff))
{
if (b == 0)
std::cout << "Skip accuracy checks" << std::endl;
continue;
}
// Return predictions from padded image to the origin
if (zeroPadW) {
float scale = static_cast<float>(inp.size[3]) / (inp.size[3] - zeroPadW);
for (auto& box : nms_boxes) {
box.x *= scale;
box.width *= scale;
}
}
normAssertDetections(refClassIds[b], refConfidences[b], refBoxes[b], nms_classIds,
nms_confidences, nms_boxes, format("batch size %d, sample %d\n", batch_size, b).c_str(), confThreshold, scoreDiff, iouDiff);
}
}
void testYOLOModel(const std::string& model,
const std::vector<int>& refClassIds,
const std::vector<float>& refConfidences,
const std::vector<Rect2d>& refBoxes,
double scoreDiff, double iouDiff, float confThreshold = 0.24,
float nmsThreshold = 0.4, bool useWinograd = true,
int zeroPadW = 0, Size inputSize = Size())
{
testYOLOModel(model,
std::vector<std::vector<int> >(1, refClassIds),
std::vector<std::vector<float> >(1, refConfidences),
std::vector<std::vector<Rect2d> >(1, refBoxes),
scoreDiff, iouDiff, confThreshold, nmsThreshold, useWinograd, zeroPadW, inputSize);
}
void testYOLOModel(const std::string& model,
const cv::Mat& ref, double scoreDiff, double iouDiff,
float confThreshold = 0.24, float nmsThreshold = 0.4, bool useWinograd = true,
int zeroPadW = 0, Size inputSize = Size())
{
CV_Assert(ref.cols == 7);
std::vector<std::vector<int> > refClassIds;
std::vector<std::vector<float> > refScores;
std::vector<std::vector<Rect2d> > refBoxes;
for (int i = 0; i < ref.rows; ++i)
{
int batchId = static_cast<int>(ref.at<float>(i, 0));
int classId = static_cast<int>(ref.at<float>(i, 1));
float score = ref.at<float>(i, 2);
float left = ref.at<float>(i, 3);
float top = ref.at<float>(i, 4);
float right = ref.at<float>(i, 5);
float bottom = ref.at<float>(i, 6);
Rect2d box(left, top, right - left, bottom - top);
if (batchId >= (int)refClassIds.size())
{
refClassIds.resize(batchId + 1);
refScores.resize(batchId + 1);
refBoxes.resize(batchId + 1);
}
refClassIds[batchId].push_back(classId);
refScores[batchId].push_back(score);
refBoxes[batchId].push_back(box);
}
testYOLOModel(model, refClassIds, refScores, refBoxes,
scoreDiff, iouDiff, confThreshold, nmsThreshold, useWinograd, zeroPadW, inputSize);
}
};
TEST_P(Test_YOLO_nets, YOLOv4)
{
applyTestTag(
CV_TEST_TAG_LONG,
CV_TEST_TAG_MEMORY_2GB,
CV_TEST_TAG_DEBUG_VERYLONG
);
// batchId, classId, confidence, left, top, right, bottom
const int N0 = 3;
const int N1 = 6;
static const float ref_[/* (N0 + N1) * 7 */] = {
0, 16, 0.968371f, 0.167918f, 0.394843f, 0.40767f, 0.942042f,
0, 1, 0.963549f, 0.146538f, 0.227724f, 0.745242f, 0.736494f,
0, 7, 0.951405f, 0.606025f, 0.133886f, 0.895092f, 0.294835f,
1, 2, 0.99849f, 0.651516f, 0.456526f, 0.812706f, 0.66287f,
1, 0, 0.996791f, 0.200903f, 0.362404f, 0.264643f, 0.627633f,
1, 2, 0.987972f, 0.450125f, 0.464126f, 0.495712f, 0.519708f,
1, 9, 0.85872f, 0.375374f, 0.314192f, 0.399161f, 0.39453f,
1, 9, 0.841318f, 0.667602f, 0.377284f, 0.686024f, 0.440855f,
1, 9, 0.502608f, 0.656728f, 0.378153f, 0.668251f, 0.432035f,
};
Mat ref(N0 + N1, 7, CV_32FC1, (void*)ref_);
double scoreDiff = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD || target == DNN_TARGET_CPU_FP16) ? 0.006 : 8e-5;
double iouDiff = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD || target == DNN_TARGET_CPU_FP16) ? 0.042 : 3e-4;
if (target == DNN_TARGET_CUDA_FP16)
{
scoreDiff = 0.008;
iouDiff = 0.03;
}
std::string model_file = "yolov4.onnx";
{
SCOPED_TRACE("batch size 1");
testYOLOModel(model_file, ref.rowRange(0, N0), scoreDiff, iouDiff, 0.3, 0.4, false, 0, Size(608, 608));
}
{
SCOPED_TRACE("batch size 2");
testYOLOModel(model_file, ref, scoreDiff, iouDiff, 0.3, 0.4, false, 0, Size(608, 608));
}
}
TEST_P(Test_YOLO_nets, YOLOv3)
{
applyTestTag(
CV_TEST_TAG_LONG,
CV_TEST_TAG_MEMORY_2GB,
CV_TEST_TAG_DEBUG_VERYLONG
);
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_MYRIAD)
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH);
// batchId, classId, confidence, left, top, right, bottom
const int N0 = 3;
const int N1 = 0;
static const float ref_[/* (N0 + N1) * 7 */] = {
0, 7, 0.606292f, 0.612037f, 0.149921f, 0.910763f, 0.300503f,
0, 16, 0.55195f, 0.17069f, 0.356024f, 0.471459f, 0.877178f,
0, 1, 0.433444f, 0.199235f, 0.301175f, 0.753253f, 0.744156f,
};
Mat ref(N0 + N1, 7, CV_32FC1, (void*)ref_);
double scoreDiff = 8e-5, iouDiff = 3e-4;
if (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD || target == DNN_TARGET_CPU_FP16)
{
scoreDiff = 0.006;
iouDiff = 0.042;
}
else if (target == DNN_TARGET_CUDA_FP16)
{
scoreDiff = 0.04;
iouDiff = 0.03;
}
std::string model_file = "yolov3.onnx";
{
SCOPED_TRACE("batch size 1");
testYOLOModel(model_file, ref.rowRange(0, N0), scoreDiff, iouDiff, 0.24, 0.4, false, 0, Size(640, 640));
}
}
TEST_P(Test_YOLO_nets, YOLOv4_tiny)
{
applyTestTag(
target == DNN_TARGET_CPU ? CV_TEST_TAG_MEMORY_512MB : CV_TEST_TAG_MEMORY_1GB
);
const double confThreshold = 0.5;
// batchId, classId, confidence, left, top, right, bottom
const int N0 = 3;
const int N1 = 3;
static const float ref_[/* (N0 + N1) * 7 */] = {
0, 16, 0.889883f, 0.177204f, 0.356279f, 0.417204f, 0.937517f,
0, 7, 0.816615f, 0.604293f, 0.137345f, 0.918016f, 0.295708f,
0, 1, 0.595912f, 0.0940107f, 0.178122f, 0.750619f, 0.829336f,
1, 2, 0.998224f, 0.652883f, 0.463477f, 0.813952f, 0.657163f,
1, 2, 0.967396f, 0.4539f, 0.466368f, 0.497716f, 0.520299f,
1, 0, 0.807866f, 0.205039f, 0.361842f, 0.260984f, 0.643621f,
};
Mat ref(N0 + N1, 7, CV_32FC1, (void*)ref_);
double scoreDiff = 0.012f;
double iouDiff = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD || target == DNN_TARGET_CPU_FP16) ? 0.15 : 0.01f;
if (target == DNN_TARGET_CUDA_FP16)
iouDiff = 0.02;
std::string model_file = "yolov4-tiny.onnx";
{
SCOPED_TRACE("batch size 1");
testYOLOModel(model_file, ref.rowRange(0, N0), scoreDiff, iouDiff, confThreshold, 0.4, false, 0, Size(416, 416));
}
{
SCOPED_TRACE("batch size 2");
testYOLOModel(model_file, ref, scoreDiff, iouDiff, confThreshold, 0.4, false, 0, Size(416, 416));
}
}
TEST_P(Test_YOLO_nets, YOLOv4x_mish)
{
applyTestTag(
CV_TEST_TAG_MEMORY_2GB,
CV_TEST_TAG_LONG,
CV_TEST_TAG_DEBUG_VERYLONG
);
// batchId, classId, confidence, left, top, right, bottom
const int N0 = 3;
const int N1 = 5;
static const float ref_[/* (N0 + N1) * 7 */] = {
0, 1, 0.93241f, 0.161592f, 0.232638f, 0.738411f, 0.731285f,
0, 16, 0.929881f, 0.171312f, 0.385948f, 0.405568f, 0.940067f,
0, 7, 0.812158f, 0.60486f, 0.129621f, 0.895285f, 0.296402f,
1, 2, 0.929241f, 0.651517f, 0.457701f, 0.8147f, 0.660816f,
1, 0, 0.918966f, 0.200175f, 0.35915f, 0.265996f, 0.631935f,
1, 2, 0.881782f, 0.45082f, 0.461253f, 0.495884f, 0.522369f,
1, 9, 0.746081f, 0.661127f, 0.372649f, 0.686827f, 0.441998f,
1, 9, 0.730318f, 0.373671f, 0.314795f, 0.401108f, 0.397822f,
};
Mat ref(N0 + N1, 7, CV_32FC1, (void*)ref_);
double scoreDiff = 8e-5;
double iouDiff = 3e-4;
if (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD || target == DNN_TARGET_CUDA_FP16 || target == DNN_TARGET_CPU_FP16)
{
scoreDiff = 0.006;
iouDiff = 0.042;
}
std::string model_file = "yolov4x-mish.onnx";
{
SCOPED_TRACE("batch size 1");
testYOLOModel(model_file, ref.rowRange(0, N0), scoreDiff, iouDiff, 0.24, 0.4, false, 0, Size(640, 640));
}
{
SCOPED_TRACE("batch size 2");
testYOLOModel(model_file, ref, scoreDiff, iouDiff, 0.24, 0.4, false, 0, Size(640, 640));
}
}
INSTANTIATE_TEST_CASE_P(/**/, Test_YOLO_nets, dnnBackendsAndTargets());
}} // namespace
+542
View File
@@ -0,0 +1,542 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
// Copyright (C) 2025, BigVision LLC, all rights reserved.
// Third party copyrights are property of their respective owners.
#include "test_precomp.hpp"
#include <opencv2/dnn/all_layers.hpp>
#include <opencv2/dnn/shape_utils.hpp>
namespace opencv_test { namespace {
//build a single-layer network
static Net buildSingleLayerNet(LayerParams& lp, const MatShape& inputShape,
int inputType = CV_32F)
{
Net net;
net.addLayerToPrev(lp.name, lp.type, lp);
Mat input(inputShape, inputType);
randu(input, -1, 1);
net.setInput(input);
net.setPreferableBackend(DNN_BACKEND_OPENCV);
return net;
}
TEST(Test_GetFLOPS, Convolution)
{
LayerParams lp;
lp.type = "Convolution";
lp.name = "conv";
lp.set("kernel_size", 3);
lp.set("num_output", 64);
lp.set("pad", 1);
lp.set("bias_term", true);
int weightsShape[] = {64, 3, 3, 3};
Mat weights(4, weightsShape, CV_32F);
randu(weights, -1, 1);
lp.blobs.push_back(weights);
Mat bias(1, 64, CV_32F, Scalar(0));
lp.blobs.push_back(bias);
MatShape inputShape{1, 3, 224, 224};
Net net = buildSingleLayerNet(lp, inputShape);
int64 flops = net.getFLOPS(inputShape, CV_32F);
// Expected: output is [1, 64, 224, 224]
// FLOPS per output element = 2 * 3*3*3 + 1 = 55
// Total = 1 * 64 * 224 * 224 * 55 = 176,455,680
// But the Data layer also contributes 0 flops, so total = conv flops
int64 expectedFlops = (int64)1 * 64 * 224 * 224 * (2 * 3 * 3 * 3 + 1);
EXPECT_EQ(flops, expectedFlops);
}
TEST(Test_GetFLOPS, FullyConnected)
{
LayerParams lp;
lp.type = "InnerProduct";
lp.name = "fc";
lp.set("num_output", 1000);
int weightsShape[] = {1000, 2048};
Mat weights(2, weightsShape, CV_32F);
randu(weights, -1, 1);
lp.blobs.push_back(weights);
Mat bias(1, 1000, CV_32F, Scalar(0));
lp.blobs.push_back(bias);
MatShape inputShape{1, 2048};
Net net = buildSingleLayerNet(lp, inputShape);
int64 flops = net.getFLOPS(inputShape, CV_32F);
// Expected: 3 * innerSize * output = 3 * 2048 * 1000 = 6,144,000
int64 expectedFlops = (int64)3 * 2048 * 1000;
EXPECT_EQ(flops, expectedFlops);
}
TEST(Test_GetFLOPS, MaxPooling)
{
LayerParams lp;
lp.type = "Pooling";
lp.name = "pool";
lp.set("pool", "max");
lp.set("kernel_size", 2);
lp.set("stride", 2);
MatShape inputShape{1, 64, 112, 112};
Net net = buildSingleLayerNet(lp, inputShape);
int64 flops = net.getFLOPS(inputShape, CV_32F);
// Output: [1, 64, 56, 56]
// Max pool: karea comparisons per output element = 2*2 = 4
// Total = 1 * 64 * 56 * 56 * 4 = 802,816
int64 expectedFlops = (int64)1 * 64 * 56 * 56 * 4;
EXPECT_EQ(flops, expectedFlops);
}
TEST(Test_GetFLOPS, BatchNorm)
{
LayerParams lp;
lp.type = "BatchNorm";
lp.name = "bn";
lp.set("has_weight", true);
lp.set("has_bias", true);
lp.set("eps", 1e-5);
int channels = 64;
Mat mean(1, channels, CV_32F, Scalar(0));
Mat var(1, channels, CV_32F, Scalar(1));
Mat scale(1, channels, CV_32F, Scalar(1));
Mat shift(1, channels, CV_32F, Scalar(0));
lp.blobs.push_back(mean);
lp.blobs.push_back(var);
lp.blobs.push_back(scale);
lp.blobs.push_back(shift);
MatShape inputShape{1, 64, 56, 56};
Net net = buildSingleLayerNet(lp, inputShape);
int64 flops = net.getFLOPS(inputShape, CV_32F);
// BatchNorm: 3 flops per element
int64 expectedFlops = (int64)3 * 1 * 64 * 56 * 56;
EXPECT_EQ(flops, expectedFlops);
}
TEST(Test_GetFLOPS, Softmax)
{
LayerParams lp;
lp.type = "Softmax";
lp.name = "softmax";
MatShape inputShape{1, 1000};
Net net = buildSingleLayerNet(lp, inputShape);
int64 flops = net.getFLOPS(inputShape, CV_32F);
// Softmax: 4 flops per element
int64 expectedFlops = (int64)4 * 1000;
EXPECT_EQ(flops, expectedFlops);
}
TEST(Test_GetFLOPS, Scale)
{
LayerParams lp;
lp.type = "Scale";
lp.name = "scale";
lp.set("axis", 1);
lp.set("has_bias", true);
int channels = 64;
Mat scaleData(1, channels, CV_32F, Scalar(1));
Mat biasData(1, channels, CV_32F, Scalar(0));
lp.blobs.push_back(scaleData);
lp.blobs.push_back(biasData);
MatShape inputShape{1, 64, 56, 56};
Net net = buildSingleLayerNet(lp, inputShape);
int64 flops = net.getFLOPS(inputShape, CV_32F);
// Scale: 2 flops per element (multiply + add)
int64 expectedFlops = (int64)2 * 1 * 64 * 56 * 56;
EXPECT_EQ(flops, expectedFlops);
}
TEST(Test_GetFLOPS, MultiLayerNetwork)
{
// Build a small network: Conv -> BatchNorm -> Pooling
Net net;
// Conv layer
{
LayerParams lp;
lp.type = "Convolution";
lp.name = "conv1";
lp.set("kernel_size", 3);
lp.set("num_output", 16);
lp.set("pad", 1);
lp.set("bias_term", true);
int wShape[] = {16, 3, 3, 3};
Mat w(4, wShape, CV_32F);
randu(w, -1, 1);
lp.blobs.push_back(w);
Mat b(1, 16, CV_32F, Scalar(0));
lp.blobs.push_back(b);
net.addLayerToPrev(lp.name, lp.type, lp);
}
// BatchNorm
{
LayerParams lp;
lp.type = "BatchNorm";
lp.name = "bn1";
lp.set("has_weight", true);
lp.set("has_bias", true);
lp.set("eps", 1e-5);
Mat mean(1, 16, CV_32F, Scalar(0));
Mat var(1, 16, CV_32F, Scalar(1));
Mat scale(1, 16, CV_32F, Scalar(1));
Mat shift(1, 16, CV_32F, Scalar(0));
lp.blobs.push_back(mean);
lp.blobs.push_back(var);
lp.blobs.push_back(scale);
lp.blobs.push_back(shift);
net.addLayerToPrev(lp.name, lp.type, lp);
}
// MaxPool
{
LayerParams lp;
lp.type = "Pooling";
lp.name = "pool1";
lp.set("pool", "max");
lp.set("kernel_size", 2);
lp.set("stride", 2);
net.addLayerToPrev(lp.name, lp.type, lp);
}
MatShape inputShape{1, 3, 32, 32};
Mat input(inputShape, CV_32F);
randu(input, -1, 1);
net.setInput(input);
net.setPreferableBackend(DNN_BACKEND_OPENCV);
int64 flops = net.getFLOPS(inputShape, CV_32F);
// Conv: output [1,16,32,32], flops = 1*16*32*32*(2*3*3*3+1) = 903,168
int64 convFlops = (int64)1 * 16 * 32 * 32 * (2 * 3 * 3 * 3 + 1);
// BN: 3 * 1*16*32*32 = 49,152
int64 bnFlops = (int64)3 * 1 * 16 * 32 * 32;
// Pool: output [1,16,16,16], karea=4, flops = 1*16*16*16*4 = 16,384
int64 poolFlops = (int64)1 * 16 * 16 * 16 * 4;
int64 expectedFlops = convFlops + bnFlops + poolFlops;
EXPECT_EQ(flops, expectedFlops);
}
TEST(Test_GetFLOPS, EmptyNet)
{
Net net;
MatShape inputShape{1, 3, 224, 224};
// An empty net should not crash
EXPECT_NO_THROW(net.getFLOPS(inputShape, CV_32F));
}
TEST(Test_GetFLOPS, PerLayerFLOPS)
{
// Test getFLOPS with specific layerId
Net net;
// Conv layer
{
LayerParams lp;
lp.type = "Convolution";
lp.name = "conv1";
lp.set("kernel_size", 3);
lp.set("num_output", 8);
lp.set("pad", 1);
lp.set("bias_term", true);
int wShape[] = {8, 3, 3, 3};
Mat w(4, wShape, CV_32F);
randu(w, -1, 1);
lp.blobs.push_back(w);
Mat b(1, 8, CV_32F, Scalar(0));
lp.blobs.push_back(b);
net.addLayerToPrev(lp.name, lp.type, lp);
}
// Softmax
{
LayerParams lp;
lp.type = "Softmax";
lp.name = "softmax";
net.addLayerToPrev(lp.name, lp.type, lp);
}
MatShape inputShape{1, 3, 16, 16};
Mat input(inputShape, CV_32F);
randu(input, -1, 1);
net.setInput(input);
net.setPreferableBackend(DNN_BACKEND_OPENCV);
if (!net.getMainGraph()) {
int convId = net.getLayerId("conv1");
int64 convFlops = net.getFLOPS(convId, inputShape, CV_32F);
int64 expectedConvFlops = (int64)1 * 8 * 16 * 16 * (2 * 3 * 3 * 3 + 1);
EXPECT_EQ(convFlops, expectedConvFlops);
int softmaxId = net.getLayerId("softmax");
int64 softmaxFlops = net.getFLOPS(softmaxId, inputShape, CV_32F);
// Softmax output: [1, 8, 16, 16] => 4 * 8 * 16 * 16
int64 expectedSoftmaxFlops = (int64)4 * 1 * 8 * 16 * 16;
EXPECT_EQ(softmaxFlops, expectedSoftmaxFlops);
}
}
TEST(Test_GetFLOPS, MatMulLayer)
{
// Test MatMul getFLOPS directly via the layer interface
LayerParams lp;
lp.type = "MatMul";
lp.name = "matmul";
lp.set("transA", false);
lp.set("transB", false);
Ptr<Layer> layer = LayerFactory::createLayerInstance("MatMul", lp);
ASSERT_TRUE(layer);
// A=[2,4,8], B=[2,8,16] => output=[2,4,16], K=8
std::vector<MatShape> inputs = {MatShape{2, 4, 8}, MatShape{2, 8, 16}};
std::vector<MatShape> outputs = {MatShape{2, 4, 16}};
int64 flops = layer->getFLOPS(inputs, outputs);
// batch=2, M=4, N=16, K=8
// flops = 2 * (2 * 4 * 16 * 8) = 2048
int64 expected = (int64)2 * (2 * 4 * 16 * 8);
EXPECT_EQ(flops, expected);
}
TEST(Test_GetFLOPS, MatMulLayerTranspose)
{
LayerParams lp;
lp.type = "MatMul";
lp.name = "matmul_t";
lp.set("transA", true);
lp.set("transB", false);
Ptr<Layer> layer = LayerFactory::createLayerInstance("MatMul", lp);
ASSERT_TRUE(layer);
// transA: A=[2,8,4] => M=4,K=8; B=[2,8,16] => N=16
std::vector<MatShape> inputs = {MatShape{2, 8, 4}, MatShape{2, 8, 16}};
std::vector<MatShape> outputs = {MatShape{2, 4, 16}};
int64 flops = layer->getFLOPS(inputs, outputs);
int64 expected = (int64)2 * (2 * 4 * 16 * 8);
EXPECT_EQ(flops, expected);
}
TEST(Test_GetFLOPS, GemmLayer)
{
LayerParams lp;
lp.type = "Gemm";
lp.name = "gemm";
lp.set("transA", false);
lp.set("transB", false);
lp.set("alpha", 1.0f);
lp.set("beta", 1.0f);
lp.set("have_bias", true);
// B as blob: [128, 64]
Mat B(128, 64, CV_32F);
randu(B, -1, 1);
lp.blobs.push_back(B);
// C as blob: [1, 64]
Mat C(1, 64, CV_32F, Scalar(0));
lp.blobs.push_back(C);
Ptr<Layer> layer = LayerFactory::createLayerInstance("Gemm", lp);
ASSERT_TRUE(layer);
// A=[32, 128], B=[128, 64] => output=[32, 64]
// M=32, K=128, N=64
std::vector<MatShape> inputs = {MatShape{32, 128}};
std::vector<MatShape> outputs = {MatShape{32, 64}};
int64 flops = layer->getFLOPS(inputs, outputs);
// 2*M*N*K + M*N (bias) = 2*32*64*128 + 32*64 = 524,288 + 2,048 = 526,336
int64 expected = (int64)2 * 32 * 64 * 128 + (int64)32 * 64;
EXPECT_EQ(flops, expected);
}
TEST(Test_GetFLOPS, AttentionLayer)
{
LayerParams lp;
lp.type = "Attention";
lp.name = "attention";
int num_heads = 4;
int D = 32; // input hidden size
int hidden = 48; // total projected size (q + k + v)
// qkv_hidden_sizes: q=16, k=16, v=16
int qkv_sizes[] = {16, 16, 16};
lp.set("num_heads", num_heads);
lp.set("qkv_hidden_sizes", DictValue::arrayInt(qkv_sizes, 3));
// Weight blob: [D, hidden] = [32, 48]
Mat weight(D, hidden, CV_32F);
randu(weight, -1, 1);
lp.blobs.push_back(weight);
// Bias blob: [1, hidden]
Mat bias(1, hidden, CV_32F, Scalar(0));
lp.blobs.push_back(bias);
Ptr<Layer> layer = LayerFactory::createLayerInstance("Attention", lp);
ASSERT_TRUE(layer);
int64 B = 2, S = 8;
int64 q_size = 16, k_size = 16;
int64 v_size = hidden - q_size - k_size; // 16
int64 q_head = q_size / num_heads; // 4
int64 v_head = v_size / num_heads; // 4
std::vector<MatShape> inputs = {MatShape{(int)B, (int)S, D}};
std::vector<MatShape> outputs = {MatShape{(int)B, (int)S, (int)(v_head * num_heads)}};
int64 flops = layer->getFLOPS(inputs, outputs);
// Input projection: B * S * 2 * D * hidden
int64 expected = B * S * (CV_BIG_INT(2) * D * hidden);
// QK^T: B * num_heads * 2 * S * S * q_head
expected += B * num_heads * CV_BIG_INT(2) * S * S * q_head;
// Softmax: B * num_heads * 4 * S * S
expected += B * num_heads * 4 * S * S;
// Attention * V: B * num_heads * 2 * S * v_head * S
expected += B * num_heads * CV_BIG_INT(2) * S * v_head * S;
EXPECT_EQ(flops, expected);
}
TEST(Test_GetFLOPS, AttentionOnnxAiLayer)
{
// Test AttentionOnnxAi (multi-head attention with separate Q, K, V inputs)
LayerParams lp;
lp.type = "AttentionOnnxAi";
lp.name = "attn_onnxai";
int nhq = 4, nhkv = 4;
lp.set("q_num_heads", nhq);
lp.set("kv_num_heads", nhkv);
Ptr<Layer> layer = LayerFactory::createLayerInstance("AttentionOnnxAi", lp);
ASSERT_TRUE(layer);
int64 B = 2, Sq = 8, Skv = 8;
int qk_head = 16, v_head = 16;
// 4D inputs: [B, num_heads, seq_len, head_dim]
std::vector<MatShape> inputs = {
MatShape{(int)B, nhq, (int)Sq, qk_head}, // Q
MatShape{(int)B, nhkv, (int)Skv, qk_head}, // K
MatShape{(int)B, nhkv, (int)Skv, v_head} // V
};
std::vector<MatShape> outputs = {MatShape{(int)B, nhq, (int)Sq, v_head}};
int64 flops = layer->getFLOPS(inputs, outputs);
// QK^T: B * nhq * 2 * Sq * Skv * qk_head
int64 expected = B * nhq * CV_BIG_INT(2) * Sq * Skv * qk_head;
// Softmax: B * nhq * 4 * Sq * Skv
expected += B * nhq * 4 * Sq * Skv;
// Attention * V: B * nhq * 2 * Sq * v_head * Skv
expected += B * nhq * CV_BIG_INT(2) * Sq * v_head * Skv;
EXPECT_EQ(flops, expected);
}
TEST(Test_GetFLOPS, EinsumLayer)
{
// Test Einsum: batch matrix multiply "bij,bjk->bik"
LayerParams lp;
lp.type = "Einsum";
lp.name = "einsum";
lp.set("equation", "bij,bjk->bik");
lp.set("inputSize", 2);
lp.set("outputSize", 1);
Ptr<Layer> layer = LayerFactory::createLayerInstance("Einsum", lp);
ASSERT_TRUE(layer);
// A=[2,4,8], B=[2,8,6] => output=[2,4,6]
// Indices: b=2, i=4, j=8, k=6
std::vector<MatShape> inputs = {MatShape{2, 4, 8}, MatShape{2, 8, 6}};
std::vector<MatShape> outputs = {MatShape{2, 4, 6}};
int64 flops = layer->getFLOPS(inputs, outputs);
// totalProduct = product of all subscript dims = 2 * 4 * 8 * 6 = 384
// flops = 2 * totalProduct = 768
int64 expected = CV_BIG_INT(2) * 2 * 4 * 8 * 6;
EXPECT_EQ(flops, expected);
}
TEST(Test_GetFLOPS, EinsumLayerTranspose)
{
// Test Einsum: transpose "ij->ji"
LayerParams lp;
lp.type = "Einsum";
lp.name = "einsum_transpose";
lp.set("equation", "ij->ji");
lp.set("inputSize", 1);
lp.set("outputSize", 1);
Ptr<Layer> layer = LayerFactory::createLayerInstance("Einsum", lp);
ASSERT_TRUE(layer);
std::vector<MatShape> inputs = {MatShape{3, 5}};
std::vector<MatShape> outputs = {MatShape{5, 3}};
int64 flops = layer->getFLOPS(inputs, outputs);
// Indices: i=3, j=5, totalProduct = 15, flops = 2 * 15 = 30
int64 expected = CV_BIG_INT(2) * 3 * 5;
EXPECT_EQ(flops, expected);
}
TEST(Test_GetFLOPS, ZeroFlopsLayers)
{
// Layers that should return 0 FLOPS (data movement only)
std::vector<std::string> zeroFlopsTypes = {"Flatten", "Reshape"};
for (const auto& typeName : zeroFlopsTypes) {
LayerParams lp;
lp.type = typeName;
lp.name = typeName + "_test";
if (typeName == "Reshape") {
int newShape[] = {1, -1};
lp.set("dim", DictValue::arrayInt(newShape, 2));
}
Ptr<Layer> layer = LayerFactory::createLayerInstance(typeName, lp);
if (!layer) continue;
std::vector<MatShape> inputs = {MatShape{1, 3, 4, 4}};
std::vector<MatShape> outputs = {MatShape{1, 48}};
int64 flops = layer->getFLOPS(inputs, outputs);
EXPECT_EQ(flops, (int64)0) << "Layer type " << typeName << " should have 0 FLOPS";
}
}
}} // namespace
+162
View File
@@ -0,0 +1,162 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#include "test_precomp.hpp"
namespace opencv_test { namespace {
class Test_Graph_Simplifier : public ::testing::Test {
public:
bool required;
Test_Graph_Simplifier() : required(true) {}
void test_conformance(const std::string &basename, const std::string &expected_layer) {
test(basename + std::string("/model"), std::vector<std::string>{expected_layer}, std::string("dnn/onnx/conformance/node/"));
}
void test(const std::string &basename, const std::string &expected_layer) {
test(basename, std::vector<std::string>{expected_layer});
}
void test(const std::string &basename, const std::vector<std::string> &expected_layers, const std::string &model_path_prefix = std::string("dnn/onnx/models/")) {
std::string model_path = findDataFile(model_path_prefix + basename + std::string(".onnx"), required);
auto net = readNet(model_path);
std::vector<std::string> layers;
net.getLayerTypes(layers);
// remove Const, Identity (output layer), __NetInputLayer__ (input layer)
layers.erase(std::remove_if(layers.begin(), layers.end(), [] (const std::string l) { return l == "Const" || l == "Identity" || l == "__NetInputLayer__"; }), layers.end());
// Instead of 'Tile', 'Expand' etc. we may now have 'Tile2', 'Expand2' etc.
// We should correctly match them with the respective patterns
for (auto& l: layers) {
if (!l.empty() && l[l.size()-1] == '2')
l = l.substr(0, l.size()-1);
}
EXPECT_EQ(layers, expected_layers);
}
};
TEST_F(Test_Graph_Simplifier, GeluSubGraph) {
test("gelu", "Gelu");
test("bias_gelu", std::vector<std::string>{"Gelu", "NaryEltwise"});
}
TEST_F(Test_Graph_Simplifier, GeluApproximationSubGraph) {
test("gelu_approximation", "GeluApproximation");
}
TEST_F(Test_Graph_Simplifier, LayerNormSubGraph) {
test("layer_norm_expanded", "LayerNormalization");
test("layer_norm_expanded_with_initializers", "LayerNormalization");
}
TEST_F(Test_Graph_Simplifier, LayerNormNoFusionSubGraph) {
test("layer_norm_no_fusion", std::vector<std::string>{"NaryEltwise", "Reduce", "Sqrt"});
}
TEST_F(Test_Graph_Simplifier, DISABLED_ResizeSubgraph) {
/* Test for 6 subgraphs:
- GatherCastSubgraph
- MulCastSubgraph
- UpsampleSubgraph
- ResizeSubgraph1
- ResizeSubgraph2
- ResizeSubgraph3
*/
test("upsample_unfused_torch1.2", std::vector<std::string>{"BatchNorm", "Resize"});
test("resize_nearest_unfused_opset11_torch1.3", std::vector<std::string>{"BatchNorm", "Convolution", "Resize"});
test("resize_nearest_unfused_opset11_torch1.4", std::vector<std::string>{"BatchNorm", "Convolution", "Resize"});
test("upsample_unfused_opset9_torch1.4", std::vector<std::string>{"BatchNorm", "Convolution", "Resize"});
test("two_resizes_with_shared_subgraphs", std::vector<std::string>{"NaryEltwise", "Resize"});
}
TEST_F(Test_Graph_Simplifier, SoftmaxSubgraph) {
/* Test for 3 subgraphs
- SoftMaxSubgraph
- SoftMaxSubgraph2 (conformance)
- LogSoftMaxSubgraph (conformance)
*/
test("softmax_unfused", "Softmax");
test_conformance("test_softmax_example_expanded", "Softmax");
test_conformance("test_softmax_axis_2_expanded", "Softmax");
test_conformance("test_softmax_default_axis_expanded", "Softmax");
test_conformance("test_softmax_axis_0_expanded", "Softmax");
test_conformance("test_softmax_axis_1_expanded", "Softmax");
test_conformance("test_softmax_large_number_expanded", "Softmax");
test_conformance("test_softmax_negative_axis_expanded", "Softmax");
test_conformance("test_logsoftmax_axis_2_expanded", "Softmax");
test_conformance("test_logsoftmax_example_1_expanded", "Softmax");
test_conformance("test_logsoftmax_negative_axis_expanded", "Softmax");
test_conformance("test_logsoftmax_axis_0_expanded", "Softmax");
test_conformance("test_logsoftmax_axis_1_expanded", "Softmax");
test_conformance("test_logsoftmax_large_number_expanded", "Softmax");
test_conformance("test_logsoftmax_default_axis_expanded", "Softmax");
}
TEST_F(Test_Graph_Simplifier, HardSwishSubgraph) {
test_conformance("test_hardswish_expanded", "HardSwish");
}
TEST_F(Test_Graph_Simplifier, CeluSubgraph) {
test_conformance("test_celu_expanded", "Celu");
}
TEST_F(Test_Graph_Simplifier, NormalizeSubgraph) {
/* Test for 6 subgraphs
- NormalizeSubgraph1
- NormalizeSubgraph2
- NormalizeSubgraph2_2
- NormalizeSubgraph3
- NormalizeSubgraph4
- NormalizeSubgraph5
*/
test("reduceL2_subgraph_2", "Normalize");
test("reduceL2_subgraph", "Normalize");
test("normalize_fusion", "Normalize");
}
TEST_F(Test_Graph_Simplifier, BatchNormalizationSubgraph) {
/* Test for 2 subgraphs
- BatchNormalizationSubgraph1
- BatchNormalizationSubgraph2
*/
test("frozenBatchNorm2d", "BatchNorm");
test("batch_norm_subgraph", "BatchNorm");
}
TEST_F(Test_Graph_Simplifier, ExpandSubgraph) {
test("expand_neg_batch", "Expand");
}
TEST_F(Test_Graph_Simplifier, MishSubgraph) {
/* Test for 2 subgraphs
- SoftplusSubgraph
- MishSubgraph
*/
test("mish_no_softplus", "Mish");
test("mish", "Mish");
}
TEST_F(Test_Graph_Simplifier, AttentionSubgraph) {
/* Test for 2 subgraphs
- AttentionSubgraph
- AttentionSingleHeadSubgraph
*/
test("attention", "Attention");
test("attention_single_head", "Attention");
}
TEST_F(Test_Graph_Simplifier, BiasedMatMulSubgraph) {
/* Test for 1 subgraphs
- BiasedMatMulSubgraph
*/
auto engine_forced = static_cast<cv::dnn::EngineType>(
cv::utils::getConfigurationParameterSizeT("OPENCV_FORCE_DNN_ENGINE", cv::dnn::ENGINE_AUTO));
const std::string expected = engine_forced == cv::dnn::ENGINE_CLASSIC ? "MatMul" : "Gemm";
test("biased_matmul", expected);
}
}}
+438
View File
@@ -0,0 +1,438 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
//
// Copyright (C) 2018-2019, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
#include "test_precomp.hpp"
#ifdef HAVE_INF_ENGINE
#include <opencv2/core/utils/filesystem.hpp>
//
// Synchronize headers include statements with src/op_inf_engine.hpp
//
//#define INFERENCE_ENGINE_DEPRECATED // turn off deprecation warnings from IE
//there is no way to suppress warnings from IE only at this moment, so we are forced to suppress warnings globally
#if defined(__GNUC__)
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
#ifdef _MSC_VER
#pragma warning(disable: 4996) // was declared deprecated
#endif
#if defined(__GNUC__)
#pragma GCC visibility push(default)
#endif
#if defined(__GNUC__)
#pragma GCC visibility pop
#endif
#include <openvino/runtime/core.hpp>
namespace opencv_test { namespace {
static void initDLDTDataPath()
{
#ifndef WINRT
static bool initialized = false;
if (!initialized)
{
#if INF_ENGINE_RELEASE <= 2018050000
cvtest::addDataSearchEnv("INTEL_CVSDK_DIR");
#else
cvtest::addDataSearchEnv("OPENCV_OPEN_MODEL_ZOO_DATA_PATH");
const std::string dnnDataPath = cv::utils::getConfigurationParameterString("OPENCV_DNN_TEST_DATA_PATH");
if (!dnnDataPath.empty())
cvtest::addDataSearchPath(std::string(dnnDataPath) + "/omz_intel_models");
#endif
initialized = true;
}
#endif
}
using namespace cv;
using namespace cv::dnn;
struct OpenVINOModelTestCaseInfo
{
const char* modelPathFP32;
const char* modelPathFP16;
};
static const std::map<std::string, OpenVINOModelTestCaseInfo>& getOpenVINOTestModels()
{
static std::map<std::string, OpenVINOModelTestCaseInfo> g_models {
#if INF_ENGINE_RELEASE >= 2018050000 && \
INF_ENGINE_RELEASE <= 2020999999 // don't use IRv5 models with 2020.1+
// layout is defined by open_model_zoo/model_downloader
// Downloaded using these parameters for Open Model Zoo downloader (2019R1):
// ./downloader.py -o ${OPENCV_DNN_TEST_DATA_PATH}/omz_intel_models --cache_dir ${OPENCV_DNN_TEST_DATA_PATH}/.omz_cache/ \
// --name face-person-detection-retail-0002,face-person-detection-retail-0002-fp16,age-gender-recognition-retail-0013,age-gender-recognition-retail-0013-fp16,head-pose-estimation-adas-0001,head-pose-estimation-adas-0001-fp16,person-detection-retail-0002,person-detection-retail-0002-fp16,vehicle-detection-adas-0002,vehicle-detection-adas-0002-fp16
{ "age-gender-recognition-retail-0013", {
"Retail/object_attributes/age_gender/dldt/age-gender-recognition-retail-0013",
"Retail/object_attributes/age_gender/dldt/age-gender-recognition-retail-0013-fp16"
}},
{ "face-person-detection-retail-0002", {
"Retail/object_detection/face_pedestrian/rmnet-ssssd-2heads/0002/dldt/face-person-detection-retail-0002",
"Retail/object_detection/face_pedestrian/rmnet-ssssd-2heads/0002/dldt/face-person-detection-retail-0002-fp16"
}},
{ "head-pose-estimation-adas-0001", {
"Transportation/object_attributes/headpose/vanilla_cnn/dldt/head-pose-estimation-adas-0001",
"Transportation/object_attributes/headpose/vanilla_cnn/dldt/head-pose-estimation-adas-0001-fp16"
}},
{ "person-detection-retail-0002", {
"Retail/object_detection/pedestrian/hypernet-rfcn/0026/dldt/person-detection-retail-0002",
"Retail/object_detection/pedestrian/hypernet-rfcn/0026/dldt/person-detection-retail-0002-fp16"
}},
{ "vehicle-detection-adas-0002", {
"Transportation/object_detection/vehicle/mobilenet-reduced-ssd/dldt/vehicle-detection-adas-0002",
"Transportation/object_detection/vehicle/mobilenet-reduced-ssd/dldt/vehicle-detection-adas-0002-fp16"
}},
#endif
#if INF_ENGINE_RELEASE >= 2020010000
// Downloaded using these parameters for Open Model Zoo downloader (2020.1):
// ./downloader.py -o ${OPENCV_DNN_TEST_DATA_PATH}/omz_intel_models --cache_dir ${OPENCV_DNN_TEST_DATA_PATH}/.omz_cache/ \
// --name person-detection-retail-0013,age-gender-recognition-retail-0013
{ "person-detection-retail-0013", { // IRv10
"intel/person-detection-retail-0013/FP32/person-detection-retail-0013",
"intel/person-detection-retail-0013/FP16/person-detection-retail-0013"
}},
{ "age-gender-recognition-retail-0013", {
"intel/age-gender-recognition-retail-0013/FP16/age-gender-recognition-retail-0013",
"intel/age-gender-recognition-retail-0013/FP32/age-gender-recognition-retail-0013"
}},
#endif
};
return g_models;
}
static const std::vector<std::string> getOpenVINOTestModelsList()
{
std::vector<std::string> result;
const std::map<std::string, OpenVINOModelTestCaseInfo>& models = getOpenVINOTestModels();
for (const auto& it : models)
result.push_back(it.first);
return result;
}
inline static std::string getOpenVINOModel(const std::string &modelName, bool isFP16)
{
const std::map<std::string, OpenVINOModelTestCaseInfo>& models = getOpenVINOTestModels();
const auto it = models.find(modelName);
if (it != models.end())
{
OpenVINOModelTestCaseInfo modelInfo = it->second;
if (isFP16 && modelInfo.modelPathFP16)
return std::string(modelInfo.modelPathFP16);
else if (!isFP16 && modelInfo.modelPathFP32)
return std::string(modelInfo.modelPathFP32);
}
return std::string();
}
void runIE(Target target, const std::string& xmlPath, const std::string& binPath,
std::map<std::string, cv::Mat>& inputsMap, std::map<std::string, cv::Mat>& outputsMap)
{
SCOPED_TRACE("runIE");
std::string device_name;
ov::Core core;
auto model = core.read_model(xmlPath, binPath);
ov::CompiledModel compiledModel;
ov::InferRequest infRequest;
try
{
switch (target)
{
case DNN_TARGET_CPU:
device_name = "CPU";
break;
case DNN_TARGET_OPENCL:
case DNN_TARGET_OPENCL_FP16:
device_name = "GPU";
break;
case DNN_TARGET_MYRIAD:
device_name = "MYRIAD";
break;
case DNN_TARGET_FPGA:
device_name = "FPGA";
break;
default:
CV_Error(Error::StsNotImplemented, "Unknown target");
};
if (target == DNN_TARGET_CPU || target == DNN_TARGET_FPGA)
{
std::string suffixes[] = {"_avx2", "_sse4", ""};
bool haveFeature[] = {
checkHardwareSupport(CPU_AVX2),
checkHardwareSupport(CPU_SSE4_2),
true
};
for (int i = 0; i < 3; ++i)
{
if (!haveFeature[i])
continue;
#ifdef _WIN32
std::string libName = "cpu_extension" + suffixes[i] + ".dll";
#elif defined(__APPLE__)
std::string libName = "libcpu_extension" + suffixes[i] + ".dylib";
#else
std::string libName = "libcpu_extension" + suffixes[i] + ".so";
#endif // _WIN32
try
{
core.add_extension(libName);
break;
}
catch(...) {}
}
// Some of networks can work without a library of extra layers.
}
compiledModel = core.compile_model(model, device_name);
infRequest = compiledModel.create_infer_request();
}
catch (const std::exception& ex)
{
CV_Error(Error::StsAssert, format("Failed to initialize Inference Engine backend: %s", ex.what()));
}
// Fill input tensors.
inputsMap.clear();
for (auto&& it : model->inputs())
{
auto type = it.get_element_type();
auto shape_ = it.get_partial_shape();
if (shape_.is_dynamic())
{
FAIL() << "Model should not have dynamic shapes (" << it.get_any_name() << " => " << shape_ << ")";
}
auto shape = shape_.to_shape();
auto& m = inputsMap[it.get_any_name()];
auto tensor = ov::Tensor(type, shape);
if (type == ov::element::f32)
{
m.create(std::vector<int>(shape.begin(), shape.end()), CV_32F);
randu(m, -1, 1);
}
else if (type == ov::element::i32)
{
m.create(std::vector<int>(shape.begin(), shape.end()), CV_32S);
randu(m, -100, 100);
}
else
{
FAIL() << "Unsupported precision: " << type;
}
std::memcpy(tensor.data(), m.data, tensor.get_byte_size());
if (cvtest::debugLevel > 0)
{
std::cout << "Input: '" << it.get_any_name() << "' precision=" << type << " dims=" << shape << " [";
for (auto d : shape)
std::cout << " " << d;
std::cout << "] ocv_mat=" << inputsMap[it.get_any_name()].size << " of " << typeToString(inputsMap[it.get_any_name()].type()) << std::endl;
}
infRequest.set_tensor(it, tensor);
}
infRequest.infer();
// Fill output tensors.
outputsMap.clear();
for (const auto& it : model->outputs())
{
auto type = it.get_element_type();
auto& m = outputsMap[it.get_any_name()];
auto tensor = infRequest.get_tensor(it);
auto shape = tensor.get_shape();
if (type == ov::element::f32)
{
m.create(std::vector<int>(shape.begin(), shape.end()), CV_32F);
}
else if (type == ov::element::i32)
{
m.create(std::vector<int>(shape.begin(), shape.end()), CV_32S);
}
else
{
FAIL() << "Unsupported precision: " << type;
}
std::memcpy(m.data, tensor.data(), tensor.get_byte_size());
if (cvtest::debugLevel > 0)
{
std::cout << "Output: '" << it.get_any_name() << "' precision=" << type << " dims=" << shape << " [";
for (auto d : shape)
std::cout << " " << d;
std::cout << "] ocv_mat=" << outputsMap[it.get_any_name()].size << " of " << typeToString(outputsMap[it.get_any_name()].type()) << std::endl;
}
}
}
void runCV(Backend backendId, Target targetId, const std::string& xmlPath, const std::string& binPath,
const std::map<std::string, cv::Mat>& inputsMap,
std::map<std::string, cv::Mat>& outputsMap)
{
SCOPED_TRACE("runOCV");
Net net = readNet(xmlPath, binPath);
for (auto& it : inputsMap)
net.setInput(it.second, it.first);
net.setPreferableBackend(backendId);
net.setPreferableTarget(targetId);
std::vector<String> outNames = net.getUnconnectedOutLayersNames();
if (cvtest::debugLevel > 0)
{
std::cout << "OpenCV output names: " << outNames.size() << std::endl;
for (auto name : outNames)
std::cout << "- " << name << std::endl;
}
std::vector<Mat> outs;
net.forward(outs, outNames);
outputsMap.clear();
EXPECT_EQ(outs.size(), outNames.size());
for (int i = 0; i < outs.size(); ++i)
{
EXPECT_TRUE(outputsMap.insert({outNames[i], outs[i]}).second);
}
}
typedef TestWithParam<tuple< tuple<Backend, Target>, std::string> > DNNTestOpenVINO;
TEST_P(DNNTestOpenVINO, models)
{
initDLDTDataPath();
const Backend backendId = get<0>(get<0>(GetParam()));
const Target targetId = get<1>(get<0>(GetParam()));
std::string modelName = get<1>(GetParam());
ASSERT_FALSE(backendId != DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && backendId != DNN_BACKEND_INFERENCE_ENGINE_NGRAPH) <<
"Inference Engine backend is required";
#if INF_ENGINE_VER_MAJOR_GE(2021030000)
if (targetId == DNN_TARGET_MYRIAD && (false
|| modelName == "person-detection-retail-0013" // ncDeviceOpen:1013 Failed to find booted device after boot
|| modelName == "age-gender-recognition-retail-0013" // ncDeviceOpen:1013 Failed to find booted device after boot
)
)
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
#endif
#if INF_ENGINE_VER_MAJOR_GE(2020020000)
if (targetId == DNN_TARGET_MYRIAD && backendId == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019)
{
if (modelName == "person-detection-retail-0013") // IRv10
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
}
#endif
#if INF_ENGINE_VER_MAJOR_EQ(2020040000)
if (targetId == DNN_TARGET_MYRIAD && modelName == "person-detection-retail-0002") // IRv5, OpenVINO 2020.4 regression
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
#endif
ASSERT_EQ(DNN_BACKEND_INFERENCE_ENGINE_NGRAPH, backendId);
bool isFP16 = (targetId == DNN_TARGET_OPENCL_FP16 || targetId == DNN_TARGET_MYRIAD);
const std::string modelPath = getOpenVINOModel(modelName, isFP16);
ASSERT_FALSE(modelPath.empty()) << modelName;
std::string xmlPath = findDataFile(modelPath + ".xml", false);
std::string binPath = findDataFile(modelPath + ".bin", false);
std::map<std::string, cv::Mat> inputsMap;
std::map<std::string, cv::Mat> ieOutputsMap, cvOutputsMap;
// Single Myriad device cannot be shared across multiple processes.
if (targetId == DNN_TARGET_MYRIAD)
resetMyriadDevice();
if (targetId == DNN_TARGET_HDDL)
releaseHDDLPlugin();
EXPECT_NO_THROW(runIE(targetId, xmlPath, binPath, inputsMap, ieOutputsMap)) << "runIE";
if (targetId == DNN_TARGET_MYRIAD)
resetMyriadDevice();
EXPECT_NO_THROW(runCV(backendId, targetId, xmlPath, binPath, inputsMap, cvOutputsMap)) << "runCV";
double eps = 0;
#if INF_ENGINE_VER_MAJOR_GE(2020010000)
if (targetId == DNN_TARGET_CPU && checkHardwareSupport(CV_CPU_AVX_512F))
eps = 1e-5;
#endif
EXPECT_EQ(ieOutputsMap.size(), cvOutputsMap.size());
for (auto& srcIt : ieOutputsMap)
{
auto dstIt = cvOutputsMap.find(srcIt.first);
CV_Assert(dstIt != cvOutputsMap.end());
dstIt->second.convertTo(dstIt->second, srcIt.second.type());
double normInf = cvtest::norm(srcIt.second, dstIt->second, cv::NORM_INF);
EXPECT_LE(normInf, eps) << "output=" << srcIt.first;
}
}
INSTANTIATE_TEST_CASE_P(/**/,
DNNTestOpenVINO,
Combine(dnnBackendsAndTargetsIE(),
testing::ValuesIn(getOpenVINOTestModelsList())
)
);
typedef TestWithParam<Target> DNNTestHighLevelAPI;
TEST_P(DNNTestHighLevelAPI, predict)
{
initDLDTDataPath();
Target target = (dnn::Target)(int)GetParam();
bool isFP16 = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD);
const std::string modelName = "age-gender-recognition-retail-0013";
const std::string modelPath = getOpenVINOModel(modelName, isFP16);
ASSERT_FALSE(modelPath.empty()) << modelName;
std::string xmlPath = findDataFile(modelPath + ".xml", false);
std::string binPath = findDataFile(modelPath + ".bin", false);
Model model(xmlPath, binPath);
Mat frame = imread(findDataFile("dnn/googlenet_1.png"));
std::vector<Mat> outs;
model.setPreferableBackend(DNN_BACKEND_INFERENCE_ENGINE);
model.setPreferableTarget(target);
model.predict(frame, outs);
Net net = readNet(xmlPath, binPath);
Mat input = blobFromImage(frame, 1.0, Size(62, 62));
net.setInput(input);
net.setPreferableBackend(DNN_BACKEND_INFERENCE_ENGINE);
net.setPreferableTarget(target);
std::vector<String> outNames = net.getUnconnectedOutLayersNames();
std::vector<Mat> refs;
net.forward(refs, outNames);
CV_Assert(refs.size() == outs.size());
for (int i = 0; i < refs.size(); ++i)
normAssert(outs[i], refs[i]);
}
INSTANTIATE_TEST_CASE_P(/**/,
DNNTestHighLevelAPI, testing::ValuesIn(getAvailableTargets(DNN_BACKEND_INFERENCE_ENGINE))
);
}}
#endif // HAVE_INF_ENGINE
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+7
View File
@@ -0,0 +1,7 @@
#include "test_precomp.hpp"
#if defined(HAVE_HPX)
#include <hpx/hpx_main.hpp>
#endif
CV_TEST_MAIN("", initDNNTests())
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+136
View File
@@ -0,0 +1,136 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
//
// Copyright (C) 2017, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
#include "test_precomp.hpp"
#include "npy_blob.hpp"
namespace opencv_test { namespace {
TEST(NMS, Accuracy)
{
//reference results obtained using tf.image.non_max_suppression with iou_threshold=0.5
std::string dataPath = findDataFile("dnn/nms_reference.yml");
FileStorage fs(dataPath, FileStorage::READ);
std::vector<Rect> bboxes;
std::vector<float> scores;
std::vector<int> ref_indices;
fs["boxes"] >> bboxes;
fs["probs"] >> scores;
fs["output"] >> ref_indices;
const float nms_thresh = .5f;
const float score_thresh = .01f;
std::vector<int> indices;
cv::dnn::NMSBoxes(bboxes, scores, score_thresh, nms_thresh, indices);
ASSERT_EQ(ref_indices.size(), indices.size());
std::sort(indices.begin(), indices.end());
std::sort(ref_indices.begin(), ref_indices.end());
for(size_t i = 0; i < indices.size(); i++)
ASSERT_EQ(indices[i], ref_indices[i]);
}
TEST(BatchedNMS, Accuracy)
{
//reference results obtained using tf.image.non_max_suppression with iou_threshold=0.5
std::string dataPath = findDataFile("dnn/batched_nms_reference.yml");
FileStorage fs(dataPath, FileStorage::READ);
std::vector<Rect> bboxes;
std::vector<float> scores;
std::vector<int> idxs;
std::vector<int> ref_indices;
fs["boxes"] >> bboxes;
fs["probs"] >> scores;
fs["idxs"] >> idxs;
fs["output"] >> ref_indices;
const float nms_thresh = .5f;
const float score_thresh = .05f;
std::vector<int> indices;
cv::dnn::NMSBoxesBatched(bboxes, scores, idxs, score_thresh, nms_thresh, indices);
ASSERT_EQ(ref_indices.size(), indices.size());
std::sort(indices.begin(), indices.end());
std::sort(ref_indices.begin(), ref_indices.end());
for(size_t i = 0; i < indices.size(); i++)
ASSERT_EQ(indices[i], ref_indices[i]);
}
TEST(SoftNMS, Accuracy)
{
//reference results are obtained using TF v2.7 tf.image.non_max_suppression_with_scores
std::string dataPath = findDataFile("dnn/soft_nms_reference.yml");
FileStorage fs(dataPath, FileStorage::READ);
std::vector<Rect> bboxes;
std::vector<float> scores;
std::vector<int> ref_indices;
std::vector<float> ref_updated_scores;
fs["boxes"] >> bboxes;
fs["probs"] >> scores;
fs["indices"] >> ref_indices;
fs["updated_scores"] >> ref_updated_scores;
std::vector<float> updated_scores;
const float score_thresh = .01f;
const float nms_thresh = .5f;
std::vector<int> indices;
const size_t top_k = 0;
const float sigma = 1.; // sigma in TF is being multiplied by 2, so 0.5 should be passed there
cv::dnn::softNMSBoxes(bboxes, scores, updated_scores, score_thresh, nms_thresh, indices, top_k, sigma);
ASSERT_EQ(ref_indices.size(), indices.size());
for(size_t i = 0; i < indices.size(); i++)
{
ASSERT_EQ(indices[i], ref_indices[i]);
}
ASSERT_EQ(ref_updated_scores.size(), updated_scores.size());
for(size_t i = 0; i < updated_scores.size(); i++)
{
EXPECT_NEAR(updated_scores[i], ref_updated_scores[i], 1e-7);
}
}
// Test NMS -> Reshape with zero detections using ONNX model.
// NMS with dynamic output shapes is only supported by the new engine.
TEST(NMS, ZeroDetections_Reshape)
{
auto engine_forced = static_cast<cv::dnn::EngineType>(
cv::utils::getConfigurationParameterSizeT("OPENCV_FORCE_DNN_ENGINE", cv::dnn::ENGINE_AUTO));
if (engine_forced == cv::dnn::ENGINE_CLASSIC)
{
applyTestTag(CV_TEST_TAG_DNN_SKIP_PARSER);
return;
}
std::string onnxmodel = findDataFile("dnn/onnx/models/nms_reshape_empty.onnx");
cv::dnn::Net net = cv::dnn::readNetFromONNX(onnxmodel);
ASSERT_FALSE(net.empty());
Mat boxes = blobFromNPY(findDataFile("dnn/onnx/data/input_nms_reshape_empty_0.npy"));
Mat scores = blobFromNPY(findDataFile("dnn/onnx/data/input_nms_reshape_empty_1.npy"));
net.setInput(boxes, "boxes");
net.setInput(scores, "scores");
std::vector<Mat> outs;
net.forward(outs, std::vector<String>{"output"});
ASSERT_EQ(outs.size(), (size_t)1);
Mat ref = blobFromNPY(findDataFile("dnn/onnx/data/output_nms_reshape_empty.npy"));
normAssert(ref, outs[0], "NMS_ZeroDetections_Reshape");
}
}} // namespace
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,142 @@
"test_add_bcast",
"test_add_uint8",
"test_argmax_default_axis_example",
"test_argmax_default_axis_example_select_last_index",
"test_argmax_default_axis_random",
"test_argmax_default_axis_random_select_last_index",
"test_argmax_keepdims_example",
"test_argmax_keepdims_example_select_last_index",
"test_argmax_keepdims_random",
"test_argmax_keepdims_random_select_last_index",
"test_argmax_negative_axis_keepdims_example",
"test_argmax_negative_axis_keepdims_example_select_last_index",
"test_argmax_negative_axis_keepdims_random",
"test_argmax_negative_axis_keepdims_random_select_last_index",
"test_argmax_no_keepdims_example",
"test_argmax_no_keepdims_example_select_last_index",
"test_argmax_no_keepdims_random",
"test_argmax_no_keepdims_random_select_last_index",
"test_argmin_default_axis_example",
"test_argmin_default_axis_example_select_last_index",
"test_argmin_default_axis_random",
"test_argmin_default_axis_random_select_last_index",
"test_argmin_keepdims_example",
"test_argmin_keepdims_example_select_last_index",
"test_argmin_keepdims_random",
"test_argmin_keepdims_random_select_last_index",
"test_argmin_negative_axis_keepdims_example",
"test_argmin_negative_axis_keepdims_example_select_last_index",
"test_argmin_negative_axis_keepdims_random",
"test_argmin_negative_axis_keepdims_random_select_last_index",
"test_argmin_no_keepdims_example",
"test_argmin_no_keepdims_example_select_last_index",
"test_argmin_no_keepdims_random",
"test_argmin_no_keepdims_random_select_last_index",
"test_averagepool_2d_pads_count_include_pad",
"test_averagepool_2d_precomputed_pads_count_include_pad",
"test_averagepool_2d_same_lower",
"test_basic_conv_with_padding",
"test_basic_conv_without_padding",
"test_cast_FLOAT_to_STRING",
"test_cast_STRING_to_FLOAT",
"test_castlike_FLOAT_to_STRING_expanded",
"test_castlike_STRING_to_FLOAT_expanded",
"test_cast_DOUBLE_to_FLOAT",
"test_concat_1d_axis_negative_1",
"test_conv_with_autopad_same",
"test_conv_with_strides_and_asymmetric_padding",
"test_conv_with_strides_no_padding",
"test_conv_with_strides_padding",
"test_cumsum_1d",
"test_cumsum_1d_exclusive",
"test_cumsum_1d_reverse",
"test_cumsum_1d_reverse_exclusive",
"test_cumsum_2d_axis_0",
"test_cumsum_2d_axis_1",
"test_cumsum_2d_negative_axis",
"test_div_bcast",
"test_div_uint8",
"test_dropout_default_ratio",
"test_einsum_batch_diagonal",
"test_einsum_batch_matmul",
"test_einsum_sum",
"test_einsum_transpose",
"test_flatten_axis0",
"test_flatten_axis2",
"test_flatten_axis3",
"test_flatten_negative_axis1",
"test_flatten_negative_axis2",
"test_flatten_negative_axis4",
"test_logsoftmax_default_axis",
"test_logsoftmax_large_number",
"test_logsoftmax_large_number_expanded",
"test_maxpool_2d_dilations",
"test_maxpool_2d_same_lower",
"test_maxpool_2d_uint8",
"test_maxpool_with_argmax_2d_precomputed_pads",
"test_maxpool_with_argmax_2d_precomputed_strides",
"test_maxunpool_export_with_output_shape",
"test_max_float64",
"test_min_float64",
"test_mod_mixed_sign_float64",
"test_mul_bcast",
"test_mul_uint8",
"test_softmax_default_axis",
"test_sub_bcast",
"test_sub_uint8",
"test_upsample_nearest",
"test_scatter_elements_with_axis",
"test_scatter_elements_with_duplicate_indices",
"test_scatter_elements_with_negative_indices",
"test_scatter_elements_with_reduction_max",
"test_scatter_elements_with_reduction_min",
"test_scatter_elements_without_axis",
"test_scatter_with_axis",
"test_scatter_without_axis",
"test_scatternd",
"test_scatternd_add",
"test_scatternd_max",
"test_scatternd_min",
"test_scatternd_multiply",
"test_dequantizelinear_blocked", // Issue https://github.com/opencv/opencv/issues/25999
"test_quantizelinear", // Issue https://github.com/opencv/opencv/issues/25999
"test_quantizelinear_axis", // Issue https://github.com/opencv/opencv/issues/25999
"test_quantizelinear_blocked", // Issue https://github.com/opencv/opencv/issues/25999
"test_attention_3d_attn_mask",
"test_attention_3d_causal",
"test_attention_3d_diff_heads_sizes",
"test_attention_3d_diff_heads_sizes_attn_mask",
"test_attention_3d_diff_heads_sizes_causal",
"test_attention_3d_diff_heads_sizes_softcap",
"test_attention_3d_diff_heads_sizes_scaled",
"test_attention_3d_gqa",
"test_attention_3d_gqa_attn_mask",
"test_attention_3d_gqa_causal",
"test_attention_3d_gqa_scaled",
"test_attention_3d_gqa_softcap",
"test_attention_3d_scaled",
"test_attention_3d_softcap",
"test_attention_3d_transpose_verification",
"test_attention_4d",
"test_attention_4d_attn_mask",
"test_attention_4d_attn_mask_3d",
"test_attention_4d_attn_mask_3d_causal",
"test_attention_4d_attn_mask_4d",
"test_attention_4d_attn_mask_4d_causal",
"test_attention_4d_attn_mask_bool",
"test_attention_4d_attn_mask_bool_4d",
"test_attention_4d_causal",
"test_attention_4d_diff_heads_sizes",
"test_attention_4d_diff_heads_sizes_attn_mask",
"test_attention_4d_diff_heads_sizes_causal",
"test_attention_4d_diff_heads_sizes_scaled",
"test_attention_4d_diff_heads_sizes_softcap",
"test_attention_4d_gqa",
"test_attention_4d_gqa_attn_mask",
"test_attention_4d_gqa_causal",
"test_attention_4d_gqa_scaled",
"test_attention_4d_gqa_softcap",
"test_attention_4d_scaled",
"test_attention_4d_softcap",
"test_attention_4d_attn_mask_bool",
"test_attention_4d_attn_mask_bool_4d",
@@ -0,0 +1,78 @@
"test_basic_conv_with_padding", // (assert failed) !blobs.empty() in initCUDA
"test_basic_conv_without_padding", // (assert failed) !blobs.empty() in initCUDA
"test_cast_DOUBLE_to_FLOAT",
"test_conv_with_autopad_same", // (assert failed) !blobs.empty() in initCUDA
"test_conv_with_strides_and_asymmetric_padding", // (assert failed) !blobs.empty() in initCUDA
"test_conv_with_strides_no_padding", // (assert failed) !blobs.empty() in initCUDA
"test_conv_with_strides_padding", // (assert failed) !blobs.empty() in initCUDA
"test_cumsum_1d",
"test_cumsum_1d_exclusive",
"test_cumsum_1d_reverse",
"test_cumsum_1d_reverse_exclusive",
"test_cumsum_2d_axis_0",
"test_cumsum_2d_axis_1",
"test_cumsum_2d_negative_axis",
"test_dropout_default_ratio",
"test_einsum_batch_diagonal",
"test_einsum_batch_matmul",
"test_einsum_sum",
"test_einsum_transpose",
"test_logsoftmax_large_number", // fp16 accuracy issue
"test_logsoftmax_large_number_expanded", // fp16 accuracy issue
"test_maxpool_with_argmax_2d_precomputed_pads", // assertion failed mat.type() == CV_32F
"test_nllloss_NCd1d2d3d4d5_none_no_weight_expanded", // crash: https://github.com/opencv/opencv/issues/25471
"test_reduce_prod_default_axes_keepdims_example", // fallback to cpu, accuracy
"test_reduce_prod_default_axes_keepdims_random", // fallback to cpu, accuracy
"test_reduce_sum_square_default_axes_keepdims_random", // fallback to cpu, accuracy
"test_reduce_sum_square_do_not_keepdims_random", // fallback to cpu, accuracy
"test_reduce_sum_square_keepdims_random", // fallback to cpu, accuracy
"test_reduce_sum_square_negative_axes_keepdims_random", // fallback to cpu, accuracy
"test_pow", // fp16 accuracy issue
"test_softmax_large_number", // fp16 accuracy issue
"test_softmax_large_number_expanded", // fp16 accuracy issue
"test_tan", // fp16 accuracy issue
"test_dequantizelinear_blocked", // Issue https://github.com/opencv/opencv/issues/25999
"test_quantizelinear", // Issue https://github.com/opencv/opencv/issues/25999
"test_quantizelinear_axis", // Issue https://github.com/opencv/opencv/issues/25999
"test_quantizelinear_blocked", // Issue https://github.com/opencv/opencv/issues/25999
"test_max_float64",
"test_min_float64",
"test_mod_mixed_sign_float64",
"test_attention_3d_attn_mask",
"test_attention_3d_causal",
"test_attention_3d_diff_heads_sizes",
"test_attention_3d_diff_heads_sizes_attn_mask",
"test_attention_3d_diff_heads_sizes_causal",
"test_attention_3d_diff_heads_sizes_softcap",
"test_attention_3d_diff_heads_sizes_scaled",
"test_attention_3d_gqa",
"test_attention_3d_gqa_attn_mask",
"test_attention_3d_gqa_causal",
"test_attention_3d_gqa_scaled",
"test_attention_3d_gqa_softcap",
"test_attention_3d_scaled",
"test_attention_3d_softcap",
"test_attention_3d_transpose_verification",
"test_attention_4d",
"test_attention_4d_attn_mask",
"test_attention_4d_attn_mask_3d",
"test_attention_4d_attn_mask_3d_causal",
"test_attention_4d_attn_mask_4d",
"test_attention_4d_attn_mask_4d_causal",
"test_attention_4d_attn_mask_bool",
"test_attention_4d_attn_mask_bool_4d",
"test_attention_4d_causal",
"test_attention_4d_diff_heads_sizes",
"test_attention_4d_diff_heads_sizes_attn_mask",
"test_attention_4d_diff_heads_sizes_causal",
"test_attention_4d_diff_heads_sizes_scaled",
"test_attention_4d_diff_heads_sizes_softcap",
"test_attention_4d_gqa",
"test_attention_4d_gqa_attn_mask",
"test_attention_4d_gqa_causal",
"test_attention_4d_gqa_scaled",
"test_attention_4d_gqa_softcap",
"test_attention_4d_scaled",
"test_attention_4d_softcap",
"test_attention_4d_attn_mask_bool",
"test_attention_4d_attn_mask_bool_4d",
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,135 @@
"test_add_bcast",
"test_add_uint8",
"test_argmax_default_axis_example",
"test_argmax_default_axis_example_select_last_index",
"test_argmax_default_axis_random",
"test_argmax_default_axis_random_select_last_index",
"test_argmax_keepdims_example",
"test_argmax_keepdims_example_select_last_index",
"test_argmax_keepdims_random",
"test_argmax_keepdims_random_select_last_index",
"test_argmax_negative_axis_keepdims_example",
"test_argmax_negative_axis_keepdims_example_select_last_index",
"test_argmax_negative_axis_keepdims_random",
"test_argmax_negative_axis_keepdims_random_select_last_index",
"test_argmax_no_keepdims_example",
"test_argmax_no_keepdims_example_select_last_index",
"test_argmax_no_keepdims_random",
"test_argmax_no_keepdims_random_select_last_index",
"test_argmin_default_axis_example",
"test_argmin_default_axis_example_select_last_index",
"test_argmin_default_axis_random",
"test_argmin_default_axis_random_select_last_index",
"test_argmin_keepdims_example",
"test_argmin_keepdims_example_select_last_index",
"test_argmin_keepdims_random",
"test_argmin_keepdims_random_select_last_index",
"test_argmin_negative_axis_keepdims_example",
"test_argmin_negative_axis_keepdims_example_select_last_index",
"test_argmin_negative_axis_keepdims_random",
"test_argmin_negative_axis_keepdims_random_select_last_index",
"test_argmin_no_keepdims_example",
"test_argmin_no_keepdims_example_select_last_index",
"test_argmin_no_keepdims_random",
"test_argmin_no_keepdims_random_select_last_index",
"test_averagepool_2d_pads_count_include_pad",
"test_averagepool_2d_precomputed_pads_count_include_pad",
"test_averagepool_2d_same_lower",
"test_averagepool_3d_default",
"test_cast_FLOAT_to_STRING",
"test_cast_STRING_to_FLOAT",
"test_castlike_FLOAT_to_STRING_expanded",
"test_castlike_STRING_to_FLOAT_expanded",
"test_cumsum_1d",
"test_cumsum_1d_exclusive",
"test_cumsum_1d_reverse",
"test_cumsum_1d_reverse_exclusive",
"test_cumsum_2d_axis_0",
"test_cumsum_2d_axis_1",
"test_cumsum_2d_negative_axis",
"test_concat_1d_axis_negative_1",
"test_dequantizelinear",
"test_dequantizelinear_axis",
"test_dequantizelinear_blocked",
"test_div_uint8",
"test_flatten_axis0",
"test_flatten_axis2",
"test_flatten_axis3",
"test_flatten_negative_axis1",
"test_flatten_negative_axis2",
"test_flatten_negative_axis4",
"test_gather_elements_0",
"test_gather_elements_1",
"test_gather_elements_negative_indices",
"test_logsoftmax_default_axis",
"test_maxpool_2d_dilations",
"test_maxpool_2d_same_lower",
"test_maxpool_2d_uint8",
"test_maxpool_3d_default",
"test_maxpool_with_argmax_2d_precomputed_pads",
"test_maxpool_with_argmax_2d_precomputed_strides",
"test_maxunpool_export_with_output_shape",
"test_maxunpool_export_without_output_shape",
"test_mul_uint8",
"test_pow_types_float32_int32", // vulkan backend does not take tensor other than float32 data type
"test_pow_types_float32_int64", // vulkan backend does not take tensor other than float32 data type
"test_pow_types_int", // vulkan backend does not take tensor other than float32 data type
"test_quantizelinear",
"test_quantizelinear_axis",
"test_quantizelinear_blocked",
"test_softmax_default_axis",
"test_sub_bcast",
"test_sub_uint8",
"test_transpose_all_permutations_0",
"test_upsample_nearest",
"test_scatter_elements_with_axis",
"test_scatter_elements_with_duplicate_indices",
"test_scatter_elements_with_negative_indices",
"test_scatter_elements_with_reduction_max",
"test_scatter_elements_with_reduction_min",
"test_scatter_elements_without_axis",
"test_scatter_with_axis",
"test_scatter_without_axis",
"test_scatternd",
"test_scatternd_add",
"test_scatternd_max",
"test_scatternd_min",
"test_scatternd_multiply",
"test_attention_3d_attn_mask",
"test_attention_3d_causal",
"test_attention_3d_diff_heads_sizes",
"test_attention_3d_diff_heads_sizes_attn_mask",
"test_attention_3d_diff_heads_sizes_causal",
"test_attention_3d_diff_heads_sizes_softcap",
"test_attention_3d_diff_heads_sizes_scaled",
"test_attention_3d_gqa",
"test_attention_3d_gqa_attn_mask",
"test_attention_3d_gqa_causal",
"test_attention_3d_gqa_scaled",
"test_attention_3d_gqa_softcap",
"test_attention_3d_scaled",
"test_attention_3d_softcap",
"test_attention_3d_transpose_verification",
"test_attention_4d",
"test_attention_4d_attn_mask",
"test_attention_4d_attn_mask_3d",
"test_attention_4d_attn_mask_3d_causal",
"test_attention_4d_attn_mask_4d",
"test_attention_4d_attn_mask_4d_causal",
"test_attention_4d_attn_mask_bool",
"test_attention_4d_attn_mask_bool_4d",
"test_attention_4d_causal",
"test_attention_4d_diff_heads_sizes",
"test_attention_4d_diff_heads_sizes_attn_mask",
"test_attention_4d_diff_heads_sizes_causal",
"test_attention_4d_diff_heads_sizes_scaled",
"test_attention_4d_diff_heads_sizes_softcap",
"test_attention_4d_gqa",
"test_attention_4d_gqa_attn_mask",
"test_attention_4d_gqa_causal",
"test_attention_4d_gqa_scaled",
"test_attention_4d_gqa_softcap",
"test_attention_4d_scaled",
"test_attention_4d_softcap"
"test_attention_4d_attn_mask_bool",
"test_attention_4d_attn_mask_bool_4d",
@@ -0,0 +1,13 @@
"test_averagepool_2d_pads_count_include_pad", // wrong output
"test_averagepool_2d_precomputed_pads_count_include_pad", // wrong output
"test_averagepool_2d_same_lower", // wrong output
"test_cast_FLOAT_to_STRING", // Unsupported type in function 'parseCast'
"test_cast_STRING_to_FLOAT", // unexception during net.forward() call
"test_castlike_FLOAT_to_STRING_expanded", // Unsupported type in function 'parseCast'
"test_castlike_STRING_to_FLOAT_expanded", // unexception during net.forward() call
"test_maxpool_2d_dilations", // output size mismatch in NORMASSERT
"test_maxpool_2d_same_lower", // wrong output
"test_maxpool_2d_uint8", // output type mismatch
"test_maxpool_with_argmax_2d_precomputed_strides", // wrong output
"test_maxunpool_export_with_output_shape", // unexception during net.forward() call
"test_upsample_nearest", // Dimension mismatch of input
@@ -0,0 +1,758 @@
"test_if",
"test_top_k", // Issue:: K being input is not compatible with the current engine
"test_top_k_negative_axis", // same as above
"test_top_k_smallest", // same as above
"test_expand_dim_changed",
"test_expand_dim_unchanged",
"test_gemm_all_attributes",
"test_gemm_alpha",
"test_gemm_beta",
"test_gemm_default_scalar_bias",
"test_gemm_default_single_elem_vector_bias",
"test_gemm_default_vector_bias",
"test_gemm_default_zero_bias",
"test_gemm_transposeA",
"test_gemm_transposeB",
"test_range_float_type_positive_delta",
"test_range_int32_type_negative_delta",
"test_reshape_extended_dims",
"test_reshape_negative_dim",
"test_reshape_negative_extended_dims",
"test_reshape_one_dim",
"test_reshape_reduced_dims",
"test_reshape_reordered_all_dims",
"test_reshape_reordered_last_dims",
"test_reshape_zero_and_negative_dim",
"test_reshape_zero_dim",
"test_shape",
"test_shape_clip_end",
"test_shape_clip_start",
"test_shape_end_1",
"test_shape_end_negative_1",
"test_shape_example",
"test_shape_start_1",
"test_shape_start_1_end_2",
"test_shape_start_1_end_negative_1",
"test_shape_start_negative_1",
"test_slice",
"test_slice_default_axes",
"test_slice_default_steps",
"test_slice_end_out_of_bounds",
"test_slice_neg",
"test_slice_neg_steps",
"test_slice_negative_axes",
"test_split_variable_parts_1d",
"test_split_variable_parts_2d",
"test_split_variable_parts_default_axis",
"test_squeeze",
"test_squeeze_negative_axes",
"test_tile",
"test_tile_precomputed",
"test_unsqueeze_axis_0",
"test_unsqueeze_axis_1",
"test_unsqueeze_axis_2",
"test_unsqueeze_negative_axes",
"test_unsqueeze_three_axes",
"test_unsqueeze_two_axes",
"test_unsqueeze_unsorted_axes",
"test_clip",
"test_clip_default_inbounds",
"test_clip_default_int8_inbounds",
"test_clip_default_int8_max",
"test_clip_default_int8_min",
"test_clip_default_max",
"test_clip_default_min",
"test_clip_example",
"test_clip_inbounds",
"test_clip_outbounds",
"test_clip_splitbounds",
"test_size",
"test_size_example",
"test_mean_example",
"test_mean_one_input",
"test_mean_two_inputs",
"test_isnan",
"test_isinf",
"test_isinf_negative",
"test_isinf_positive",
"test_tril",
"test_tril_neg",
"test_tril_one_row_neg",
"test_tril_out_neg",
"test_tril_out_pos",
"test_tril_pos",
"test_tril_square",
"test_tril_square_neg",
"test_triu",
"test_triu_neg",
"test_triu_one_row",
"test_triu_out_neg_out",
"test_triu_out_pos",
"test_triu_pos",
"test_triu_square",
"test_triu_square_neg",
"test_det_2d",
"test_det_nd",
"test_max_int16",
"test_max_uint16",
"test_max_uint32",
"test_max_uint64",
"test_min_int16",
"test_min_uint16",
"test_min_uint32",
"test_min_uint64",
"test_mod_mixed_sign_int16",
"test_mod_uint16",
"test_mod_uint32",
"test_mod_uint64",
"test_bitshift_left_uint16",
"test_bitshift_left_uint32",
"test_bitshift_left_uint64",
"test_bitshift_left_uint8",
"test_bitshift_right_uint16",
"test_bitshift_right_uint32",
"test_bitshift_right_uint64",
"test_bitshift_right_uint8",
"test_gridsample",
"test_gridsample_aligncorners_true",
"test_gridsample_bilinear",
"test_gridsample_border_padding",
"test_gridsample_reflection_padding",
"test_gridsample_zeros_padding",
"test_gridsample_nearest",
"test_edge_pad",
"test_lstm_batchwise",
"test_lstm_defaults",
"test_lstm_with_initial_bias",
"test_lstm_with_peepholes",
"test_pow_types_float",
"test_pow_types_float32_int32",
"test_pow_types_float32_int64",
"test_pow_types_float32_uint32",
"test_pow_types_float32_uint64",
"test_pow_types_int",
"test_pow_types_int32_float32",
"test_pow_types_int32_int32",
"test_pow_types_int64_float32",
"test_reflect_pad",
"test_constant",
"test_constant_pad",
"test_constantofshape_float_ones",
"test_constantofshape_int_zeros",
"test_nonzero_example",
"test_unique_not_sorted_without_axis",
"test_unique_sorted_with_axis",
"test_unique_sorted_with_axis_3d",
"test_unique_sorted_with_negative_axis",
"test_unique_sorted_without_axis",
"test_resize_downsample_scales_nearest",
"test_resize_downsample_sizes_cubic",
"test_resize_downsample_sizes_nearest",
"test_resize_upsample_scales_cubic",
"test_resize_upsample_scales_cubic_A_n0p5_exclude_outside",
"test_resize_upsample_scales_cubic_align_corners",
"test_resize_upsample_scales_cubic_asymmetric",
"test_resize_upsample_scales_linear",
"test_resize_upsample_scales_linear_align_corners",
"test_resize_upsample_scales_nearest",
"test_resize_upsample_sizes_cubic",
"test_resize_upsample_sizes_nearest",
"test_resize_upsample_sizes_nearest_ceil_half_pixel",
"test_resize_upsample_sizes_nearest_floor_align_corners",
"test_resize_upsample_sizes_nearest_round_prefer_ceil_asymmetric",
"test_resize_downsample_scales_cubic",
"test_resize_downsample_scales_cubic_A_n0p5_exclude_outside",
"test_resize_downsample_scales_linear",
"test_resize_downsample_sizes_linear_pytorch_half_pixel",
"test_resize_downsample_sizes_nearest_tf_half_pixel_for_nn",
"test_resize_tf_crop_and_resize",
"test_nonmaxsuppression_center_point_box_format",
"test_nonmaxsuppression_flipped_coordinates",
"test_nonmaxsuppression_identical_boxes",
"test_nonmaxsuppression_limit_output_size",
"test_nonmaxsuppression_single_box",
"test_nonmaxsuppression_suppress_by_IOU",
"test_nonmaxsuppression_suppress_by_IOU_and_scores",
"test_nonmaxsuppression_two_batches",
"test_nonmaxsuppression_two_classes",
"test_add_int16",
"test_add_int8",
"test_add_uint16",
"test_add_uint32",
"test_add_uint64",
"test_clip_default_inbounds_expanded",
"test_clip_default_int8_inbounds_expanded",
"test_clip_default_int8_max_expanded",
"test_clip_default_int8_min_expanded",
"test_clip_default_max_expanded",
"test_clip_default_min_expanded",
"test_clip_inbounds_expanded",
"test_clip_splitbounds_expanded",
"test_equal_int16",
"test_equal_int8",
"test_equal_uint16",
"test_equal_uint32",
"test_equal_uint64",
"test_equal_uint8",
"test_isinf_float16",
"test_isnan_float16",
"test_logsoftmax_axis_0_expanded_ver18",
"test_logsoftmax_axis_1_expanded_ver18",
"test_logsoftmax_axis_2_expanded_ver18",
"test_logsoftmax_default_axis_expanded_ver18",
"test_logsoftmax_example_1_expanded_ver18",
"test_logsoftmax_large_number_expanded_ver18",
"test_logsoftmax_negative_axis_expanded_ver18",
"test_mul_int16",
"test_mul_int8",
"test_mul_uint16",
"test_mul_uint32",
"test_mul_uint64",
"test_softmax_axis_0_expanded_ver18",
"test_softmax_axis_1_expanded_ver18",
"test_softmax_axis_2_expanded_ver18",
"test_softmax_default_axis_expanded_ver18",
"test_softmax_example_expanded_ver18",
"test_softmax_large_number_expanded_ver18",
"test_softmax_negative_axis_expanded_ver18",
"test_swish",
"test_greater_equal_int16",
"test_greater_equal_int16_expanded",
"test_greater_equal_int8",
"test_greater_equal_int8_expanded",
"test_greater_equal_uint16",
"test_greater_equal_uint16_expanded",
"test_greater_equal_uint32",
"test_greater_equal_uint32_expanded",
"test_greater_equal_uint64",
"test_greater_equal_uint64_expanded",
"test_greater_equal_uint8",
"test_greater_equal_uint8_expanded",
"test_greater_int16",
"test_greater_int8",
"test_greater_uint16",
"test_greater_uint32",
"test_greater_uint64",
"test_greater_uint8",
"test_less_equal_int16",
"test_less_equal_int16_expanded",
"test_less_equal_int8",
"test_less_equal_int8_expanded",
"test_less_equal_uint16",
"test_less_equal_uint16_expanded",
"test_less_equal_uint32",
"test_less_equal_uint32_expanded",
"test_less_equal_uint64",
"test_less_equal_uint64_expanded",
"test_less_equal_uint8",
"test_less_equal_uint8_expanded",
"test_less_int16",
"test_less_int8",
"test_less_uint16",
"test_less_uint32",
"test_less_uint64",
"test_less_uint8",
"test_lpnormalization_default",
"test_resize_upsample_scales_nearest_axes_2_3",
"test_resize_upsample_sizes_nearest_axes_2_3",
"test_split_equal_parts_2d_opset13",
"test_split_variable_parts_1d_opset13",
"test_split_variable_parts_1d_opset18",
"test_split_variable_parts_2d_opset13",
"test_split_variable_parts_2d_opset18",
"test_split_variable_parts_default_axis_opset13",
"test_split_variable_parts_default_axis_opset18",
"test_sub_int16",
"test_sub_int8",
"test_sub_uint16",
"test_sub_uint32",
"test_sub_uint64",
"test_top_k_same_values", //type mismatch
"test_top_k_same_values_2d",
"test_top_k_same_values_largest",
"test_top_k_uint64",
"test_training_dropout_zero_ratio", // ---- same as above ---
"test_wrap_pad", // type mismatch
"test_div_int16",
"test_div_uint8",
"test_div_int8",
"test_div_uint16",
"test_div_uint32",
"test_div_uint64",
"test_cumsum_1d_int32_exclusive",
"test_cumsum_2d_int32",
"test_cast_BFLOAT16_to_FLOAT",
"test_cast_DOUBLE_to_FLOAT16",
"test_cast_FLOAT16_to_DOUBLE",
"test_cast_FLOAT16_to_FLOAT",
"test_cast_FLOAT_to_BFLOAT16",
"test_cast_FLOAT_to_DOUBLE",
"test_cast_FLOAT_to_FLOAT16",
"test_castlike_BFLOAT16_to_FLOAT",
"test_castlike_BFLOAT16_to_FLOAT_expanded",
"test_castlike_DOUBLE_to_FLOAT",
"test_castlike_DOUBLE_to_FLOAT16",
"test_castlike_DOUBLE_to_FLOAT16_expanded",
"test_castlike_DOUBLE_to_FLOAT_expanded",
"test_castlike_FLOAT16_to_DOUBLE",
"test_castlike_FLOAT16_to_DOUBLE_expanded",
"test_castlike_FLOAT16_to_FLOAT",
"test_castlike_FLOAT16_to_FLOAT_expanded",
"test_castlike_FLOAT_to_BFLOAT16",
"test_castlike_FLOAT_to_BFLOAT16_expanded",
"test_castlike_FLOAT_to_DOUBLE",
"test_castlike_FLOAT_to_DOUBLE_expanded",
"test_castlike_FLOAT_to_FLOAT16",
"test_castlike_FLOAT_to_FLOAT16_expanded",
"test_gelu_default_1_expanded",
"test_gelu_default_2_expanded",
"test_gelu_tanh_1_expanded",
"test_gelu_tanh_2_expanded",
"test_bitwise_and_i16_3d",
"test_bitwise_and_i32_2d",
"test_bitwise_and_ui64_bcast_3v1d",
"test_bitwise_and_ui8_bcast_4v3d",
"test_bitwise_not_2d",
"test_bitwise_not_3d",
"test_bitwise_not_4d",
"test_bitwise_or_i16_4d",
"test_bitwise_or_i32_2d",
"test_bitwise_or_ui64_bcast_3v1d",
"test_bitwise_or_ui8_bcast_4v3d",
"test_bitwise_xor_i16_3d",
"test_bitwise_xor_i32_2d",
"test_bitwise_xor_ui64_bcast_3v1d",
"test_bitwise_xor_ui8_bcast_4v3d",
"test_reduce_sum_default_axes_keepdims_example",
"test_reduce_sum_do_not_keepdims_example",
"test_reduce_sum_do_not_keepdims_random",
"test_reduce_sum_empty_axes_input_noop_example",
"test_reduce_sum_empty_axes_input_noop_random",
"test_reduce_sum_keepdims_example",
"test_reduce_sum_keepdims_random",
"test_reduce_sum_negative_axes_keepdims_example",
"test_reduce_sum_negative_axes_keepdims_random",
"test_reduce_sum_default_axes_keepdims_random",
"test_reduce_l1_default_axes_keepdims_example_expanded",
"test_reduce_l1_default_axes_keepdims_random_expanded",
"test_reduce_l1_do_not_keepdims_example_expanded",
"test_reduce_l1_do_not_keepdims_random_expanded",
"test_reduce_l1_keep_dims_example_expanded",
"test_reduce_l1_keep_dims_random_expanded",
"test_reduce_l1_negative_axes_keep_dims_example_expanded",
"test_reduce_l1_negative_axes_keep_dims_random_expanded",
"test_reduce_log_sum_asc_axes_expanded",
"test_reduce_log_sum_default_expanded",
"test_reduce_log_sum_desc_axes_expanded",
"test_reduce_log_sum_negative_axes_expanded",
"test_reduce_max_bool_inputs",
"test_reduce_min_bool_inputs",
"test_reduce_sum_square_default_axes_keepdims_example_expanded",
"test_reduce_sum_square_default_axes_keepdims_random_expanded",
"test_reduce_sum_square_do_not_keepdims_example_expanded",
"test_reduce_sum_square_do_not_keepdims_random_expanded",
"test_reduce_sum_square_keepdims_example_expanded",
"test_reduce_sum_square_keepdims_random_expanded",
"test_reduce_sum_square_negative_axes_keepdims_example_expanded",
"test_reduce_sum_square_negative_axes_keepdims_random_expanded",
"test_reduce_sum_empty_axes_input_noop",
"test_reduce_l1_default_axes_keepdims_example",
"test_reduce_l1_default_axes_keepdims_random",
"test_reduce_l1_do_not_keepdims_example",
"test_reduce_l1_do_not_keepdims_random",
"test_reduce_l1_keep_dims_example",
"test_reduce_l1_keep_dims_random",
"test_reduce_l1_negative_axes_keep_dims_example",
"test_reduce_l1_negative_axes_keep_dims_random",
"test_reduce_l2_default_axes_keepdims_example",
"test_reduce_l2_default_axes_keepdims_example_expanded",
"test_reduce_l2_default_axes_keepdims_random",
"test_reduce_l2_default_axes_keepdims_random_expanded",
"test_reduce_l2_do_not_keepdims_example",
"test_reduce_l2_do_not_keepdims_example_expanded",
"test_reduce_l2_do_not_keepdims_random",
"test_reduce_l2_do_not_keepdims_random_expanded",
"test_reduce_l2_keep_dims_example",
"test_reduce_l2_keep_dims_example_expanded",
"test_reduce_l2_keep_dims_random",
"test_reduce_l2_keep_dims_random_expanded",
"test_reduce_l2_negative_axes_keep_dims_example",
"test_reduce_l2_negative_axes_keep_dims_example_expanded",
"test_reduce_l2_negative_axes_keep_dims_random",
"test_reduce_l2_negative_axes_keep_dims_random_expanded",
"test_reduce_log_sum_asc_axes",
"test_reduce_log_sum_default",
"test_reduce_log_sum_desc_axes",
"test_reduce_log_sum_exp_default_axes_keepdims_example",
"test_reduce_log_sum_exp_default_axes_keepdims_example_expanded",
"test_reduce_log_sum_exp_default_axes_keepdims_random",
"test_reduce_log_sum_exp_default_axes_keepdims_random_expanded",
"test_reduce_log_sum_exp_do_not_keepdims_example",
"test_reduce_log_sum_exp_do_not_keepdims_example_expanded",
"test_reduce_log_sum_exp_do_not_keepdims_random",
"test_reduce_log_sum_exp_do_not_keepdims_random_expanded",
"test_reduce_log_sum_exp_keepdims_example",
"test_reduce_log_sum_exp_keepdims_example_expanded",
"test_reduce_log_sum_exp_keepdims_random",
"test_reduce_log_sum_exp_keepdims_random_expanded",
"test_reduce_log_sum_exp_negative_axes_keepdims_example",
"test_reduce_log_sum_exp_negative_axes_keepdims_example_expanded",
"test_reduce_log_sum_exp_negative_axes_keepdims_random",
"test_reduce_log_sum_exp_negative_axes_keepdims_random_expanded",
"test_reduce_log_sum_negative_axes",
"test_reduce_max_do_not_keepdims_example",
"test_reduce_max_do_not_keepdims_random",
"test_reduce_max_keepdims_example",
"test_reduce_max_keepdims_random",
"test_reduce_max_negative_axes_keepdims_example",
"test_reduce_max_negative_axes_keepdims_random",
"test_reduce_mean_default_axes_keepdims_example",
"test_reduce_mean_default_axes_keepdims_random",
"test_reduce_mean_do_not_keepdims_example",
"test_reduce_mean_do_not_keepdims_random",
"test_reduce_mean_keepdims_example",
"test_reduce_mean_keepdims_random",
"test_reduce_mean_negative_axes_keepdims_example",
"test_reduce_mean_negative_axes_keepdims_random",
"test_reduce_min_do_not_keepdims_example",
"test_reduce_min_do_not_keepdims_random",
"test_reduce_min_keepdims_example",
"test_reduce_min_keepdims_random",
"test_reduce_min_negative_axes_keepdims_example",
"test_reduce_min_negative_axes_keepdims_random",
"test_reduce_prod_do_not_keepdims_example",
"test_reduce_prod_do_not_keepdims_random",
"test_reduce_prod_keepdims_example",
"test_reduce_prod_keepdims_random",
"test_reduce_prod_negative_axes_keepdims_example",
"test_reduce_prod_negative_axes_keepdims_random",
"test_reduce_sum_square_default_axes_keepdims_example",
"test_reduce_sum_square_default_axes_keepdims_random",
"test_reduce_sum_square_do_not_keepdims_example",
"test_reduce_sum_square_do_not_keepdims_random",
"test_reduce_sum_square_keepdims_example",
"test_reduce_sum_square_keepdims_random",
"test_reduce_sum_square_negative_axes_keepdims_example",
"test_reduce_sum_square_negative_axes_keepdims_random",
"test_elu_default_expanded_ver18",
"test_elu_example_expanded_ver18",
"test_elu_expanded_ver18",
"test_thresholdedrelu_default_expanded_ver18",
"test_thresholdedrelu_example_expanded_ver18",
"test_thresholdedrelu_expanded_ver18",
"test_selu_default_expanded_ver18",
"test_selu_example_expanded_ver18",
"test_selu_expanded_ver18",
"test_hardsigmoid_default_expanded_ver18",
"test_hardsigmoid_example_expanded_ver18",
"test_hardsigmoid_expanded_ver18",
"test_softplus_example_expanded_ver18",
"test_softplus_expanded_ver18",
"test_softsign_example_expanded_ver18",
"test_softsign_expanded_ver18",
"test_shrink_hard_expanded_ver18",
"test_shrink_soft_expanded_ver18",
"test_relu_expanded_ver18",
"test_prelu_broadcast_expanded",
"test_prelu_example_expanded",
"test_leakyrelu_default_expanded",
"test_leakyrelu_example_expanded",
"test_leakyrelu_expanded",
"test_sce_NCd1_mean_weight_negative_ii",
"test_sce_NCd1_mean_weight_negative_ii_expanded",
"test_sce_NCd1_mean_weight_negative_ii_log_prob",
"test_sce_NCd1_mean_weight_negative_ii_log_prob_expanded",
"test_sce_NCd1d2d3_none_no_weight_negative_ii",
"test_sce_NCd1d2d3_none_no_weight_negative_ii_expanded",
"test_sce_NCd1d2d3_none_no_weight_negative_ii_log_prob",
"test_sce_NCd1d2d3_none_no_weight_negative_ii_log_prob_expanded",
"test_sce_NCd1d2d3_sum_weight_high_ii",
"test_sce_NCd1d2d3_sum_weight_high_ii_expanded",
"test_sce_NCd1d2d3_sum_weight_high_ii_log_prob",
"test_sce_NCd1d2d3_sum_weight_high_ii_log_prob_expanded",
"test_sce_NCd1d2d3d4d5_mean_weight",
"test_sce_NCd1d2d3d4d5_mean_weight_expanded",
"test_sce_NCd1d2d3d4d5_mean_weight_log_prob",
"test_sce_NCd1d2d3d4d5_mean_weight_log_prob_expanded",
"test_sce_NCd1d2d3d4d5_none_no_weight",
"test_sce_NCd1d2d3d4d5_none_no_weight_expanded",
"test_sce_NCd1d2d3d4d5_none_no_weight_log_prob",
"test_sce_NCd1d2d3d4d5_none_no_weight_log_prob_expanded",
"test_sce_mean",
"test_sce_mean_3d",
"test_sce_mean_3d_expanded",
"test_sce_mean_3d_log_prob",
"test_sce_mean_3d_log_prob_expanded",
"test_sce_mean_expanded",
"test_sce_mean_log_prob",
"test_sce_mean_log_prob_expanded",
"test_sce_mean_no_weight_ii",
"test_sce_mean_no_weight_ii_3d",
"test_sce_mean_no_weight_ii_3d_expanded",
"test_sce_mean_no_weight_ii_3d_log_prob",
"test_sce_mean_no_weight_ii_3d_log_prob_expanded",
"test_sce_mean_no_weight_ii_4d",
"test_sce_mean_no_weight_ii_4d_expanded",
"test_sce_mean_no_weight_ii_4d_log_prob",
"test_sce_mean_no_weight_ii_4d_log_prob_expanded",
"test_sce_mean_no_weight_ii_expanded",
"test_sce_mean_no_weight_ii_log_prob",
"test_sce_mean_no_weight_ii_log_prob_expanded",
"test_sce_mean_weight",
"test_sce_mean_weight_expanded",
"test_sce_mean_weight_ii",
"test_sce_mean_weight_ii_3d",
"test_sce_mean_weight_ii_3d_expanded",
"test_sce_mean_weight_ii_3d_log_prob",
"test_sce_mean_weight_ii_3d_log_prob_expanded",
"test_sce_mean_weight_ii_4d",
"test_sce_mean_weight_ii_4d_expanded",
"test_sce_mean_weight_ii_4d_log_prob",
"test_sce_mean_weight_ii_4d_log_prob_expanded",
"test_sce_mean_weight_ii_expanded",
"test_sce_mean_weight_ii_log_prob",
"test_sce_mean_weight_ii_log_prob_expanded",
"test_sce_mean_weight_log_prob",
"test_sce_mean_weight_log_prob_expanded",
"test_sce_none",
"test_sce_none_expanded",
"test_sce_none_log_prob",
"test_sce_none_log_prob_expanded",
"test_sce_none_weights",
"test_sce_none_weights_expanded",
"test_sce_none_weights_log_prob",
"test_sce_none_weights_log_prob_expanded",
"test_sce_sum",
"test_sce_sum_expanded",
"test_sce_sum_log_prob",
"test_sce_sum_log_prob_expanded",
"test_nllloss_NC",
"test_nllloss_NCd1",
"test_nllloss_NCd1_ii",
"test_nllloss_NCd1_ii_expanded",
"test_nllloss_NCd1_mean_weight_negative_ii",
"test_nllloss_NCd1_mean_weight_negative_ii_expanded",
"test_nllloss_NCd1_weight",
"test_nllloss_NCd1_weight_ii",
"test_nllloss_NCd1_weight_ii_expanded",
"test_nllloss_NCd1d2",
"test_nllloss_NCd1d2_no_weight_reduction_mean_ii",
"test_nllloss_NCd1d2_no_weight_reduction_mean_ii_expanded",
"test_nllloss_NCd1d2_reduction_mean",
"test_nllloss_NCd1d2_reduction_mean_expanded",
"test_nllloss_NCd1d2_reduction_sum",
"test_nllloss_NCd1d2_with_weight",
"test_nllloss_NCd1d2_with_weight_reduction_mean",
"test_nllloss_NCd1d2_with_weight_reduction_sum",
"test_nllloss_NCd1d2_with_weight_reduction_sum_expanded",
"test_nllloss_NCd1d2_with_weight_reduction_sum_ii",
"test_nllloss_NCd1d2_with_weight_reduction_sum_ii_expanded",
"test_nllloss_NCd1d2d3_none_no_weight_negative_ii",
"test_nllloss_NCd1d2d3_none_no_weight_negative_ii_expanded",
"test_nllloss_NCd1d2d3_sum_weight_high_ii",
"test_nllloss_NCd1d2d3_sum_weight_high_ii_expanded",
"test_nllloss_NCd1d2d3d4d5_mean_weight",
"test_nllloss_NCd1d2d3d4d5_none_no_weight",
"test_center_crop_pad_crop",
"test_center_crop_pad_crop_and_pad",
"test_center_crop_pad_crop_and_pad_expanded",
"test_center_crop_pad_crop_axes_chw",
"test_center_crop_pad_crop_axes_chw_expanded",
"test_center_crop_pad_crop_axes_hwc",
"test_center_crop_pad_crop_axes_hwc_expanded",
"test_center_crop_pad_crop_expanded",
"test_center_crop_pad_crop_negative_axes_hwc",
"test_center_crop_pad_crop_negative_axes_hwc_expanded",
"test_center_crop_pad_pad",
"test_center_crop_pad_pad_expanded",
"test_gridsample_bilinear_align_corners_0_additional_1",
"test_gridsample_bilinear_align_corners_1_additional_1",
"test_gridsample_nearest_align_corners_0_additional_1",
"test_gridsample_nearest_align_corners_1_additional_1",
"test_gridsample_volumetric_bilinear_align_corners_0",
"test_gridsample_volumetric_bilinear_align_corners_1",
"test_gridsample_volumetric_nearest_align_corners_0",
"test_gridsample_volumetric_nearest_align_corners_1",
"test_onehot_negative_indices",
"test_onehot_with_axis",
"test_onehot_with_negative_axis",
"test_onehot_without_axis",
"test_dft",
"test_dft_axis_opset19",
"test_dft_inverse",
"test_dft_inverse_opset19",
"test_dft_opset19",
"test_affine_grid_3d",
"test_affine_grid_3d_align_corners",
"test_affine_grid_2d",
"test_affine_grid_2d_align_corners",
"test_rotary_embedding", //type mismatch
"test_rotary_embedding_3d_input",
"test_rotary_embedding_3d_input_expanded",
"test_rotary_embedding_expanded",
"test_rotary_embedding_interleaved",
"test_rotary_embedding_interleaved_expanded",
"test_rotary_embedding_no_position_ids",
"test_rotary_embedding_no_position_ids_expanded",
"test_rotary_embedding_no_position_ids_interleaved",
"test_rotary_embedding_no_position_ids_interleaved_expanded",
"test_rotary_embedding_no_position_ids_rotary_dim",
"test_rotary_embedding_no_position_ids_rotary_dim_expanded",
"test_rotary_embedding_with_interleaved_rotary_dim",
"test_rotary_embedding_with_interleaved_rotary_dim_expanded",
"test_rotary_embedding_with_rotary_dim",
"test_rotary_embedding_with_rotary_dim_expanded",
"test_attention_3d",
"test_attention_3d_attn_mask",
"test_attention_3d_causal",
"test_attention_3d_diff_heads_sizes",
"test_attention_3d_diff_heads_sizes_attn_mask",
"test_attention_3d_diff_heads_sizes_causal",
"test_attention_3d_diff_heads_sizes_softcap",
"test_attention_3d_diff_heads_sizes_scaled",
"test_attention_3d_gqa",
"test_attention_3d_gqa_attn_mask",
"test_attention_3d_gqa_causal",
"test_attention_3d_gqa_scaled",
"test_attention_3d_gqa_softcap",
"test_attention_3d_scaled",
"test_attention_3d_softcap",
"test_attention_3d_transpose_verification",
"test_attention_4d",
"test_attention_4d_attn_mask",
"test_attention_4d_attn_mask_3d",
"test_attention_4d_attn_mask_3d_causal",
"test_attention_4d_attn_mask_4d",
"test_attention_4d_attn_mask_4d_causal",
"test_attention_4d_attn_mask_bool",
"test_attention_4d_attn_mask_bool_4d",
"test_attention_4d_causal",
"test_attention_4d_diff_heads_sizes",
"test_attention_4d_diff_heads_sizes_attn_mask",
"test_attention_4d_diff_heads_sizes_causal",
"test_attention_4d_diff_heads_sizes_scaled",
"test_attention_4d_diff_heads_sizes_softcap",
"test_attention_4d_gqa",
"test_attention_4d_gqa_attn_mask",
"test_attention_4d_gqa_causal",
"test_attention_4d_gqa_scaled",
"test_attention_4d_gqa_softcap",
"test_attention_4d_scaled",
"test_attention_4d_softcap",
"test_attention_4d_attn_mask_bool",
"test_attention_4d_attn_mask_bool_4d",
"test_rotary_embedding_with_rotary_dim_expanded",
"test_hammingwindow",
"test_hammingwindow_expanded",
"test_hammingwindow_symmetric",
"test_hammingwindow_symmetric_expanded",
"test_hannwindow",
"test_hannwindow_expanded",
"test_hannwindow_symmetric",
"test_hannwindow_symmetric_expanded",
"test_blackmanwindow",
"test_blackmanwindow_expanded",
"test_blackmanwindow_symmetric",
"test_blackmanwindow_symmetric_expanded",
"test_layer_normalization_2d_axis0",
"test_layer_normalization_2d_axis0_expanded",
"test_layer_normalization_2d_axis0_expanded_ver18",
"test_layer_normalization_2d_axis1",
"test_layer_normalization_2d_axis1_expanded",
"test_layer_normalization_2d_axis1_expanded_ver18",
"test_layer_normalization_2d_axis_negative_1",
"test_layer_normalization_2d_axis_negative_1_expanded",
"test_layer_normalization_2d_axis_negative_1_expanded_ver18",
"test_layer_normalization_2d_axis_negative_2",
"test_layer_normalization_2d_axis_negative_2_expanded",
"test_layer_normalization_2d_axis_negative_2_expanded_ver18",
"test_layer_normalization_3d_axis0_epsilon",
"test_layer_normalization_3d_axis0_epsilon_expanded",
"test_layer_normalization_3d_axis0_epsilon_expanded_ver18",
"test_layer_normalization_3d_axis1_epsilon",
"test_layer_normalization_3d_axis1_epsilon_expanded",
"test_layer_normalization_3d_axis1_epsilon_expanded_ver18",
"test_layer_normalization_3d_axis2_epsilon",
"test_layer_normalization_3d_axis2_epsilon_expanded",
"test_layer_normalization_3d_axis2_epsilon_expanded_ver18",
"test_layer_normalization_3d_axis_negative_1_epsilon",
"test_layer_normalization_3d_axis_negative_1_epsilon_expanded",
"test_layer_normalization_3d_axis_negative_1_epsilon_expanded_ver18",
"test_layer_normalization_3d_axis_negative_2_epsilon",
"test_layer_normalization_3d_axis_negative_2_epsilon_expanded",
"test_layer_normalization_3d_axis_negative_2_epsilon_expanded_ver18",
"test_layer_normalization_3d_axis_negative_3_epsilon",
"test_layer_normalization_3d_axis_negative_3_epsilon_expanded",
"test_layer_normalization_3d_axis_negative_3_epsilon_expanded_ver18",
"test_layer_normalization_4d_axis0",
"test_layer_normalization_4d_axis0_expanded",
"test_layer_normalization_4d_axis0_expanded_ver18",
"test_layer_normalization_4d_axis1",
"test_layer_normalization_4d_axis1_expanded",
"test_layer_normalization_4d_axis1_expanded_ver18",
"test_layer_normalization_4d_axis2",
"test_layer_normalization_4d_axis2_expanded",
"test_layer_normalization_4d_axis2_expanded_ver18",
"test_layer_normalization_4d_axis3",
"test_layer_normalization_4d_axis3_expanded",
"test_layer_normalization_4d_axis3_expanded_ver18",
"test_layer_normalization_4d_axis_negative_1",
"test_layer_normalization_4d_axis_negative_1_expanded",
"test_layer_normalization_4d_axis_negative_1_expanded_ver18",
"test_layer_normalization_4d_axis_negative_2",
"test_layer_normalization_4d_axis_negative_2_expanded",
"test_layer_normalization_4d_axis_negative_2_expanded_ver18",
"test_layer_normalization_4d_axis_negative_3",
"test_layer_normalization_4d_axis_negative_3_expanded",
"test_layer_normalization_4d_axis_negative_3_expanded_ver18",
"test_layer_normalization_4d_axis_negative_4",
"test_layer_normalization_4d_axis_negative_4_expanded",
"test_layer_normalization_4d_axis_negative_4_expanded_ver18",
"test_layer_normalization_default_axis",
"test_layer_normalization_default_axis_expanded",
"test_layer_normalization_default_axis_expanded_ver18",
"test_roialign_aligned_false",
"test_roialign_aligned_true",
"test_roialign_mode_max",
"test_batchnorm_example",
"test_batchnorm_epsilon",
"test_gru_batchwise",
"test_gru_defaults",
"test_gru_seq_length",
"test_gru_with_initial_bias",
"test_reduce_l1_empty_set",
"test_reduce_l1_empty_set_expanded",
"test_reduce_l2_empty_set",
"test_reduce_l2_empty_set_expanded",
"test_reduce_log_sum_empty_set",
"test_reduce_log_sum_empty_set_expanded",
"test_reduce_log_sum_exp_empty_set",
"test_reduce_max_empty_set",
"test_reduce_min_empty_set",
"test_reduce_prod_empty_set",
"test_reduce_sum_empty_set",
"test_reduce_sum_empty_set_non_reduced_axis_zero",
"test_reduce_sum_square_empty_set",
"test_reduce_sum_square_empty_set_expanded",
"test_reduce_log_sum_exp_empty_set_expanded",
"test_loop11",
"test_eyelike_populate_off_main_diagonal",
"test_eyelike_with_dtype",
"test_eyelike_without_dtype",
"test_qlinearconv",
"test_qlinearmatmul_2D",
"test_qlinearmatmul_3D",
"test_convtranspose",
"test_convtranspose_1d",
"test_convtranspose_3d",
"test_convtranspose_dilations",
"test_convtranspose_group_2",
"test_convtranspose_group_2_image_3",
"test_convtranspose_kernel_shape",
"test_convtranspose_output_shape",
"test_convtranspose_pad",
"test_convtranspose_pads",
"test_convtranspose_with_kernel",
"test_maxpool_3d_dilations",
"test_maxpool_3d_dilations_use_ref_impl",
"test_maxpool_3d_dilations_use_ref_impl_large",
@@ -0,0 +1,23 @@
"test_averagepool_3d_default",
"test_dequantizelinear",
"test_dequantizelinear_axis",
"test_dequantizelinear_blocked",
"test_logsoftmax_large_number",
"test_logsoftmax_large_number_expanded",
"test_maxpool_3d_default",
"test_pow",
"test_quantizelinear",
"test_quantizelinear_axis",
"test_quantizelinear_blocked",
"test_softmax_large_number",
"test_softmax_large_number_expanded",
"test_tan",
"test_reduce_prod_default_axes_keepdims_example", // Expected: (normL1) <= (l1), actual: inf vs 0.004
"test_reduce_prod_default_axes_keepdims_random", // Expected: (normL1) <= (l1), actual: 18.6621 vs 0.004, Expected: (normInf) <= (lInf), actual: 18.6621 vs 0.02
"test_reduce_prod_do_not_keepdims_random", // Expected: (normL1) <= (l1), actual: 0.00436729 vs 0.004, Expected: (normInf) <= (lInf), actual: 0.0201836 vs 0.02
"test_reduce_prod_keepdims_random", // Expected: (normL1) <= (l1), actual: 0.00436729 vs 0.004, Expected: (normInf) <= (lInf), actual: 0.0201836 vs 0.02
"test_reduce_prod_negative_axes_keepdims_random", // Expected: (normL1) <= (l1), actual: 0.00436729 vs 0.004, Expected: (normInf) <= (lInf), actual: 0.0201836 vs 0.02
"test_reduce_sum_square_default_axes_keepdims_random", // Expected: (normL1) <= (l1), actual: 0.0183411 vs 0.004
"test_reduce_sum_square_do_not_keepdims_random", // Expected: (normL1) <= (l1), actual: 0.010789 vs 0.004, Expected: (normInf) <= (lInf), actual: 0.0290298 vs 0.02
"test_reduce_sum_square_keepdims_random", // Expected: (normL1) <= (l1), actual: 0.010789 vs 0.004, Expected: (normInf) <= (lInf), actual: 0.0290298 vs 0.02
"test_reduce_sum_square_negative_axes_keepdims_random", // Expected: (normL1) <= (l1), actual: 0.010789 vs 0.004, Expected: (normInf) <= (lInf), actual: 0.0290298 vs 0.02
@@ -0,0 +1,8 @@
"test_averagepool_3d_default",
"test_dequantizelinear",
"test_dequantizelinear_axis",
"test_dequantizelinear_blocked",
"test_maxpool_3d_default",
"test_quantizelinear",
"test_quantizelinear_axis",
"test_quantizelinear_blocked",
@@ -0,0 +1,489 @@
// The file is autogenerated
// Update note: execute <opencv_extra>/testdata/dnn/onnx/generate_conformance_list.py <gtest_xml_file>
"test_adagrad", // Issues::Layer::Can't create layer "onnx_node_output_0!X1_new" of type "ai.onnx.preview.training.Adagrad" in function 'getLayerInstance'
"test_adagrad_multiple", // ---- same as above ---
"test_adam", // Issues::Layer::Can't create layer "onnx_node_output_0!X1_new" of type "ai.onnx.preview.training.Adam" in function 'getLayerInstance'
"test_adam_multiple", // ---- same as above ---
"test_affine_grid_2d_align_corners_expanded",
"test_affine_grid_2d_expanded",
"test_affine_grid_3d_align_corners_expanded",
"test_affine_grid_3d_expanded",
"test_ai_onnx_ml_array_feature_extractor",
"test_ai_onnx_ml_binarizer",
"test_ai_onnx_ml_label_encoder_string_int",
"test_ai_onnx_ml_label_encoder_string_int_no_default",
"test_ai_onnx_ml_label_encoder_tensor_mapping",
"test_ai_onnx_ml_label_encoder_tensor_value_only_mapping",
"test_ai_onnx_ml_tree_ensemble_set_membership",
"test_ai_onnx_ml_tree_ensemble_single_tree",
// autoSize <= INT_MAX && autoSize*outTotal == inpTotal in function 'getOutShape' @ C++ exception with description
//"OpenCV(5.0.0-pre) opencv/modules/dnn/src/layers/reshape2_layer.cpp:110
// expanded graphs are not imported correctly
"test_attention_3d_expanded",
"test_attention_3d_attn_mask_expanded",
"test_attention_3d_diff_heads_sizes_attn_mask_expanded",
"test_attention_3d_scaled_expanded",
"test_attention_3d_gqa_attn_mask_expanded",
"test_attention_3d_diff_heads_sizes_expanded",
"test_attention_3d_transpose_verification_expanded",
"test_attention_3d_softcap_expanded",
"test_attention_3d_gqa_scaled_expanded",
"test_attention_3d_with_past_and_present_qk_matmul_softmax_expanded",
"test_attention_3d_with_past_and_present_qk_matmul_softcap_expanded",
"test_attention_3d_with_past_and_present_qk_matmul_bias_expanded",
"test_attention_3d_with_past_and_present_qk_matmul_expanded",
"test_attention_3d_with_past_and_present_expanded",
"test_attention_3d_gqa_with_past_and_present_expanded",
"test_attention_3d_causal_expanded",
"test_attention_3d_diff_heads_sizes_causal_expanded",
"test_attention_3d_diff_heads_sizes_scaled_expanded",
"test_attention_3d_diff_heads_sizes_softcap",
"test_attention_3d_diff_heads_sizes_softcap_expanded",
"test_attention_3d_diff_heads_with_past_and_present",
"test_attention_3d_diff_heads_with_past_and_present_expanded",
"test_attention_3d_gqa_causal_expanded",
"test_attention_3d_gqa_expanded",
"test_attention_3d_gqa_softcap_expanded",
"test_attention_4d_attn_mask_3d_causal_expanded",
"test_attention_4d_attn_mask_3d_expanded",
"test_attention_4d_causal_expanded",
"test_attention_4d_diff_heads_sizes_attn_mask_expanded",
"test_attention_4d_diff_heads_mask4d_padded_kv_expanded",
"test_attention_4d_attn_mask_4d_causal_expanded",
"test_attention_4d_attn_mask_4d_expanded",
"test_attention_4d_attn_mask_bool_4d_expanded",
"test_attention_4d_attn_mask_bool_expanded",
"test_attention_4d_attn_mask_expanded",
"test_attention_4d_diff_heads_sizes_causal_expanded",
"test_attention_4d_diff_heads_sizes_expanded",
"test_attention_4d_diff_heads_sizes_scaled_expanded",
"test_attention_4d_diff_heads_sizes_softcap_expanded",
"test_attention_4d_expanded",
"test_attention_3d_gqa_with_past_and_present",
"test_attention_3d_with_past_and_present",
"test_attention_3d_with_past_and_present_qk_matmul",
"test_attention_3d_with_past_and_present_qk_matmul_bias",
"test_attention_3d_with_past_and_present_qk_matmul_softcap",
"test_attention_3d_with_past_and_present_qk_matmul_softmax",
"test_attention_4d_diff_heads_mask4d_padded_kv",
"test_attention_4d_diff_heads_with_past_and_present",
"test_attention_4d_diff_heads_with_past_and_present_expanded",
"test_attention_4d_diff_heads_with_past_and_present_mask3d",
"test_attention_4d_diff_heads_with_past_and_present_mask3d_expanded",
"test_attention_4d_diff_heads_with_past_and_present_mask4d",
"test_attention_4d_diff_heads_with_past_and_present_mask4d_expanded",
"test_attention_4d_fp16_expanded",
"test_attention_4d_gqa_attn_mask_expanded",
"test_attention_4d_gqa_causal_expanded",
"test_attention_4d_gqa_expanded",
"test_attention_4d_gqa_scaled_expanded",
"test_attention_4d_gqa_softcap_expanded",
// fixme
"test_attention_4d_fp16",
"test_attention_4d_gqa_with_past_and_present",
"test_attention_4d_gqa_with_past_and_present_expanded",
"test_attention_4d_gqa_with_past_and_present_fp16",
"test_attention_4d_gqa_with_past_and_present_fp16_expanded",
"test_attention_4d_scaled_expanded",
"test_attention_4d_softcap_expanded",
"test_attention_4d_with_past_and_present",
"test_attention_4d_with_past_and_present_expanded",
"test_attention_4d_with_past_and_present_qk_matmul",
"test_attention_4d_with_past_and_present_qk_matmul_bias",
"test_attention_4d_with_past_and_present_qk_matmul_bias_3d_mask",
"test_attention_4d_with_past_and_present_qk_matmul_bias_3d_mask_causal",
"test_attention_4d_with_past_and_present_qk_matmul_bias_3d_mask_causal_expanded",
"test_attention_4d_with_past_and_present_qk_matmul_bias_3d_mask_expanded",
"test_attention_4d_with_past_and_present_qk_matmul_bias_4d_mask",
"test_attention_4d_with_past_and_present_qk_matmul_bias_4d_mask_causal",
"test_attention_4d_with_past_and_present_qk_matmul_bias_4d_mask_causal_expanded",
"test_attention_4d_with_past_and_present_qk_matmul_bias_4d_mask_expanded",
"test_attention_4d_with_past_and_present_qk_matmul_bias_expanded",
"test_attention_4d_with_past_and_present_qk_matmul_expanded",
"test_attention_4d_with_qk_matmul",
"test_attention_4d_with_qk_matmul_bias",
"test_attention_4d_with_qk_matmul_bias_expanded",
"test_attention_4d_with_qk_matmul_expanded",
"test_attention_4d_with_qk_matmul_softcap",
"test_attention_4d_with_qk_matmul_softcap_expanded",
"test_attention_4d_with_qk_matmul_softmax",
"test_attention_4d_with_qk_matmul_softmax_expanded",
"test_averagepool_2d_ceil_last_window_starts_on_pad",
"test_averagepool_2d_dilations",
"test_averagepool_3d_dilations_large_count_include_pad_is_0_ceil_mode_is_False",
"test_averagepool_3d_dilations_large_count_include_pad_is_0_ceil_mode_is_True",
"test_averagepool_3d_dilations_large_count_include_pad_is_1_ceil_mode_is_False",
"test_averagepool_3d_dilations_large_count_include_pad_is_1_ceil_mode_is_True",
"test_averagepool_3d_dilations_small",
"test_basic_convinteger", // Issues::Layer::Can't create layer "onnx_node_output_0!y" of type "ConvInteger" in function 'getLayerInstance'
"test_basic_deform_conv_with_padding",
"test_basic_deform_conv_without_padding",
"test_batchnorm_epsilon_training_mode", // ---- same as above ---
"test_batchnorm_example_training_mode", // ---- same as above ---
"test_bernoulli", // Issues::Layer::Can't create layer "onnx_node_output_0!y" of type "Bernoulli" in function 'getLayerInstance'
"test_bernoulli_double", // ---- same as above ---
"test_bernoulli_double_expanded", // ---- same as above ---
"test_bernoulli_expanded", // ---- same as above ---
"test_bernoulli_seed", // ---- same as above ---
"test_bernoulli_seed_expanded", // ---- same as above ---
"test_cast_FLOAT16_to_FLOAT4E2M1",
"test_cast_FLOAT16_to_FLOAT8E4M3FN",
"test_cast_FLOAT16_to_FLOAT8E4M3FNUZ",
"test_cast_FLOAT16_to_FLOAT8E5M2",
"test_cast_FLOAT16_to_FLOAT8E5M2FNUZ",
"test_cast_FLOAT16_to_INT4",
"test_cast_FLOAT16_to_UINT4",
"test_cast_FLOAT4E2M1_to_FLOAT",
"test_cast_FLOAT4E2M1_to_FLOAT16",
"test_cast_FLOAT8E4M3FNUZ_to_FLOAT",
"test_cast_FLOAT8E4M3FNUZ_to_FLOAT16",
"test_cast_FLOAT8E4M3FN_to_FLOAT",
"test_cast_FLOAT8E4M3FN_to_FLOAT16",
"test_cast_FLOAT8E5M2FNUZ_to_FLOAT",
"test_cast_FLOAT8E5M2FNUZ_to_FLOAT16",
"test_cast_FLOAT8E5M2_to_FLOAT",
"test_cast_FLOAT8E5M2_to_FLOAT16",
"test_cast_FLOAT_to_FLOAT4E2M1",
"test_cast_FLOAT_to_FLOAT8E4M3FN",
"test_cast_FLOAT_to_FLOAT8E4M3FNUZ",
"test_cast_FLOAT_to_FLOAT8E5M2",
"test_cast_FLOAT_to_FLOAT8E5M2FNUZ",
"test_cast_FLOAT_to_INT4",
"test_cast_FLOAT_to_UINT4",
"test_cast_INT4_to_FLOAT",
"test_cast_INT4_to_FLOAT16",
"test_cast_INT4_to_INT8",
"test_cast_UINT4_to_FLOAT",
"test_cast_UINT4_to_FLOAT16",
"test_cast_UINT4_to_UINT8",
"test_cast_e8m0_FLOAT16_to_FLOAT8E8M0",
"test_cast_e8m0_FLOAT8E8M0_to_FLOAT",
"test_cast_e8m0_FLOAT8E8M0_to_FLOAT16",
"test_cast_e8m0_FLOAT_to_FLOAT8E8M0",
"test_cast_no_saturate_FLOAT16_to_FLOAT8E4M3FN",
"test_cast_no_saturate_FLOAT16_to_FLOAT8E4M3FNUZ",
"test_cast_no_saturate_FLOAT16_to_FLOAT8E5M2",
"test_cast_no_saturate_FLOAT16_to_FLOAT8E5M2FNUZ",
"test_cast_no_saturate_FLOAT_to_FLOAT8E4M3FN",
"test_cast_no_saturate_FLOAT_to_FLOAT8E4M3FNUZ",
"test_cast_no_saturate_FLOAT_to_FLOAT8E5M2",
"test_cast_no_saturate_FLOAT_to_FLOAT8E5M2FNUZ",
"test_castlike_FLOAT16_to_FLOAT4E2M1",
"test_castlike_FLOAT16_to_FLOAT4E2M1_expanded",
"test_castlike_FLOAT16_to_FLOAT8E4M3FN",
"test_castlike_FLOAT16_to_FLOAT8E4M3FNUZ",
"test_castlike_FLOAT16_to_FLOAT8E4M3FNUZ_expanded",
"test_castlike_FLOAT16_to_FLOAT8E4M3FN_expanded",
"test_castlike_FLOAT16_to_FLOAT8E5M2",
"test_castlike_FLOAT16_to_FLOAT8E5M2FNUZ",
"test_castlike_FLOAT16_to_FLOAT8E5M2FNUZ_expanded",
"test_castlike_FLOAT16_to_FLOAT8E5M2_expanded",
"test_castlike_FLOAT16_to_INT4",
"test_castlike_FLOAT16_to_INT4_expanded",
"test_castlike_FLOAT16_to_UINT4",
"test_castlike_FLOAT16_to_UINT4_expanded",
"test_castlike_FLOAT4E2M1_to_FLOAT",
"test_castlike_FLOAT4E2M1_to_FLOAT16",
"test_castlike_FLOAT4E2M1_to_FLOAT16_expanded",
"test_castlike_FLOAT4E2M1_to_FLOAT_expanded",
"test_castlike_FLOAT8E4M3FNUZ_to_FLOAT",
"test_castlike_FLOAT8E4M3FNUZ_to_FLOAT16",
"test_castlike_FLOAT8E4M3FNUZ_to_FLOAT16_expanded",
"test_castlike_FLOAT8E4M3FNUZ_to_FLOAT_expanded",
"test_castlike_FLOAT8E4M3FN_to_FLOAT",
"test_castlike_FLOAT8E4M3FN_to_FLOAT16",
"test_castlike_FLOAT8E4M3FN_to_FLOAT16_expanded",
"test_castlike_FLOAT8E4M3FN_to_FLOAT_expanded",
"test_castlike_FLOAT8E5M2FNUZ_to_FLOAT",
"test_castlike_FLOAT8E5M2FNUZ_to_FLOAT16",
"test_castlike_FLOAT8E5M2FNUZ_to_FLOAT16_expanded",
"test_castlike_FLOAT8E5M2FNUZ_to_FLOAT_expanded",
"test_castlike_FLOAT8E5M2_to_FLOAT",
"test_castlike_FLOAT8E5M2_to_FLOAT16",
"test_castlike_FLOAT8E5M2_to_FLOAT16_expanded",
"test_castlike_FLOAT8E5M2_to_FLOAT_expanded",
"test_castlike_FLOAT_to_FLOAT4E2M1",
"test_castlike_FLOAT_to_FLOAT4E2M1_expanded",
"test_castlike_FLOAT_to_FLOAT8E4M3FN",
"test_castlike_FLOAT_to_FLOAT8E4M3FNUZ",
"test_castlike_FLOAT_to_FLOAT8E4M3FNUZ_expanded",
"test_castlike_FLOAT_to_FLOAT8E4M3FN_expanded",
"test_castlike_FLOAT_to_FLOAT8E5M2",
"test_castlike_FLOAT_to_FLOAT8E5M2FNUZ",
"test_castlike_FLOAT_to_FLOAT8E5M2FNUZ_expanded",
"test_castlike_FLOAT_to_FLOAT8E5M2_expanded",
"test_castlike_FLOAT_to_INT4",
"test_castlike_FLOAT_to_INT4_expanded",
"test_castlike_FLOAT_to_STRING",
"test_castlike_FLOAT_to_UINT4",
"test_castlike_FLOAT_to_UINT4_expanded",
"test_castlike_INT4_to_FLOAT",
"test_castlike_INT4_to_FLOAT16",
"test_castlike_INT4_to_FLOAT16_expanded",
"test_castlike_INT4_to_FLOAT_expanded",
"test_castlike_INT4_to_INT8",
"test_castlike_INT4_to_INT8_expanded",
"test_castlike_STRING_to_FLOAT", // Issues::Layer::Can't create layer "onnx_node_output_0!output" of type "CastLike" in function 'getLayerInstance'
"test_castlike_UINT4_to_FLOAT",
"test_castlike_UINT4_to_FLOAT16",
"test_castlike_UINT4_to_FLOAT16_expanded",
"test_castlike_UINT4_to_FLOAT_expanded",
"test_castlike_UINT4_to_UINT8",
"test_castlike_UINT4_to_UINT8_expanded",
"test_castlike_no_saturate_FLOAT16_to_FLOAT8E4M3FN",
"test_castlike_no_saturate_FLOAT16_to_FLOAT8E4M3FNUZ",
"test_castlike_no_saturate_FLOAT16_to_FLOAT8E4M3FNUZ_expanded",
"test_castlike_no_saturate_FLOAT16_to_FLOAT8E4M3FN_expanded",
"test_castlike_no_saturate_FLOAT16_to_FLOAT8E5M2",
"test_castlike_no_saturate_FLOAT16_to_FLOAT8E5M2FNUZ",
"test_castlike_no_saturate_FLOAT16_to_FLOAT8E5M2FNUZ_expanded",
"test_castlike_no_saturate_FLOAT16_to_FLOAT8E5M2_expanded",
"test_castlike_no_saturate_FLOAT_to_FLOAT8E4M3FN",
"test_castlike_no_saturate_FLOAT_to_FLOAT8E4M3FNUZ",
"test_castlike_no_saturate_FLOAT_to_FLOAT8E5M2",
"test_castlike_no_saturate_FLOAT_to_FLOAT8E5M2FNUZ",
"test_castlike_no_saturate_FLOAT_to_FLOAT8E5M2FNUZ_expanded",
"test_castlike_no_saturate_FLOAT_to_FLOAT8E5M2_expanded",
"test_clip_example_expanded", //wrong output
"test_clip_expanded",
"test_clip_min_greater_than_max",
"test_clip_min_greater_than_max_expanded",
"test_clip_outbounds_expanded",
"test_col2im",
"test_col2im_5d",
"test_col2im_dilations",
"test_col2im_pads",
"test_col2im_strides",
"test_compress_0", // Issue::Can't create layer "onnx_node_output_0!output" of type "Compress" in function 'getLayerInstance'
"test_compress_1", // ---- same as above ---
"test_compress_default_axis", // ---- same as above ---
"test_compress_negative_axis", // ---- same as above ---
"test_constant_pad_axes", //type mismatch
"test_constant_pad_negative_axes",
"test_constantofshape_int_shape_zero", // Issue::Parser::Weights are required as inputs
"test_convinteger_with_padding", // Issues::Layer::Can't create layer "onnx_node_output_0!y" of type "ConvInteger" in function 'getLayerInstance'
"test_convinteger_without_padding", //Issues::Layer::Can't create layer "onnx_node_output_0!y" of type "ConvInteger" in function 'getLayerInstance'
"test_convtranspose_autopad_same",
"test_deform_conv_with_mask_bias",
"test_deform_conv_with_multiple_offset_groups",
"test_dequantizelinear_e4m3fn",
"test_dequantizelinear_e4m3fn_float16",
"test_dequantizelinear_e4m3fn_zero_point",
"test_dequantizelinear_e5m2",
"test_dequantizelinear_float4e2m1",
"test_dequantizelinear_int16",
"test_dequantizelinear_int4",
"test_dequantizelinear_uint16",
"test_dequantizelinear_uint4",
"test_dft_axis",
"test_dropout_default_mask", // Issue::cvtest::norm::wrong data type
"test_dropout_default_mask_ratio", // ---- same as above ---
"test_dynamicquantizelinear", // Issue:: Unkonwn error
"test_dynamicquantizelinear_expanded", // ---- same as above ---
"test_dynamicquantizelinear_max_adjusted", // ---- same as above ---
"test_dynamicquantizelinear_max_adjusted_expanded", // ---- same as above ---
"test_dynamicquantizelinear_min_adjusted", // ---- same as above ---
"test_dynamicquantizelinear_min_adjusted_expanded", // ---- same as above ---
"test_einsum_inner_prod", // Issue::Output shape does not match with reference
"test_einsum_scalar",
"test_equal_string",
"test_equal_string_broadcast",
"test_gridsample_bicubic", // ---- same as above ---
"test_gridsample_bicubic_align_corners_0_additional_1",
"test_gridsample_bicubic_align_corners_1_additional_1",
"test_group_normalization_epsilon_expanded",
"test_group_normalization_example_expanded",
"test_identity_opt", // 23221 illegal hardware instruction
"test_identity_sequence", // Issue:: Unkonwn error
"test_if_opt", // Issue::Failed to allocate 17059022683624350 bytes in function 'OutOfMemoryError'
"test_if_seq", // Issue::typeProto.has_tensor_type() in function 'dumpValueInfoProto'
"test_image_decoder_decode_bmp_rgb",
"test_image_decoder_decode_jpeg2k_rgb",
"test_image_decoder_decode_jpeg_bgr",
"test_image_decoder_decode_jpeg_grayscale",
"test_image_decoder_decode_jpeg_rgb",
"test_image_decoder_decode_png_rgb",
"test_image_decoder_decode_pnm_rgb",
"test_image_decoder_decode_tiff_rgb",
"test_image_decoder_decode_webp_rgb",
"test_l1normalization_axis_0",
"test_l1normalization_axis_1",
"test_l1normalization_axis_last",
"test_l2normalization_axis_0",
"test_l2normalization_axis_1",
"test_loop13_seq", // Loop with tensor sequences output, not yet supported in OpenCV
"test_loop16_seq_none", // Loop with optional tensor sequences, not yet supported in OpenCV
"test_lppool_1d_default",
"test_lppool_2d_default",
"test_lppool_2d_dilations",
"test_lppool_2d_pads",
"test_lppool_2d_same_lower",
"test_lppool_2d_same_upper",
"test_lppool_2d_strides",
"test_lppool_3d_default",
"test_matmulinteger", // Issues::Layer does not exist. Can't create layer "onnx_node_output_0!Y" of type "MatMulInteger" in function 'getLayerInstance'
"test_maxpool_2d_ceil_output_size_reduce_by_one",
"test_melweightmatrix",
"test_momentum", // Issues::Layer does not exist. Can't create layer "onnx_node_output_0!X1_new" of type "ai.onnx.preview.training.Momentum" in function 'getLayerInstance'
"test_momentum_multiple", // ---- same as above ---
"test_mvn", // Issues::Wrong answer
"test_mvn_expanded", // Issues::Wrong answer
"test_mvn_expanded_ver18",
"test_nesterov_momentum", // Issues::Layer does not exist (NesterovsAcceleratedGradient) Can't create layer "onnx_node_output_0!X_new" of type "ai.onnx.preview.training.Momentum" in function 'getLayerInstance'
"test_nllloss_NCd1d2_reduction_sum_expanded",
"test_nllloss_NCd1d2d3d4d5_mean_weight_expanded",
"test_optional_get_element", // Issue::out of memory :: Failed to allocate 1044051907127083008 bytes in function 'OutOfMemoryError'
"test_optional_get_element_optional_sequence",
"test_optional_get_element_optional_tensor",
"test_optional_get_element_sequence", // ---- same as above ---
"test_optional_get_element_tensor",
"test_optional_has_element", // Issue::typeProto.has_tensor_type() in function 'populateNet'
"test_optional_has_element_empty", // ---- same as above ---
"test_optional_has_element_empty_no_input_name_optional_input",
"test_optional_has_element_empty_no_input_name_tensor_input",
"test_optional_has_element_empty_no_input_optional_input",
"test_optional_has_element_empty_no_input_tensor_input",
"test_optional_has_element_empty_optional_input",
"test_optional_has_element_optional_input",
"test_optional_has_element_tensor_input",
"test_prelu_broadcast", // Issue::Parser:Blob slope not found in const blobs in function 'getBlob' (weights are required as inputs)
"test_prelu_example", // ---- same as above ---
"test_qlinearmatmul_2D_int8_float16", // Float output QLinearMatMul variants not supported
"test_qlinearmatmul_2D_int8_float32",
"test_qlinearmatmul_2D_uint8_float16",
"test_qlinearmatmul_2D_uint8_float32",
"test_qlinearmatmul_3D_int8_float16", // Float output QLinearMatMul variants not supported
"test_qlinearmatmul_3D_int8_float32",
"test_qlinearmatmul_3D_uint8_float16",
"test_qlinearmatmul_3D_uint8_float32",
"test_quantizelinear_blocked_asymmetric",
"test_quantizelinear_blocked_symmetric",
"test_quantizelinear_e4m3fn",
"test_quantizelinear_e5m2",
"test_quantizelinear_float4e2m1",
"test_quantizelinear_int16",
"test_quantizelinear_int4",
"test_quantizelinear_uint16",
"test_quantizelinear_uint4",
"test_range_float_type_positive_delta_expanded", // ---- Unsupported operations: Loop ---
"test_range_int32_type_negative_delta_expanded", // ---- same as above ---
"test_regex_full_match_basic",
"test_regex_full_match_email_domain",
"test_regex_full_match_empty",
"test_reshape_allowzero_reordered", // incompatible type of input tensor #0 'data': CV_8UC1 given, CV_32FC1 expected in function 'setGraphInput'
"test_resize_downsample_scales_cubic_align_corners", // ---- same as above ---
"test_resize_downsample_scales_cubic_antialias",
"test_resize_downsample_scales_linear_align_corners", // ---- same as above ---
"test_resize_downsample_scales_linear_antialias", //incorrect output
"test_resize_downsample_scales_linear_half_pixel_symmetric",
"test_resize_downsample_sizes_cubic_antialias",
"test_resize_downsample_sizes_linear_antialias",
"test_resize_downsample_sizes_nearest_not_larger",
"test_resize_downsample_sizes_nearest_not_smaller",
"test_resize_tf_crop_and_resize_axes_2_3",
"test_resize_tf_crop_and_resize_axes_3_2",
"test_resize_tf_crop_and_resize_extrapolation_value",
"test_resize_upsample_scales_linear_half_pixel_symmetric", //shape mismatch
"test_resize_upsample_scales_nearest_axes_3_2",
"test_resize_upsample_sizes_nearest_axes_3_2",
"test_resize_upsample_sizes_nearest_not_larger",
"test_resize_upsample_sizes_nearest_not_smaller",
"test_reversesequence_batch", // Issue:: Parser: Can't create layer "onnx_node_output_0!y" of type "ReverseSequence" in function 'getLayerInstance'
"test_reversesequence_time", // ---- same as above ---
"test_rms_normalization_2d_axis0_expanded",
"test_rms_normalization_2d_axis1_expanded",
"test_rms_normalization_2d_axis_negative_1_expanded",
"test_rms_normalization_2d_axis_negative_2_expanded",
"test_rms_normalization_3d_axis0_epsilon_expanded",
"test_rms_normalization_3d_axis1_epsilon_expanded",
"test_rms_normalization_3d_axis2_epsilon_expanded",
"test_rms_normalization_3d_axis_negative_1_epsilon_expanded",
"test_rms_normalization_3d_axis_negative_2_epsilon_expanded",
"test_rms_normalization_3d_axis_negative_3_epsilon_expanded",
"test_rms_normalization_4d_axis0_expanded",
"test_rms_normalization_4d_axis1_expanded",
"test_rms_normalization_4d_axis2_expanded",
"test_rms_normalization_4d_axis3_expanded",
"test_rms_normalization_4d_axis_negative_1_expanded",
"test_rms_normalization_4d_axis_negative_2_expanded",
"test_rms_normalization_4d_axis_negative_3_expanded",
"test_rms_normalization_4d_axis_negative_4_expanded",
"test_rms_normalization_default_axis_expanded",
"test_rnn_seq_length", // Issue:: Parser: Can't create layer "onnx_node_output_1!Y_h" of type "RNN" in function 'getLayerInstance'
"test_scan9_sum", // Issue:: Parser: 'Graph' is not supported in function 'getLayerParams'
"test_scan_sum", // ---- same as above ---
"test_sequence_insert_at_back", // Issue:: Parser: typeProto.has_tensor_type() in function 'populateNet'
"test_sequence_insert_at_front", // ---- same as above ---
"test_sequence_map_add_1_sequence_1_tensor",
"test_sequence_map_add_1_sequence_1_tensor_expanded",
"test_sequence_map_add_2_sequences",
"test_sequence_map_add_2_sequences_expanded",
"test_sequence_map_extract_shapes",
"test_sequence_map_extract_shapes_expanded",
"test_sequence_map_identity_1_sequence",
"test_sequence_map_identity_1_sequence_1_tensor",
"test_sequence_map_identity_1_sequence_1_tensor_expanded",
"test_sequence_map_identity_1_sequence_expanded",
"test_sequence_map_identity_2_sequences",
"test_sequence_map_identity_2_sequences_expanded",
"test_shape_start_greater_than_end",
"test_simple_rnn_batchwise", // Issue:: Parser: Can't create layer "onnx_node_output_1!Y_h" of type "RNN" in function 'getLayerInstance'
"test_simple_rnn_defaults", // ---- same as above ---
"test_simple_rnn_with_initial_bias", // ---- same as above ---
"test_slice_start_out_of_bounds",
"test_split_1d_uneven_split_opset18", //type mismatch
"test_split_2d_uneven_split_opset18",
"test_split_equal_parts_1d_opset13",
"test_split_equal_parts_1d_opset18",
"test_split_equal_parts_default_axis_opset13",
"test_split_equal_parts_default_axis_opset18",
"test_split_to_sequence_1",
"test_split_to_sequence_2",
"test_split_to_sequence_nokeepdims",
"test_split_zero_size_splits", // ---- incompatible type of input tensor #0 'input': CV_8UC1 given, CV_32FC1 expected in function 'setGraphInput' ---
"test_split_zero_size_splits_opset13", // type mismatch
"test_split_zero_size_splits_opset18", // type mismatch
"test_stft",
"test_stft_with_window",
"test_string_concat",
"test_string_concat_broadcasting",
"test_string_concat_empty_string",
"test_string_concat_utf8",
"test_string_concat_zero_dimensional",
"test_string_split_basic",
"test_string_split_consecutive_delimiters",
"test_string_split_empty_string_delimiter",
"test_string_split_empty_tensor",
"test_string_split_maxsplit",
"test_string_split_no_delimiter",
"test_strnormalizer_export_monday_casesensintive_lower", // 'Strings' (1) are not supported in function 'getLayerParams'
"test_strnormalizer_export_monday_casesensintive_nochangecase", // ---- same as above ---
"test_strnormalizer_export_monday_casesensintive_upper", // ---- same as above ---
"test_strnormalizer_export_monday_empty_output", // ---- same as above ---
"test_strnormalizer_export_monday_insensintive_upper_twodim", // ---- same as above ---
"test_strnormalizer_nostopwords_nochangecase", // Issue:: Parser: Can't create layer "onnx_node_output_0!y" of type "StringNormalizer" in function 'getLayerInstance'
"test_swish_expanded",
"test_tensorscatter",
"test_tensorscatter_3d",
"test_tensorscatter_circular",
"test_tfidfvectorizer_tf_batch_onlybigrams_skip0", // Issue:: Parser: Can't create layer "onnx_node_output_0!Y" of type "TfIdfVectorizer" in function 'getLayerInstance'
"test_tfidfvectorizer_tf_batch_onlybigrams_skip5", // ---- same as above ---
"test_tfidfvectorizer_tf_batch_uniandbigrams_skip5", // ---- same as above ---
"test_tfidfvectorizer_tf_only_bigrams_skip0", // ---- same as above ---
"test_tfidfvectorizer_tf_onlybigrams_levelempty", // ---- same as above ---
"test_tfidfvectorizer_tf_onlybigrams_skip5", // ---- same as above ---
"test_tfidfvectorizer_tf_uniandbigrams_skip5", // Issue:: Parser: Can't create layer "onnx_node_output_0!Y" of type "TfIdfVectorizer" in function 'getLayerInstance'
"test_training_dropout", // Issue::cvtest::norm::wrong data type
"test_training_dropout_default", // ---- same as above --- type mismatch
"test_training_dropout_default_mask", // ---- same as above ---
"test_training_dropout_mask", // ---- same as above ---
"test_training_dropout_zero_ratio_mask", // ---- same as above ---
"test_tril_zero", // ---- same as above --- type mismatch
"test_triu_zero", // ---- same as above --- type mismatch
"test_unique_length_1", //incorrect output
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,90 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#include "test_precomp.hpp"
#include "npy_blob.hpp"
namespace opencv_test { namespace {
#ifdef HAVE_ONNXRUNTIME
static std::string _tf(const std::string& filename, bool required = true)
{
return findDataFile(std::string("dnn/onnx/") + filename, required);
}
static cv::dnn::Net readNetFromONNX_ORT(const std::string& onnxModelPath)
{
cv::dnn::Net net = cv::dnn::readNetFromONNX(onnxModelPath, cv::dnn::ENGINE_ORT);
EXPECT_FALSE(net.empty());
return net;
}
TEST(Test_ONNX_ORT_Wrapper, SingleInputSingleOutput)
{
const std::string basename = "convolution";
const std::string onnxmodel = _tf("models/" + basename + ".onnx", true);
cv::Mat input = blobFromNPY(_tf("data/input_" + basename + ".npy"));
cv::Mat ref = blobFromNPY(_tf("data/output_" + basename + ".npy"));
cv::dnn::Net net = readNetFromONNX_ORT(onnxmodel);
net.setPreferableBackend(cv::dnn::DNN_BACKEND_OPENCV);
net.setPreferableTarget(cv::dnn::DNN_TARGET_CPU);
net.setInput(input);
cv::Mat out = net.forward();
normAssert(ref, out, "ORT 1in/1out convolution", 1e-5, 1e-4);
}
TEST(Test_ONNX_ORT_Wrapper, MultipleInputSingleOutput)
{
const std::string basename = "min";
const std::string onnxmodel = _tf("models/" + basename + ".onnx", true);
cv::Mat inp0 = blobFromNPY(_tf("data/input_" + basename + "_0.npy"));
cv::Mat inp1 = blobFromNPY(_tf("data/input_" + basename + "_1.npy"));
cv::Mat ref = blobFromNPY(_tf("data/output_" + basename + ".npy"));
cv::dnn::Net net = readNetFromONNX_ORT(onnxmodel);
net.setPreferableBackend(cv::dnn::DNN_BACKEND_OPENCV);
net.setPreferableTarget(cv::dnn::DNN_TARGET_CPU);
net.setInput(inp0, "0");
net.setInput(inp1, "1");
cv::Mat out = net.forward();
normAssert(ref, out, "ORT 2in/1out min", 1e-5, 1e-4);
}
TEST(Test_ONNX_ORT_Wrapper, SingleInputMultipleOutput)
{
const std::string basename = "top_k";
const std::string onnxmodel = _tf("models/" + basename + ".onnx", true);
cv::Mat input = cv::dnn::readTensorFromONNX(_tf("data/input_" + basename + ".pb"));
cv::Mat ref_val = cv::dnn::readTensorFromONNX(_tf("data/output_" + basename + "_0.pb"));
cv::Mat ref_ind = cv::dnn::readTensorFromONNX(_tf("data/output_" + basename + "_1.pb"));
cv::dnn::Net net = readNetFromONNX_ORT(onnxmodel);
net.setPreferableBackend(cv::dnn::DNN_BACKEND_OPENCV);
net.setPreferableTarget(cv::dnn::DNN_TARGET_CPU);
net.setInput(input);
std::vector<cv::Mat> outputs;
net.forward(outputs, std::vector<std::string>{"values", "indices"});
ASSERT_EQ(outputs.size(), 2u);
normAssert(ref_val, outputs[0], "ORT top_k values", 1e-5, 1e-4);
normAssert(ref_ind, outputs[1], "ORT top_k indices", 0.0, 0.0);
}
#else // HAVE_ONNXRUNTIME
TEST(Test_ONNX_ORT_Wrapper, DISABLED_NoONNXRuntime) {}
#endif
}} // namespace
+53
View File
@@ -0,0 +1,53 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#ifndef __OPENCV_TEST_PRECOMP_HPP__
#define __OPENCV_TEST_PRECOMP_HPP__
#include "opencv2/ts.hpp"
#include "opencv2/ts/ts_perf.hpp"
#include "opencv2/core/utility.hpp"
#include "opencv2/core/ocl.hpp"
#include "opencv2/core/utils/configuration.private.hpp"
#include "opencv2/dnn.hpp"
#include "test_common.hpp"
#endif
File diff suppressed because it is too large Load Diff
+352
View File
@@ -0,0 +1,352 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
/*
Test for TFLite models loading
*/
#include "test_precomp.hpp"
#include "npy_blob.hpp"
#include <opencv2/dnn/layer.details.hpp> // CV_DNN_REGISTER_LAYER_CLASS
#include <opencv2/dnn/utils/debug_utils.hpp>
#include <opencv2/dnn/shape_utils.hpp>
#ifdef OPENCV_TEST_DNN_TFLITE
namespace opencv_test { namespace {
using namespace cv;
using namespace cv::dnn;
class Test_TFLite : public DNNTestLayer {
public:
void testModel(Net& net, const std::string& modelName, const Mat& input, double l1 = 0, double lInf = 0);
void testModel(const std::string& modelName, const Mat& input, double l1 = 0, double lInf = 0);
void testModel(const std::string& modelName, const Size& inpSize, double l1 = 0, double lInf = 0);
void testLayer(const std::string& modelName, double l1 = 0, double lInf = 0);
};
void testInputShapes(const Net& net, const std::vector<Mat>& inps) {
std::vector<MatShape> inLayerShapes;
std::vector<MatShape> outLayerShapes;
net.getLayerShapes(MatShape(), CV_32F, 0, inLayerShapes, outLayerShapes);
ASSERT_EQ(inLayerShapes.size(), inps.size());
for (int i = 0; i < inps.size(); ++i) {
ASSERT_EQ(inLayerShapes[i], shape(inps[i]));
}
}
void Test_TFLite::testModel(Net& net, const std::string& modelName, const Mat& input, double l1, double lInf)
{
l1 = l1 ? l1 : default_l1;
lInf = lInf ? lInf : default_lInf;
net.setPreferableBackend(backend);
net.setPreferableTarget(target);
testInputShapes(net, {input});
net.setInput(input);
std::vector<String> outNames = net.getUnconnectedOutLayersNames();
std::vector<Mat> outs;
net.forward(outs, outNames);
ASSERT_EQ(outs.size(), outNames.size());
for (int i = 0; i < outNames.size(); ++i) {
std::replace(outNames[i].begin(), outNames[i].end(), ':', '_');
Mat ref = blobFromNPY(findDataFile(format("dnn/tflite/%s_out_%s.npy", modelName.c_str(), outNames[i].c_str())));
// A workaround solution for the following cases due to inconsistent shape definitions.
// The details please see: https://github.com/opencv/opencv/pull/25297#issuecomment-2039081369
if (modelName == "face_landmark" || modelName == "selfie_segmentation") {
ref = ref.reshape(1, 1);
outs[i] = outs[i].reshape(1, 1);
}
normAssert(ref, outs[i], outNames[i].c_str(), l1, lInf);
}
}
void Test_TFLite::testModel(const std::string& modelName, const Mat& input, double l1, double lInf)
{
Net net = readNet(findDataFile("dnn/tflite/" + modelName + ".tflite", false));
testModel(net, modelName, input, l1, lInf);
}
void Test_TFLite::testModel(const std::string& modelName, const Size& inpSize, double l1, double lInf)
{
Mat input = imread(findDataFile("cv/shared/lena.png"));
input = blobFromImage(input, 1.0 / 255, inpSize, 0, true);
testModel(modelName, input, l1, lInf);
}
void Test_TFLite::testLayer(const std::string& modelName, double l1, double lInf)
{
Mat inp = blobFromNPY(findDataFile("dnn/tflite/" + modelName + "_inp.npy"));
Net net = readNet(findDataFile("dnn/tflite/" + modelName + ".tflite"));
testModel(net, modelName, inp, l1, lInf);
}
// https://google.github.io/mediapipe/solutions/face_mesh
TEST_P(Test_TFLite, face_landmark)
{
if (backend == DNN_BACKEND_CUDA && target == DNN_TARGET_CUDA_FP16)
applyTestTag(CV_TEST_TAG_DNN_SKIP_CUDA_FP16);
double l1 = 0.066, lInf = 0.21;
if (target == DNN_TARGET_CPU_FP16 || target == DNN_TARGET_CUDA_FP16 || target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD ||
(backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL))
{
l1 = 0.15;
lInf = 0.82;
}
testModel("face_landmark", Size(192, 192), l1, lInf);
}
// https://google.github.io/mediapipe/solutions/face_detection
TEST_P(Test_TFLite, face_detection_short_range)
{
double l1 = 0, lInf = 2e-4;
if (target == DNN_TARGET_CPU_FP16 || target == DNN_TARGET_CUDA_FP16 || target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD ||
(backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL))
{
l1 = 0.04;
lInf = 0.8;
}
testModel("face_detection_short_range", Size(128, 128), l1, lInf);
}
// https://google.github.io/mediapipe/solutions/selfie_segmentation
TEST_P(Test_TFLite, selfie_segmentation)
{
double l1 = 0.002, lInf = 0.24;
if (target == DNN_TARGET_CPU_FP16 || target == DNN_TARGET_CUDA_FP16 || target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD ||
(backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL))
{
l1 = 0.01;
lInf = 0.48;
}
testModel("selfie_segmentation", Size(256, 256), l1, lInf);
}
TEST_P(Test_TFLite, max_unpooling)
{
if (backend == DNN_BACKEND_CUDA)
applyTestTag(CV_TEST_TAG_DNN_SKIP_CUDA);
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LT(2022010000)
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
#endif
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target != DNN_TARGET_CPU) {
if (target == DNN_TARGET_OPENCL_FP16) applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH);
if (target == DNN_TARGET_OPENCL) applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH);
if (target == DNN_TARGET_MYRIAD) applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH);
}
if (backend == DNN_BACKEND_OPENCV && target == DNN_TARGET_OPENCL_FP16)
applyTestTag(CV_TEST_TAG_DNN_SKIP_OPENCL_FP16);
// Due Max Unpoling is a numerically unstable operation and small difference between frameworks
// might lead to positional difference of maximal elements in the tensor, this test checks
// behavior of Max Unpooling layer only.
Net net = readNet(findDataFile("dnn/tflite/hair_segmentation.tflite", false));
net.setPreferableBackend(backend);
net.setPreferableTarget(target);
if (net.getMainGraph())
throw SkipTestException("The new dnn engine doesn't support forward to specified layers"); // https://github.com/opencv/opencv/issues/26349
Mat input = imread(findDataFile("cv/shared/lena.png"));
cvtColor(input, input, COLOR_BGR2RGBA);
input = input.mul(Scalar(1, 1, 1, 0));
input = blobFromImage(input, 1.0 / 255);
testInputShapes(net, {input});
net.setInput(input);
std::vector<std::vector<Mat> > outs;
net.forward(outs, {"p_re_lu_1", "max_pooling_with_argmax2d", "conv2d_86", "max_unpooling2d_2"});
ASSERT_EQ(outs.size(), 4);
ASSERT_EQ(outs[0].size(), 1);
ASSERT_EQ(outs[1].size(), 2);
ASSERT_EQ(outs[2].size(), 1);
ASSERT_EQ(outs[3].size(), 1);
Mat poolInp = outs[0][0];
Mat poolOut = outs[1][0];
Mat poolIds = outs[1][1];
Mat unpoolInp = outs[2][0];
Mat unpoolOut = outs[3][0];
ASSERT_EQ(poolInp.size, unpoolOut.size);
ASSERT_EQ(poolOut.size, poolIds.size);
ASSERT_EQ(poolOut.size, unpoolInp.size);
ASSERT_EQ(countNonZero(poolInp), poolInp.total());
for (int c = 0; c < 32; ++c) {
float *poolInpData = poolInp.ptr<float>(0, c);
float *poolOutData = poolOut.ptr<float>(0, c);
int64_t *poolIdsData = poolIds.ptr<int64_t>(0, c);
float *unpoolInpData = unpoolInp.ptr<float>(0, c);
float *unpoolOutData = unpoolOut.ptr<float>(0, c);
for (int y = 0; y < 64; ++y) {
for (int x = 0; x < 64; ++x) {
int maxIdx = (y * 128 + x) * 2;
std::vector<int> indices{maxIdx + 1, maxIdx + 128, maxIdx + 129};
std::string errMsg = format("Channel %d, y: %d, x: %d", c, y, x);
for (int idx : indices) {
if (poolInpData[idx] > poolInpData[maxIdx]) {
EXPECT_EQ(unpoolOutData[maxIdx], 0.0f) << errMsg;
maxIdx = idx;
}
}
EXPECT_EQ(poolInpData[maxIdx], poolOutData[y * 64 + x]) << errMsg;
if (backend != DNN_BACKEND_INFERENCE_ENGINE_NGRAPH) {
EXPECT_EQ(poolIdsData[y * 64 + x], (int64_t)maxIdx) << errMsg;
}
EXPECT_EQ(unpoolOutData[maxIdx], unpoolInpData[y * 64 + x]) << errMsg;
}
}
}
}
TEST_P(Test_TFLite, EfficientDet_int8) {
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NGRAPH); // TODO: fix this test for OpenVINO
if (target != DNN_TARGET_CPU || (backend != DNN_BACKEND_OPENCV &&
backend != DNN_BACKEND_TIMVX && backend != DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)) {
throw SkipTestException("Only OpenCV, TimVX and OpenVINO targets support INT8 on CPU");
}
Net net = readNet(findDataFile("dnn/tflite/coco_efficientdet_lite0_v1_1.0_quant_2021_09_06.tflite", false));
net.setPreferableBackend(backend);
net.setPreferableTarget(target);
Mat img = imread(findDataFile("dnn/dog416.png"));
Mat blob = blobFromImage(img, 1.0, Size(320, 320));
net.setInput(blob);
Mat out = net.forward();
Mat_<float> ref({3, 7}, {
0, 7, 0.62890625, 0.6014542579650879, 0.13300055265426636, 0.8977657556533813, 0.292389452457428,
0, 17, 0.56640625, 0.15983937680721283, 0.35905322432518005, 0.5155506730079651, 0.9409466981887817,
0, 1, 0.5, 0.14357104897499084, 0.2240825891494751, 0.7183101177215576, 0.9140362739562988
});
normAssertDetections(ref, out, "", 0.5, 0.05, 0.1);
}
TEST_P(Test_TFLite, replicate_by_pack) {
double l1 = 0, lInf = 0;
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL)
{
l1 = 4e-4;
lInf = 2e-3;
}
testLayer("replicate_by_pack", l1, lInf);
}
TEST_P(Test_TFLite, split) {
testLayer("split");
}
TEST_P(Test_TFLite, fully_connected) {
if (backend == DNN_BACKEND_VKCOM)
applyTestTag(CV_TEST_TAG_DNN_SKIP_VULKAN);
testLayer("fully_connected");
}
TEST_P(Test_TFLite, permute) {
testLayer("permutation_3d");
// Temporarily disabled as TFLiteConverter produces a incorrect graph in this case
//testLayer("permutation_4d_0123");
testLayer("permutation_4d_0132");
testLayer("permutation_4d_0213");
testLayer("permutation_4d_0231");
}
TEST_P(Test_TFLite, global_average_pooling_2d) {
testLayer("global_average_pooling_2d");
}
TEST_P(Test_TFLite, global_max_pooling_2d) {
testLayer("global_max_pooling_2d");
}
TEST_P(Test_TFLite, leakyRelu) {
testLayer("leakyRelu");
}
TEST_P(Test_TFLite, StridedSlice) {
testLayer("strided_slice");
}
TEST_P(Test_TFLite, face_blendshapes)
{
Mat inp = blobFromNPY(findDataFile("dnn/tflite/face_blendshapes_inp.npy"));
testModel("face_blendshapes", inp);
}
TEST_P(Test_TFLite, maximum)
{
Net net = readNetFromTFLite(findDataFile("dnn/tflite/maximum.tflite"));
net.setPreferableBackend(backend);
net.setPreferableTarget(target);
Mat input_x = blobFromNPY(findDataFile("dnn/tflite/maximum_input_x.npy"));
Mat input_y = blobFromNPY(findDataFile("dnn/tflite/maximum_input_y.npy"));
net.setInput(input_x, "x");
net.setInput(input_y, "y");
Mat out = net.forward();
Mat ref = blobFromNPY(findDataFile("dnn/tflite/maximum_output.npy"));
double l1 = 1e-5;
double lInf = 1e-4;
if (target == DNN_TARGET_CUDA_FP16 || target == DNN_TARGET_OPENCL_FP16)
{
l1 = 1e-3;
lInf = 1e-3;
}
normAssert(ref, out, "", l1, lInf);
}
TEST_P(Test_TFLite, minimum)
{
Net net = readNetFromTFLite(findDataFile("dnn/tflite/minimum.tflite"));
net.setPreferableBackend(backend);
net.setPreferableTarget(target);
Mat input_x = blobFromNPY(findDataFile("dnn/tflite/minimum_input_x.npy"));
Mat input_y = blobFromNPY(findDataFile("dnn/tflite/minimum_input_y.npy"));
net.setInput(input_x, "x");
net.setInput(input_y, "y");
Mat out = net.forward();
Mat ref = blobFromNPY(findDataFile("dnn/tflite/minimum_output.npy"));
double l1 = 1e-5;
double lInf = 1e-4;
if (target == DNN_TARGET_CUDA_FP16 || target == DNN_TARGET_OPENCL_FP16)
{
l1 = 1e-3;
lInf = 1e-3;
}
normAssert(ref, out, "", l1, lInf);
}
INSTANTIATE_TEST_CASE_P(/**/, Test_TFLite, dnnBackendsAndTargets());
}} // namespace
#endif // OPENCV_TEST_DNN_TFLITE
+240
View File
@@ -0,0 +1,240 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#include "test_precomp.hpp"
namespace opencv_test { namespace {
template<typename TString>
static String _tf(TString filename) {
String basetestdir = getOpenCVExtraDir();
size_t len = basetestdir.size();
if(len > 0 && basetestdir[len-1] != '/' && basetestdir[len-1] != '\\')
return (basetestdir + "/dnn/llm") + filename;
return (basetestdir + "dnn/llm/") + filename;
}
TEST(Tokenizer_BPE, Tokenizer_GPT2_Tokens) {
std::string gpt2_model = _tf("gpt2/config.json");
Tokenizer tok = Tokenizer::load(gpt2_model);
std::vector<int> tokens = tok.encode("hello world");
std::vector<int> expected = {31373, 995};
EXPECT_EQ(tokens, expected);
}
TEST(Tokenizer_BPE, Tokenizer_GPT4) {
std::string gpt4_model = _tf("gpt4/config.json");
Tokenizer tok = Tokenizer::load(gpt4_model);
std::vector<int> tokens = tok.encode("hello world");
std::vector<int> expected = {15339, 1917};
EXPECT_EQ(tokens, expected);
std::string sent = tok.decode({15339, 1917});
std::string expec_str = "hello world";
EXPECT_EQ(sent, expec_str);
}
TEST(Tokenizer_BPE, Tokenizer_GPT2) {
std::string gpt2_model = _tf("gpt2/config.json");
Tokenizer tok = Tokenizer::load(gpt2_model);
auto ids = tok.encode("hello world");
for (auto id : ids) std::cout << id << " ";
std::cout << std::endl;
auto txt = tok.decode(ids);
EXPECT_EQ(txt, "hello world");
// "Long characters" in Chinese
auto ids_j = tok.encode("\xe9\x95\xbf\xe5\xad\x97\xe7\xac\xa6");
std::string word = tok.decode(ids_j);
std::cout << word << std::endl;
}
TEST(Tokenizer_BPE, Tokenizer_GPT2_Model) {
std::string gpt2_model = _tf("gpt2/config.json");
Tokenizer tok = Tokenizer::load(gpt2_model);
auto ids = tok.encode("hello world");
auto text = tok.decode(ids);
EXPECT_EQ(text, "hello world");
}
TEST(Tokenizer_BPE, SimpleRepeated_GPT2) {
Tokenizer gpt2_tok = Tokenizer::load(_tf("gpt2/config.json"));
EXPECT_EQ(gpt2_tok.encode("0"), std::vector<int>({15}));
EXPECT_EQ(gpt2_tok.encode("00"), std::vector<int>({405}));
EXPECT_EQ(gpt2_tok.encode("000"), std::vector<int>({830}));
EXPECT_EQ(gpt2_tok.encode("0000"), std::vector<int>({2388}));
EXPECT_EQ(gpt2_tok.encode("00000"), std::vector<int>({20483}));
EXPECT_EQ(gpt2_tok.encode("000000"), std::vector<int>({10535}));
EXPECT_EQ(gpt2_tok.encode("0000000"), std::vector<int>({24598}));
EXPECT_EQ(gpt2_tok.encode("00000000"), std::vector<int>({8269}));
EXPECT_EQ(gpt2_tok.encode("000000000"), std::vector<int>({10535, 830}));
EXPECT_EQ(gpt2_tok.encode("0000000000"), std::vector<int>({8269, 405}));
EXPECT_EQ(gpt2_tok.encode("00000000000"), std::vector<int>({8269, 830}));
EXPECT_EQ(gpt2_tok.encode("000000000000"), std::vector<int>({8269, 2388}));
EXPECT_EQ(gpt2_tok.encode("0000000000000"), std::vector<int>({8269, 20483}));
EXPECT_EQ(gpt2_tok.encode("00000000000000"), std::vector<int>({8269, 10535}));
EXPECT_EQ(gpt2_tok.encode("000000000000000"), std::vector<int>({8269, 24598}));
EXPECT_EQ(gpt2_tok.encode("0000000000000000"), std::vector<int>({25645}));
EXPECT_EQ(gpt2_tok.encode("00000000000000000"), std::vector<int>({8269, 10535, 830}));
}
TEST(Tokenizer_BPE, CatastrophicallyRepetitive_GPT2) {
Tokenizer gpt2_tok = Tokenizer::load(_tf("gpt2/config.json"));
std::vector<std::string> chars = {"^", "0", "a", "'s", " ", "\n"};
for (const auto& c : chars) {
std::string big_value(c.size() == 1 ? 10000 : 10000 * c.size(), c[0]);
if (c == "'s") big_value = std::string(10000, '\'') + std::string(10000, 's');
EXPECT_EQ(big_value, gpt2_tok.decode(gpt2_tok.encode(big_value)));
std::string with_space = " " + big_value;
EXPECT_EQ(with_space, gpt2_tok.decode(gpt2_tok.encode(with_space)));
std::string with_newline = big_value + "\n";
EXPECT_EQ(with_newline, gpt2_tok.decode(gpt2_tok.encode(with_newline)));
}
}
// ---- Qwen2.5 tests ----
// Ground truth generated with:
// from transformers import AutoTokenizer
// tok = AutoTokenizer.from_pretrained("Qwen/Qwen2.5-0.5B")
// tok.encode(text)
TEST(Tokenizer_BPE, Tokenizer_Qwen2_5_English) {
std::string model = _tf("qwen2.5/config.json");
Tokenizer tok = Tokenizer::load(model);
EXPECT_EQ(tok.encode("Hello world"), (std::vector<int>{9707, 1879}));
}
TEST(Tokenizer_BPE, Tokenizer_Qwen2_5_Chinese) {
std::string model = _tf("qwen2.5/config.json");
Tokenizer tok = Tokenizer::load(model);
// 你好世界
EXPECT_EQ(tok.encode("\xe4\xbd\xa0\xe5\xa5\xbd\xe4\xb8\x96\xe7\x95\x8c"),
(std::vector<int>{108386, 99489}));
}
TEST(Tokenizer_BPE, Tokenizer_Qwen2_5_Code) {
std::string model = _tf("qwen2.5/config.json");
Tokenizer tok = Tokenizer::load(model);
EXPECT_EQ(tok.encode("def hello(): print('hello')"),
(std::vector<int>{750, 23811, 4555, 1173, 492, 14990, 863}));
}
TEST(Tokenizer_BPE, Tokenizer_Qwen2_5_Numbers) {
std::string model = _tf("qwen2.5/config.json");
Tokenizer tok = Tokenizer::load(model);
EXPECT_EQ(tok.encode("2024"), (std::vector<int>{17, 15, 17, 19}));
}
TEST(Tokenizer_BPE, Tokenizer_Qwen2_5_SpecialTokens) {
std::string model = _tf("qwen2.5/config.json");
Tokenizer tok = Tokenizer::load(model);
// <|im_start|>user\nHello<|im_end|>
EXPECT_EQ(tok.encode("<|im_start|>user\nHello<|im_end|>"),
(std::vector<int>{151644, 872, 198, 9707, 151645}));
}
TEST(Tokenizer_BPE, Tokenizer_Qwen2_5_Roundtrip) {
std::string model = _tf("qwen2.5/config.json");
Tokenizer tok = Tokenizer::load(model);
std::vector<std::string> cases = {
"Hello world",
"def hello(): print('hello')",
"2024",
};
for (const auto& text : cases) {
EXPECT_EQ(tok.decode(tok.encode(text)), text);
}
}
TEST(Tokenizer_Gemma, Tokenizer_Gemma3_English) {
std::string model = _tf("gemma3/config.json");
Tokenizer tok = Tokenizer::load(model);
EXPECT_EQ(tok.encode("Hello world"), (std::vector<int>{9259, 1902}));
}
TEST(Tokenizer_Gemma, Tokenizer_Gemma3_Phrase) {
std::string model = _tf("gemma3/config.json");
Tokenizer tok = Tokenizer::load(model);
EXPECT_EQ(tok.encode("the quick brown fox"),
(std::vector<int>{1437, 3823, 8864, 37423}));
}
TEST(Tokenizer_Gemma, Tokenizer_Gemma3_Mixed) {
std::string model = _tf("gemma3/config.json");
Tokenizer tok = Tokenizer::load(model);
EXPECT_EQ(tok.encode("OpenCV"), (std::vector<int>{7084, 20741}));
}
TEST(Tokenizer_Gemma, Tokenizer_Gemma3_Numbers) {
std::string model = _tf("gemma3/config.json");
Tokenizer tok = Tokenizer::load(model);
EXPECT_EQ(tok.encode("2024"), (std::vector<int>{236778, 236771, 236778, 236812}));
}
TEST(Tokenizer_Gemma, Tokenizer_Gemma3_SpecialTokens) {
std::string model = _tf("gemma3/config.json");
Tokenizer tok = Tokenizer::load(model);
EXPECT_EQ(tok.encode("<bos>Hello<eos>"), (std::vector<int>{2, 9259, 1}));
}
TEST(Tokenizer_Gemma, Tokenizer_Gemma3_Roundtrip) {
std::string model = _tf("gemma3/config.json");
Tokenizer tok = Tokenizer::load(model);
std::vector<std::string> cases = {
"Hello world",
"the quick brown fox",
"OpenCV",
"hello world",
};
for (const auto& text : cases) {
EXPECT_EQ(tok.decode(tok.encode(text)), text);
}
}
// Gemma2 tests (SentencePiece tokenizer)
TEST(Tokenizer_SentencePiece, Tokenizer_Gemma2_English) {
std::string model = _tf("gemma2/config.json");
Tokenizer tok = Tokenizer::load(model);
EXPECT_EQ(tok.encode("Hello world"), (std::vector<int>{2, 4521, 2134}));
}
TEST(Tokenizer_SentencePiece, Tokenizer_Gemma2_Phrase) {
std::string model = _tf("gemma2/config.json");
Tokenizer tok = Tokenizer::load(model);
EXPECT_EQ(tok.encode("the quick brown fox"),
(std::vector<int>{2, 1175, 4320, 8426, 25341}));
}
TEST(Tokenizer_SentencePiece, Tokenizer_Gemma2_Mixed) {
std::string model = _tf("gemma2/config.json");
Tokenizer tok = Tokenizer::load(model);
EXPECT_EQ(tok.encode("OpenCV"), (std::vector<int>{2, 6047, 17813}));
}
TEST(Tokenizer_SentencePiece, Tokenizer_Gemma2_Numbers) {
std::string model = _tf("gemma2/config.json");
Tokenizer tok = Tokenizer::load(model);
EXPECT_EQ(tok.encode("2024"), (std::vector<int>{2, 235284, 235276, 235284, 235310}));
}
TEST(Tokenizer_SentencePiece, Tokenizer_Gemma2_Roundtrip) {
std::string model = _tf("gemma2/config.json");
Tokenizer tok = Tokenizer::load(model);
std::vector<std::string> cases = {
"Hello world",
"the quick brown fox",
"OpenCV",
"hello world",
};
for (const auto& text : cases) {
EXPECT_EQ(tok.decode(tok.encode(text)), text);
}
}
}}