<!-- This comment will put IE 6, 7 and 8 in quirks mode -->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<title>GpuCV: Testing and benchmarking a GpuCV operator</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javaScript" src="search/search.js"></script>
<link href="twiki_style.css" rel="stylesheet" type="text/css"/>
</head>
<body onload='searchBox.OnSelectItem(0);'>
<!-- Generated by Doxygen 1.6.3 -->
<script type="text/javascript"><!--
var searchBox = new SearchBox("searchBox", "search",false,'Search');
--></script>
<div class="navigation" id="top">
<div class="tabs">
<ul>
<li><a href="index.html"><span>Main Page</span></a></li>
<li class="current"><a href="pages.html"><span>Related Pages</span></a></li>
<li><a href="modules.html"><span>Modules</span></a></li>
<li><a href="namespaces.html"><span>Namespaces</span></a></li>
<li><a href="annotated.html"><span>Data Structures</span></a></li>
<li>
<div id="MSearchBox" class="MSearchBoxInactive">
<img id="MSearchSelect" src="search/search.png"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
alt=""/>
<input type="text" id="MSearchField" value="Search" accesskey="S"
onfocus="searchBox.OnSearchFieldFocus(true)"
onblur="searchBox.OnSearchFieldFocus(false)"
onkeyup="searchBox.OnSearchFieldChange(event)"/>
<a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.png" alt=""/></a>
</div>
</li>
</ul>
</div>
</div>
<div class="contents">
<h1><a class="anchor" id="TUTO_TEST_OP">Testing and benchmarking a GpuCV operator </a></h1><h2><a class="anchor" id="TUTO_TEST_OP__SCT_INTRO">
Intro</a></h2>
<dl class="user"><dt><b>PRE-REQUIS</b></dt><dd><ul>
<li>
<a class="el" href="TUTO__CREATE__OP__BASE.html">Creating a GpuCV operator - base concept -</a> </li>
<li>
<a class="el" href="group__GPUCVCONSOLE__GRP.html">Using GpuCVConsole application</a> </li>
</ul>
</dd></dl>
<dl class="author"><dt><b>Author:</b></dt><dd>Yannick Allusse </dd></dl>
<dl class="version"><dt><b>Version:</b></dt><dd>GpuCV v0.4.2 rev 310 </dd></dl>
<dl class="note"><dt><b>Note:</b></dt><dd>Turorial tag: <b>TUTO_TEST_OP_TAG</b></dd></dl>
<dl class="user"><dt><b></b></dt><dd>In this tutorial, we will describe how to test and benchmark a new operator using the GpuCVConsole application. <br/>
<br/>
Follow the key tag <b>TUTO_TEST_OP_TAG*</b> in full project source code to have the correspondance of each steps: <ol>
<li>
<a class="el" href="TUTO__TEST__OP.html#TUTO_TEST_OP__STP1__RUN_FCT_WRITING">Write the 'run' function</a> </li>
<li>
<a class="el" href="TUTO__TEST__OP.html#TUTO_TEST_OP__STP2__RUN_FCT_CALL">Calling your new function</a> </li>
</ol>
</dd></dl>
<h2><a class="anchor" id="TUTO_TEST_OP__STP1__RUN_FCT_WRITING">
Write the 'run' function</a></h2>
<dl class="user"><dt><b>Goal of the 'run' function:</b></dt><dd>A 'run' has to take care of the following steps: <ul>
<li>
Creating/Releasing destination images/data </li>
<li>
Calling OpenCV/IPP/GLSL/CUDA operator implementation </li>
<li>
Showing images when required </li>
<li>
Convert input data to required type </li>
</ul>
Most of them are performed using macros.</dd></dl>
<dl class="user"><dt><b>Files to edit</b></dt><dd>First, open/create the corresponding file: <ul>
<li>
src/GPUCVConsole/cxcoreg_test.[cpp/h] for a <b>cxcore</b> operator </li>
<li>
src/GPUCVConsole/cvg_test.[cpp/h] for a <b>cv</b> operator </li>
<li>
src/GPUCVConsole/cvaux_test.[cpp/h] for a <b>cvaux</b> operator </li>
<li>
src/GPUCVConsole/highgui_test.[cpp/h] for a <b>highui</b> operator </li>
<li>
src/GPUCVConsole/custom_test.[cpp/h] for a <b>user custom</b> operator </li>
</ul>
</dd></dl>
<dl class="note"><dt><b>Note:</b></dt><dd>In GpuCV examples, header files are stored in the source folder and not in the include folder cause they do not need to be included by other applications. </dd>
<dd>
We recommand you to create your own test file "YOURNAME_test.cpp" to avoid any conflicts with other operators while your are debugging. When your new operator is stable, you can merge it to corresponding main test file.</dd></dl>
<dl class="user"><dt><b>Function declaration</b></dt><dd><em>Tag:</em> <b>TUTO_TEST_OP_TAG__STP1_1__DECLARE_TEST_FUNCT</b><br/>
Open the corresponding header file to declare your function. The calling convention is: <b>run</b><em>Opername</em>, ex: runAdd, runSub, runSobel...<br/>
It takes some parameters like one or several input images, some scalar values, options, etc... depending on the original operator parameters. It does not return any values and do not use any destination image pointer. <div class="fragment"><pre class="fragment"><span class="comment">//File: src/GPUCVConsole/cxcoreg_test.h</span>
<span class="comment">//cvAdd takes two input images and an optionnal mask image.</span>
<span class="comment">//CVGXCORE_OPER_ARITHM_LOGIC_COMP_GRP</span>
...
<span class="keywordtype">void</span> <a class="code" href="group__CVGXCORE__TEST__GRP.html#ga759e7fe37a185407a8c7abb171391382">runAdd</a>(IplImage * src1,IplImage * src2, IplImage * mask);
...
<span class="comment">//CVGXCORE_OPER_STATS_GRP</span>
...
</pre></div> </dd></dl>
<dl class="note"><dt><b>Note:</b></dt><dd>Operator declarations are organized by operator categories, please keep them sorted.</dd></dl>
<dl class="user"><dt><b>Function definition</b></dt><dd>The test function must respect some conventions and rules to work correctly in GpuCVConsole: <ul>
<li>
Use macro GPUCV_FUNCNAME to define your current test function name, it is used for debugging. </li>
<li>
Use macro __CreateImages__ to create destination images with the required image format and channel. Forth parameter is a switch flag to set which implementations (OpenCV, GLSL, CUDA) have been implemented and/or must be tested. See OperType enum for details. </li>
<li>
Use macro __CreateWindows__ to create corresponding windows and __ShowImages__ to show final results. </li>
<li>
Use corresponding macros [_CV_benchLoop|_GPU_benchLoop|_CUDA_benchLoop] to run the corresponding [OpenCV|GLSL|CUDA] operator </li>
<li>
<b>DO NOT FORGOT</b> to release destination images with __ReleaseImages__ </li>
</ul>
</dd></dl>
<dl class="user"><dt><b>Example of 'runAdd' function:</b></dt><dd><em>Tag:</em> <b>TUTO_TEST_OP_TAG__STP1_2__WRITE_TEST_FUNCT</b><br/>
Here is an example of 'run' function for the add operator between two images: <div class="fragment"><pre class="fragment"><span class="comment">//File: src/GPUCVConsole/cxcoreg_test.cpp</span>
<span class="keywordtype">void</span> <a class="code" href="group__CVGXCORE__TEST__GRP.html#ga759e7fe37a185407a8c7abb171391382">runAdd</a>(IplImage * src1,IplImage * src2, IplImage * mask)
{
<a class="code" href="group__GPUCV__MACRO__BENCH__GRP.html#gaca70e19a7aa4bc59e4c06579a3cb81bf">GPUCV_FUNCNAME</a>(<span class="stringliteral">"Add"</span>);
__CreateImages__(cvGetSize(src1) ,src1->depth, src1->nChannels, OperALL);
__CreateWindows__();
std::string ParamStr=(mask)?<span class="stringliteral">"mask"</span>:<span class="stringliteral">""</span>;
_SW_benchLoop (cvgswAdd(src1,src2, destSW, mask), ParamStr);
_CV_benchLoop (cvAdd(src1,src2, destCV, mask), ParamStr);
_GPU_benchLoop (<a class="code" href="group__CVGXCORE__OPER__ARITHM__LOGIC__COMP__GRP.html#ga46fd662a659ad05df9e8b7677d9d1fe5" title="GPUCV correspondence of cvAdd function.">cvgAdd</a>(src1,src2, destGLSL, mask),destGLSL , ParamStr);
_CUDA_benchLoop (<a class="code" href="group__CVGXCORE__OPER__ARITHM__LOGIC__COMP__GRP.html#ga6c79cbb6005eb1af2d60c3ae4f6766ca">cvgCudaAdd</a>(src1,src2, destCUDA, mask),destCUDA , ParamStr);
__ShowImages__();
__ReleaseImages__();
}
</pre></div> </dd></dl>
<dl class="see"><dt><b>See also:</b></dt><dd>Macros documentation: <a class="el" href="group__GPUCV__MACRO__BENCH__GRP.html#gaca70e19a7aa4bc59e4c06579a3cb81bf">GPUCV_FUNCNAME</a>, __CreateImages__/__ReleaseImages__, __CreateWindows__/__ShowImages__, _SW_benchLoop/_CV_benchLoop/_GPU_benchLoop/_CUDA_benchLoop</dd></dl>
<dl class="warning"><dt><b>Warning:</b></dt><dd>Macros are expecting some images pointer to be defined in your function scope like <b>src1/src2</b>, you must declare them even if you do not use them: <div class="fragment"><pre class="fragment">IplImage * src1=NULL;
IplImage * src2=NULL;
</pre></div></dd></dl>
<dl class="note"><dt><b>Note:</b></dt><dd>Macros __CreateImages__/__ReleaseImages__ are creating/releasing ouput images named: <div class="fragment"><pre class="fragment"> IplImage * destCV;
IplImage * destGLSL;
IplImage * destCUDA;
</pre></div></dd></dl>
<p>If you are using other input images or matrices, you must load them to GPU using macros _SetInputImage__ or __SetInputMatrix__. It is required only for benchmarks so loading time is not recorded.</p>
<dl class="user"><dt><b>Test function specific cases</b></dt><dd>??????????????????????</dd></dl>
<h2><a class="anchor" id="TUTO_TEST_OP__STP2__RUN_FCT_CALL">
Calling your new function</a></h2>
<dl class="user"><dt><b>Add the test function to console command parser</b></dt><dd><em>Tag:</em> <b>TUTO_TEST_OP_TAG__STP2_1__PARSE_FCT_CALL</b><br/>
GpuCVConsole is using a command line/command file parser to execute user commands. You need to add your test function to the parser. <div class="fragment"><pre class="fragment"><span class="comment">//Ex: runAdd</span>
<span class="comment">//File: cxcoreg_test.cpp</span>
<span class="comment">//GlobSrc1,GlobSrc2, GlobMask are global test images managed by the GpuCVConsole application.</span>
<span class="keywordtype">bool</span> <a class="code" href="group__CVGXCORE__TEST__GRP.html#ga7faec49dc493ecd2f4363eef5685fa79" title="Parse the current command string to look for all cxcoreg operators and call them...">cxcoreg_processCommand</a>(std::string & CurCmd, std::string & nextCmd)
{
...
<span class="comment">//CVGXCORE_OPER_ARITHM_LOGIC_COMP_GRP</span>
...
<span class="keywordflow">else</span> <span class="keywordflow">if</span> (CurCmd==<span class="stringliteral">"add"</span>)
{<a class="code" href="group__CVGXCORE__TEST__GRP.html#ga759e7fe37a185407a8c7abb171391382">runAdd</a>(<a class="code" href="group__GPUCVCONSOLE__VARIABLES__GRP.html#gaddb95ed9bc68fdeed134abae3d98f814" title="Global image used as source 1.">GlobSrc1</a>,<a class="code" href="group__GPUCVCONSOLE__VARIABLES__GRP.html#ga7a198b82346b921a3cf31ffcfa99783f" title="Global image used as source 2.">GlobSrc2</a>, <a class="code" href="group__GPUCVCONSOLE__VARIABLES__GRP.html#gaa93477706651e777aa4db43e61fedaae" title="Global image used as optional mask.">GlobMask</a>);}
...
}
</pre></div> </dd></dl>
<dl class="note"><dt><b>Note:</b></dt><dd>Use only lowercase names. Some operators might need user optional values like cvMul(). In this case it is possible to ask/read a parameter from the command string buffer: <div class="fragment"><pre class="fragment"><span class="comment">//Ex: runAdd</span>
<span class="comment">//File: cxcoreg_test.cpp</span>
<span class="comment">//GlobSrc1,GlobSrc2, GlobMask are global test images managed by the GpuCVConsole application.</span>
<span class="keywordtype">bool</span> <a class="code" href="group__CVGXCORE__TEST__GRP.html#ga7faec49dc493ecd2f4363eef5685fa79" title="Parse the current command string to look for all cxcoreg operators and call them...">cxcoreg_processCommand</a>(std::string & CurCmd, std::string & nextCmd)
{
...
<span class="comment">//CVGXCORE_OPER_ARITHM_LOGIC_COMP_GRP</span>
...
<span class="keywordflow">else</span> <span class="keywordflow">if</span> (CurCmd==<span class="stringliteral">"mul"</span>)
{
<span class="keywordtype">float</span> coef=0; <span class="comment">//temporary value</span>
<a class="code" href="group__GPUCV__SIMPLEAPP__GRP.html#gabb884554bc935afb492e575d9b4fec95">GPUCV_NOTICE</a>(<span class="stringliteral">"\nFactor?"</span>); <span class="comment">//ask for it</span>
SGE::GetNextCommand(nextCmd, coef); <span class="comment">//read it from the input string(console input or command file)</span>
<a class="code" href="group__CVGXCORE__TEST__GRP.html#ga1417383645b6af7897153b0ad1ed62d5">runMul</a>(<a class="code" href="group__GPUCVCONSOLE__VARIABLES__GRP.html#gaddb95ed9bc68fdeed134abae3d98f814" title="Global image used as source 1.">GlobSrc1</a>,<a class="code" href="group__GPUCVCONSOLE__VARIABLES__GRP.html#ga7a198b82346b921a3cf31ffcfa99783f" title="Global image used as source 2.">GlobSrc2</a>, coef); <span class="comment">//run the runMul() test function with an additionnal custom value</span>
}
...
}
</pre></div> </dd></dl>
<dl class="see"><dt><b>See also:</b></dt><dd>SGE::GetNextCommand(): it use template parameters so we can read any type of values from the command string.</dd></dl>
<dl class="user"><dt><b>Add the test function to benchmarking loop</b></dt><dd><em>Tag:</em> <b>TUTO_TEST_OP_TAG__STP2_2__BENCHMARK</b><br/>
GpuCVConsole application use "runbench" command to perform benchmark on all operators using several images size, from 32x32 to 2048x2048. To benchmark your function, add it to <a class="el" href="group__CVGXCORE__TEST__GRP.html#ga6720afc5b68760cb0a4983383cf837bb" title="Execute all cxcoreg operators. It is called from the benchmarking loop.">cxcoreg_runAll()</a>/cvg_runAll() functions. <div class="fragment"><pre class="fragment"><span class="comment">//Ex: runAdd</span>
<span class="comment">//File: cxcoreg_test.cpp</span>
<span class="comment">//GlobSrc1,GlobSrc2, GlobMask are global test images managed by the GpuCVConsole application.</span>
<span class="keywordtype">void</span> <a class="code" href="group__CVGXCORE__TEST__GRP.html#ga6720afc5b68760cb0a4983383cf837bb" title="Execute all cxcoreg operators. It is called from the benchmarking loop.">cxcoreg_runAll</a>(IplImage **src1, IplImage ** src2, IplImage ** mask)
{
...
<span class="comment">//CVGXCORE_OPER_ARITHM_LOGIC_COMP_GRP</span>
...
<a class="code" href="group__CVGXCORE__TEST__GRP.html#ga759e7fe37a185407a8c7abb171391382">runAdd</a>(&src1,&src2, &mask);
...
}
</pre></div></dd></dl>
<dl class="user"><dt><b>Test your function</b></dt><dd>Now simply call you operator in the console with: <b>"opername [%arg1 %arg2]"</b>.<br/>
You can also call the benchmark loop with:<b>"runbench %loopnbr"</b>.<br/>
</dd></dl>
</div>
<!--- window showing the filter options -->
<div id="MSearchSelectWindow"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
onkeydown="return searchBox.OnSearchSelectKey(event)">
<a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(0)"><span class="SelectionMark"> </span>All</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(1)"><span class="SelectionMark"> </span>Data Structures</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(2)"><span class="SelectionMark"> </span>Namespaces</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(3)"><span class="SelectionMark"> </span>Functions</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(4)"><span class="SelectionMark"> </span>Variables</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(5)"><span class="SelectionMark"> </span>Typedefs</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(6)"><span class="SelectionMark"> </span>Enumerations</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(7)"><span class="SelectionMark"> </span>Enumerator</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(8)"><span class="SelectionMark"> </span>Friends</a></div>
<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="" frameborder="0"
name="MSearchResults" id="MSearchResults">
</iframe>
</div>
<hr size="1">
<table border="0" width="100%">
<tr>
<td>
Retrieve latest informations, releases and documentation on <a href="https://picoforge.int-evry.fr/cgi-bin/twiki/view/Gpucv/Web/WebHome">GpuCV website</a>.
</td>
<td width ="50">
</td>
<td>
<address style="text-align: right;"><small>Generated
on Wed Oct 22 20:37:13 2008 for <a href="https://picoforge.int-evry.fr/cgi-bin/twiki/view/Gpucv/Web/WebHome">GpuCV</a> by
<a href="http://www.doxygen.org/index.html"><img
src="doxygen.png" alt="doxygen" align="middle"
border="0"></a> 1.5.4 </small></address>
</td>
</tr>
</table>
|