Implementation detector and selector for IPP and OpenCL;
IPP can be switched on and off on runtime; Optional implementation collector was added (switched off by default in CMake). Gathers data of implementation used in functions and report this info through performance TS; TS modifications for implementations control;
This commit is contained in:
@@ -265,6 +265,95 @@ enum PERF_STRATEGY
|
||||
/*****************************************************************************************\
|
||||
* Base fixture for performance tests *
|
||||
\*****************************************************************************************/
|
||||
#ifdef CV_COLLECT_IMPL_DATA
|
||||
// Implementation collection processing class.
|
||||
// Accumulates and shapes implementation data.
|
||||
typedef struct ImplData
|
||||
{
|
||||
bool ipp;
|
||||
bool icv;
|
||||
bool ipp_mt;
|
||||
bool ocl;
|
||||
bool plain;
|
||||
std::vector<int> implCode;
|
||||
std::vector<cv::String> funName;
|
||||
|
||||
ImplData()
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
cv::setImpl(0);
|
||||
ipp = icv = ocl = ipp_mt = false;
|
||||
implCode.clear();
|
||||
funName.clear();
|
||||
}
|
||||
|
||||
void GetImpl()
|
||||
{
|
||||
flagsToVars(cv::getImpl(implCode, funName));
|
||||
}
|
||||
|
||||
std::vector<cv::String> GetCallsForImpl(int impl)
|
||||
{
|
||||
std::vector<cv::String> out;
|
||||
|
||||
for(int i = 0; i < implCode.size(); i++)
|
||||
{
|
||||
if(impl == implCode[i])
|
||||
out.push_back(funName[i]);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
// Remove duplicate entries
|
||||
void ShapeUp()
|
||||
{
|
||||
std::vector<int> savedCode;
|
||||
std::vector<cv::String> savedName;
|
||||
|
||||
for(int i = 0; i < implCode.size(); i++)
|
||||
{
|
||||
bool match = false;
|
||||
for(int j = 0; j < savedCode.size(); j++)
|
||||
{
|
||||
if(implCode[i] == savedCode[j] && !funName[i].compare(savedName[j]))
|
||||
{
|
||||
match = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!match)
|
||||
{
|
||||
savedCode.push_back(implCode[i]);
|
||||
savedName.push_back(funName[i]);
|
||||
}
|
||||
}
|
||||
|
||||
implCode = savedCode;
|
||||
funName = savedName;
|
||||
}
|
||||
|
||||
// convert flags register to more handy variables
|
||||
void flagsToVars(int flags)
|
||||
{
|
||||
#if defined(HAVE_IPP_ICV_ONLY)
|
||||
ipp = 0;
|
||||
icv = ((flags&CV_IMPL_IPP) > 0);
|
||||
#else
|
||||
ipp = ((flags&CV_IMPL_IPP) > 0);
|
||||
icv = 0;
|
||||
#endif
|
||||
ipp_mt = ((flags&CV_IMPL_MT) > 0);
|
||||
ocl = ((flags&CV_IMPL_OCL) > 0);
|
||||
plain = (flags == 0);
|
||||
}
|
||||
|
||||
} ImplData;
|
||||
#endif
|
||||
|
||||
class CV_EXPORTS TestBase: public ::testing::Test
|
||||
{
|
||||
public:
|
||||
@@ -308,6 +397,10 @@ protected:
|
||||
performance_metrics& calcMetrics();
|
||||
|
||||
void RunPerfTestBody();
|
||||
|
||||
#ifdef CV_COLLECT_IMPL_DATA
|
||||
ImplData implConf;
|
||||
#endif
|
||||
private:
|
||||
typedef std::vector<std::pair<int, cv::Size> > SizeVector;
|
||||
typedef std::vector<int64> TimeVector;
|
||||
|
@@ -31,6 +31,9 @@ static double param_time_limit;
|
||||
static int param_threads;
|
||||
static bool param_write_sanity;
|
||||
static bool param_verify_sanity;
|
||||
#ifdef CV_COLLECT_IMPL_DATA
|
||||
static bool param_collect_impl;
|
||||
#endif
|
||||
extern bool test_ipp_check;
|
||||
#ifdef HAVE_CUDA
|
||||
static int param_cuda_device;
|
||||
@@ -673,6 +676,9 @@ void TestBase::Init(const std::vector<std::string> & availableImpls,
|
||||
"{ perf_max_deviation |1.0 |}"
|
||||
#ifdef HAVE_IPP
|
||||
"{ perf_ipp_check |false |check whether IPP works without failures}"
|
||||
#endif
|
||||
#ifdef CV_COLLECT_IMPL_DATA
|
||||
"{ perf_collect_impl |false |collect info about executed implementations}"
|
||||
#endif
|
||||
"{ help h |false |print help info}"
|
||||
#ifdef HAVE_CUDA
|
||||
@@ -719,6 +725,9 @@ void TestBase::Init(const std::vector<std::string> & availableImpls,
|
||||
param_verify_sanity = args.has("perf_verify_sanity");
|
||||
test_ipp_check = !args.has("perf_ipp_check") ? getenv("OPENCV_IPP_CHECK") != NULL : true;
|
||||
param_threads = args.get<int>("perf_threads");
|
||||
#ifdef CV_COLLECT_IMPL_DATA
|
||||
param_collect_impl = args.has("perf_collect_impl");
|
||||
#endif
|
||||
#ifdef ANDROID
|
||||
param_affinity_mask = args.get<int>("perf_affinity_mask");
|
||||
log_power_checkpoints = args.has("perf_log_power_checkpoints");
|
||||
@@ -743,6 +752,13 @@ void TestBase::Init(const std::vector<std::string> & availableImpls,
|
||||
exit(1);
|
||||
}
|
||||
|
||||
#ifdef CV_COLLECT_IMPL_DATA
|
||||
if(param_collect_impl)
|
||||
cv::setUseCollection(1);
|
||||
else
|
||||
cv::setUseCollection(0);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CUDA
|
||||
|
||||
bool printOnly = args.has("perf_cuda_info_only");
|
||||
@@ -1242,6 +1258,28 @@ void TestBase::reportMetrics(bool toJUnitXML)
|
||||
RecordProperty("gstddev", cv::format("%.6f", m.gstddev).c_str());
|
||||
RecordProperty("mean", cv::format("%.0f", m.mean).c_str());
|
||||
RecordProperty("stddev", cv::format("%.0f", m.stddev).c_str());
|
||||
#ifdef CV_COLLECT_IMPL_DATA
|
||||
if(param_collect_impl)
|
||||
{
|
||||
RecordProperty("impl_ipp", (int)(implConf.ipp || implConf.icv));
|
||||
RecordProperty("impl_ocl", (int)implConf.ocl);
|
||||
RecordProperty("impl_plain", (int)implConf.plain);
|
||||
|
||||
std::string rec_line;
|
||||
std::vector<cv::String> rec;
|
||||
rec_line.clear();
|
||||
rec = implConf.GetCallsForImpl(CV_IMPL_IPP|CV_IMPL_MT);
|
||||
for(int i=0; i<rec.size();i++ ){rec_line += rec[i].c_str(); rec_line += " ";}
|
||||
rec = implConf.GetCallsForImpl(CV_IMPL_IPP);
|
||||
for(int i=0; i<rec.size();i++ ){rec_line += rec[i].c_str(); rec_line += " ";}
|
||||
RecordProperty("impl_rec_ipp", rec_line.c_str());
|
||||
|
||||
rec_line.clear();
|
||||
rec = implConf.GetCallsForImpl(CV_IMPL_OCL);
|
||||
for(int i=0; i<rec.size();i++ ){rec_line += rec[i].c_str(); rec_line += " ";}
|
||||
RecordProperty("impl_rec_ocl", rec_line.c_str());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1276,6 +1314,29 @@ void TestBase::reportMetrics(bool toJUnitXML)
|
||||
break;
|
||||
};
|
||||
|
||||
#ifdef CV_COLLECT_IMPL_DATA
|
||||
if(param_collect_impl)
|
||||
{
|
||||
LOGD("impl_ipp =%11d", (int)(implConf.ipp || implConf.icv));
|
||||
LOGD("impl_ocl =%11d", (int)implConf.ocl);
|
||||
LOGD("impl_plain =%11d", (int)implConf.plain);
|
||||
|
||||
std::string rec_line;
|
||||
std::vector<cv::String> rec;
|
||||
rec_line.clear();
|
||||
rec = implConf.GetCallsForImpl(CV_IMPL_IPP|CV_IMPL_MT);
|
||||
for(int i=0; i<rec.size();i++ ){rec_line += rec[i].c_str(); rec_line += " ";}
|
||||
rec = implConf.GetCallsForImpl(CV_IMPL_IPP);
|
||||
for(int i=0; i<rec.size();i++ ){rec_line += rec[i].c_str(); rec_line += " ";}
|
||||
LOGD("impl_rec_ipp =%s", rec_line.c_str());
|
||||
|
||||
rec_line.clear();
|
||||
rec = implConf.GetCallsForImpl(CV_IMPL_OCL);
|
||||
for(int i=0; i<rec.size();i++ ){rec_line += rec[i].c_str(); rec_line += " ";}
|
||||
LOGD("impl_rec_ocl =%s", rec_line.c_str());
|
||||
}
|
||||
#endif
|
||||
|
||||
LOGD("bytesIn =%11lu", (unsigned long)m.bytesIn);
|
||||
LOGD("bytesOut =%11lu", (unsigned long)m.bytesOut);
|
||||
if (nIters == (unsigned int)-1 || m.terminationReason == performance_metrics::TERM_ITERATIONS)
|
||||
@@ -1343,6 +1404,30 @@ void TestBase::TearDown()
|
||||
const char* value_param = test_info->value_param();
|
||||
if (value_param) printf("[ VALUE ] \t%s\n", value_param), fflush(stdout);
|
||||
if (type_param) printf("[ TYPE ] \t%s\n", type_param), fflush(stdout);
|
||||
|
||||
#ifdef CV_COLLECT_IMPL_DATA
|
||||
if(param_collect_impl)
|
||||
{
|
||||
implConf.ShapeUp();
|
||||
printf("[ I. FLAGS ] \t");
|
||||
if(implConf.ipp_mt)
|
||||
{
|
||||
if(implConf.icv) {printf("ICV_MT "); std::vector<cv::String> fun = implConf.GetCallsForImpl(CV_IMPL_IPP|CV_IMPL_MT); printf("("); for(int i=0; i<fun.size();i++ ){printf("%s ", fun[i].c_str());} printf(") "); }
|
||||
if(implConf.ipp) {printf("IPP_MT "); std::vector<cv::String> fun = implConf.GetCallsForImpl(CV_IMPL_IPP|CV_IMPL_MT); printf("("); for(int i=0; i<fun.size();i++ ){printf("%s ", fun[i].c_str());} printf(") "); }
|
||||
}
|
||||
else
|
||||
{
|
||||
if(implConf.icv) {printf("ICV "); std::vector<cv::String> fun = implConf.GetCallsForImpl(CV_IMPL_IPP); printf("("); for(int i=0; i<fun.size();i++ ){printf("%s ", fun[i].c_str());} printf(") "); }
|
||||
if(implConf.ipp) {printf("IPP "); std::vector<cv::String> fun = implConf.GetCallsForImpl(CV_IMPL_IPP); printf("("); for(int i=0; i<fun.size();i++ ){printf("%s ", fun[i].c_str());} printf(") "); }
|
||||
}
|
||||
if(implConf.ocl) {printf("OCL "); std::vector<cv::String> fun = implConf.GetCallsForImpl(CV_IMPL_OCL); printf("("); for(int i=0; i<fun.size();i++ ){printf("%s ", fun[i].c_str());} printf(") "); }
|
||||
if(implConf.plain) printf("PLAIN ");
|
||||
if(!(implConf.ipp_mt || implConf.icv || implConf.ipp || implConf.ocl || implConf.plain))
|
||||
printf("ERROR ");
|
||||
printf("\n");
|
||||
fflush(stdout);
|
||||
}
|
||||
#endif
|
||||
reportMetrics(true);
|
||||
}
|
||||
|
||||
@@ -1391,7 +1476,15 @@ void TestBase::RunPerfTestBody()
|
||||
{
|
||||
try
|
||||
{
|
||||
#ifdef CV_COLLECT_IMPL_DATA
|
||||
if(param_collect_impl)
|
||||
implConf.Reset();
|
||||
#endif
|
||||
this->PerfTestBody();
|
||||
#ifdef CV_COLLECT_IMPL_DATA
|
||||
if(param_collect_impl)
|
||||
implConf.GetImpl();
|
||||
#endif
|
||||
}
|
||||
catch(PerfSkipTestException&)
|
||||
{
|
||||
|
Reference in New Issue
Block a user