Skip to content

Commit

Permalink
updated code for more flexible parallelisation : TBB parallel for loo…
Browse files Browse the repository at this point in the history
…ps are replaced by opencv parallel_for_ wrapper
  • Loading branch information
albenoit committed Aug 31, 2012
1 parent e5f9f97 commit 5a6114e
Show file tree
Hide file tree
Showing 9 changed files with 97 additions and 98 deletions.
28 changes: 14 additions & 14 deletions modules/contrib/src/basicretinafilter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -345,8 +345,8 @@ void BasicRetinaFilter::_localLuminanceAdaptation(const float *inputFrame, const
//float tempMeanValue=meanLuminance+_meanInputValue*_tau;
updateCompressionParameter(meanLuminance);
}
#ifdef HAVE_TBB
tbb::parallel_for(tbb::blocked_range<size_t>(0,_filterOutput.getNBpixels()), Parallel_localAdaptation(localLuminance, inputFrame, outputFrame, _localLuminanceFactor, _localLuminanceAddon, _maxInputValue), tbb::auto_partitioner());
#ifdef MAKE_PARALLEL
cv::parallel_for_(cv::Range(0,_filterOutput.getNBpixels()), Parallel_localAdaptation(localLuminance, inputFrame, outputFrame, _localLuminanceFactor, _localLuminanceAddon, _maxInputValue));
#else
//std::cout<<meanLuminance<<std::endl;
const float *localLuminancePTR=localLuminance;
Expand Down Expand Up @@ -466,8 +466,8 @@ void BasicRetinaFilter::_horizontalCausalFilter(float *outputFrame, unsigned int
// horizontal causal filter which adds the input inside
void BasicRetinaFilter::_horizontalCausalFilter_addInput(const float *inputFrame, float *outputFrame, unsigned int IDrowStart, unsigned int IDrowEnd)
{
#ifdef HAVE_TBB
tbb::parallel_for(tbb::blocked_range<size_t>(IDrowStart,IDrowEnd), Parallel_horizontalCausalFilter_addInput(inputFrame, outputFrame, IDrowStart, _filterOutput.getNBcolumns(), _a, _tau), tbb::auto_partitioner());
#ifdef MAKE_PARALLEL
cv::parallel_for_(cv::Range(IDrowStart,IDrowEnd), Parallel_horizontalCausalFilter_addInput(inputFrame, outputFrame, IDrowStart, _filterOutput.getNBcolumns(), _a, _tau));
#else
for (unsigned int IDrow=IDrowStart; IDrow<IDrowEnd; ++IDrow)
{
Expand All @@ -487,8 +487,8 @@ void BasicRetinaFilter::_horizontalCausalFilter_addInput(const float *inputFrame
void BasicRetinaFilter::_horizontalAnticausalFilter(float *outputFrame, unsigned int IDrowStart, unsigned int IDrowEnd)
{

#ifdef HAVE_TBB
tbb::parallel_for(tbb::blocked_range<size_t>(IDrowStart,IDrowEnd), Parallel_horizontalAnticausalFilter(outputFrame, IDrowEnd, _filterOutput.getNBcolumns(), _a ), tbb::auto_partitioner());
#ifdef MAKE_PARALLEL
cv::parallel_for_(cv::Range(IDrowStart,IDrowEnd), Parallel_horizontalAnticausalFilter(outputFrame, IDrowEnd, _filterOutput.getNBcolumns(), _a ));
#else
for (unsigned int IDrow=IDrowStart; IDrow<IDrowEnd; ++IDrow)
{
Expand Down Expand Up @@ -523,8 +523,8 @@ void BasicRetinaFilter::_horizontalAnticausalFilter_multGain(float *outputFrame,
// vertical anticausal filter
void BasicRetinaFilter::_verticalCausalFilter(float *outputFrame, unsigned int IDcolumnStart, unsigned int IDcolumnEnd)
{
#ifdef HAVE_TBB
tbb::parallel_for(tbb::blocked_range<size_t>(IDcolumnStart,IDcolumnEnd), Parallel_verticalCausalFilter(outputFrame, _filterOutput.getNBrows(), _filterOutput.getNBcolumns(), _a ), tbb::auto_partitioner());
#ifdef MAKE_PARALLEL
cv::parallel_for_(cv::Range(IDcolumnStart,IDcolumnEnd), Parallel_verticalCausalFilter(outputFrame, _filterOutput.getNBrows(), _filterOutput.getNBcolumns(), _a ));
#else
for (unsigned int IDcolumn=IDcolumnStart; IDcolumn<IDcolumnEnd; ++IDcolumn)
{
Expand Down Expand Up @@ -566,8 +566,8 @@ void BasicRetinaFilter::_verticalAnticausalFilter(float *outputFrame, unsigned i
// vertical anticausal filter which multiplies the output by _gain
void BasicRetinaFilter::_verticalAnticausalFilter_multGain(float *outputFrame, unsigned int IDcolumnStart, unsigned int IDcolumnEnd)
{
#ifdef HAVE_TBB
tbb::parallel_for(tbb::blocked_range<size_t>(IDcolumnStart,IDcolumnEnd), Parallel_verticalAnticausalFilter_multGain(outputFrame, _filterOutput.getNBrows(), _filterOutput.getNBcolumns(), _a, _gain ), tbb::auto_partitioner());
#ifdef MAKE_PARALLEL
cv::parallel_for_(cv::Range(IDcolumnStart,IDcolumnEnd), Parallel_verticalAnticausalFilter_multGain(outputFrame, _filterOutput.getNBrows(), _filterOutput.getNBcolumns(), _a, _gain ));
#else
float* offset=outputFrame+_filterOutput.getNBpixels()-_filterOutput.getNBcolumns();
//#pragma omp parallel for
Expand Down Expand Up @@ -819,8 +819,8 @@ void BasicRetinaFilter::_horizontalCausalFilter_Irregular_addInput(const float *
// horizontal anticausal filter (basic way, no add on)
void BasicRetinaFilter::_horizontalAnticausalFilter_Irregular(float *outputFrame, unsigned int IDrowStart, unsigned int IDrowEnd, const float *spatialConstantBuffer)
{
#ifdef HAVE_TBB
tbb::parallel_for(tbb::blocked_range<size_t>(IDrowStart,IDrowEnd), Parallel_horizontalAnticausalFilter_Irregular(outputFrame, spatialConstantBuffer, IDrowEnd, _filterOutput.getNBcolumns()), tbb::auto_partitioner());
#ifdef MAKE_PARALLEL
cv::parallel_for_(cv::Range(IDrowStart,IDrowEnd), Parallel_horizontalAnticausalFilter_Irregular(outputFrame, spatialConstantBuffer, IDrowEnd, _filterOutput.getNBcolumns()));
#else
register float* outputPTR=outputFrame+IDrowEnd*(_filterOutput.getNBcolumns())-1;
register const float* spatialConstantPTR=spatialConstantBuffer+IDrowEnd*(_filterOutput.getNBcolumns())-1;
Expand All @@ -841,8 +841,8 @@ void BasicRetinaFilter::_horizontalAnticausalFilter_Irregular(float *outputFrame
// vertical anticausal filter
void BasicRetinaFilter::_verticalCausalFilter_Irregular(float *outputFrame, unsigned int IDcolumnStart, unsigned int IDcolumnEnd, const float *spatialConstantBuffer)
{
#ifdef HAVE_TBB
tbb::parallel_for(tbb::blocked_range<size_t>(IDcolumnStart,IDcolumnEnd), Parallel_verticalCausalFilter_Irregular(outputFrame, spatialConstantBuffer, _filterOutput.getNBrows(), _filterOutput.getNBcolumns()), tbb::auto_partitioner());
#ifdef MAKE_PARALLEL
cv::parallel_for_(cv::Range(IDcolumnStart,IDcolumnEnd), Parallel_verticalCausalFilter_Irregular(outputFrame, spatialConstantBuffer, _filterOutput.getNBrows(), _filterOutput.getNBcolumns()));
#else
for (unsigned int IDcolumn=IDcolumnStart; IDcolumn<IDcolumnEnd; ++IDcolumn)
{
Expand Down
54 changes: 27 additions & 27 deletions modules/contrib/src/basicretinafilter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -436,16 +436,16 @@ class BasicRetinaFilter
void _local_verticalCausalFilter(float *outputFrame, unsigned int IDcolumnStart, unsigned int IDcolumnEnd, const unsigned int *integrationAreas);
void _local_verticalAnticausalFilter_multGain(float *outputFrame, unsigned int IDcolumnStart, unsigned int IDcolumnEnd, const unsigned int *integrationAreas); // this functions affects _gain at the output

#ifdef HAVE_TBB
#ifdef MAKE_PARALLEL
/******************************************************
** IF TBB is useable, then, main loops are parallelized using these functors
** IF some parallelizing thread methods are available, then, main loops are parallelized using these functors
** ==> main idea paralellise main filters loops, then, only the most used methods are parallelized... TODO : increase the number of parallelised methods as necessary
** ==> functors names = Parallel_$$$ where $$$= the name of the serial method that is parallelised
** ==> functors constructors can differ from the parameters used with their related serial functions
*/

#define _DEBUG_TBB // define DEBUG_TBB in order to display additionnal data on stdout
class Parallel_horizontalAnticausalFilter
class Parallel_horizontalAnticausalFilter: public cv::ParallelLoopBody
{
private:
float *outputFrame;
Expand All @@ -465,16 +465,16 @@ class BasicRetinaFilter
#endif
}

void operator()( const tbb::blocked_range<size_t>& r ) const {
virtual void operator()( const Range& r ) const {

#ifdef DEBUG_TBB
std::cout<<"Parallel_horizontalAnticausalFilter::operator() :"
<<"\n\t range size="<<r.size()
<<"\n\t first index="<<r.begin()
<<"\n\t first index="<<r.start
//<<"\n\t last index="<<filterParam
<<std::endl;
#endif
for (size_t IDrow=r.begin(); IDrow!=r.end(); ++IDrow)
for (int IDrow=r.start; IDrow!=r.end; ++IDrow)
{
register float* outputPTR=outputFrame+(IDrowEnd-IDrow)*(nbColumns)-1;
register float result=0;
Expand All @@ -487,7 +487,7 @@ class BasicRetinaFilter
}
};

class Parallel_horizontalCausalFilter_addInput
class Parallel_horizontalCausalFilter_addInput: public cv::ParallelLoopBody
{
private:
const float *inputFrame;
Expand All @@ -498,8 +498,8 @@ class BasicRetinaFilter
Parallel_horizontalCausalFilter_addInput(const float *bufferToAddAsInputProcess, float *bufferToProcess, const unsigned int idStart, const unsigned int nbCols, const float a, const float tau)
:inputFrame(bufferToAddAsInputProcess), outputFrame(bufferToProcess), IDrowStart(idStart), nbColumns(nbCols), filterParam_a(a), filterParam_tau(tau){}

void operator()( const tbb::blocked_range<size_t>& r ) const {
for (unsigned int IDrow=r.begin(); IDrow!=r.end(); ++IDrow)
virtual void operator()( const Range& r ) const {
for (int IDrow=r.start; IDrow!=r.end; ++IDrow)
{
register float* outputPTR=outputFrame+(IDrowStart+IDrow)*nbColumns;
register const float* inputPTR=inputFrame+(IDrowStart+IDrow)*nbColumns;
Expand All @@ -513,7 +513,7 @@ class BasicRetinaFilter
}
};

class Parallel_verticalCausalFilter
class Parallel_verticalCausalFilter: public cv::ParallelLoopBody
{
private:
float *outputFrame;
Expand All @@ -523,8 +523,8 @@ class BasicRetinaFilter
Parallel_verticalCausalFilter(float *bufferToProcess, const unsigned int nbRws, const unsigned int nbCols, const float a )
:outputFrame(bufferToProcess), nbRows(nbRws), nbColumns(nbCols), filterParam_a(a){}

void operator()( const tbb::blocked_range<size_t>& r ) const {
for (unsigned int IDcolumn=r.begin(); IDcolumn!=r.end(); ++IDcolumn)
virtual void operator()( const Range& r ) const {
for (int IDcolumn=r.start; IDcolumn!=r.end; ++IDcolumn)
{
register float result=0;
register float *outputPTR=outputFrame+IDcolumn;
Expand All @@ -540,7 +540,7 @@ class BasicRetinaFilter
}
};

class Parallel_verticalAnticausalFilter_multGain
class Parallel_verticalAnticausalFilter_multGain: public cv::ParallelLoopBody
{
private:
float *outputFrame;
Expand All @@ -550,9 +550,9 @@ class BasicRetinaFilter
Parallel_verticalAnticausalFilter_multGain(float *bufferToProcess, const unsigned int nbRws, const unsigned int nbCols, const float a, const float gain)
:outputFrame(bufferToProcess), nbRows(nbRws), nbColumns(nbCols), filterParam_a(a), filterParam_gain(gain){}

void operator()( const tbb::blocked_range<size_t>& r ) const {
virtual void operator()( const Range& r ) const {
float* offset=outputFrame+nbColumns*nbRows-nbColumns;
for (unsigned int IDcolumn=r.begin(); IDcolumn!=r.end(); ++IDcolumn)
for (int IDcolumn=r.start; IDcolumn!=r.end; ++IDcolumn)
{
register float result=0;
register float *outputPTR=offset+IDcolumn;
Expand All @@ -568,7 +568,7 @@ class BasicRetinaFilter
}
};

class Parallel_localAdaptation
class Parallel_localAdaptation: public cv::ParallelLoopBody
{
private:
const float *localLuminance, *inputFrame;
Expand All @@ -578,11 +578,11 @@ class BasicRetinaFilter
Parallel_localAdaptation(const float *localLum, const float *inputImg, float *bufferToProcess, const float localLuminanceFact, const float localLuminanceAdd, const float maxInputVal)
:localLuminance(localLum), inputFrame(inputImg),outputFrame(bufferToProcess), localLuminanceFactor(localLuminanceFact), localLuminanceAddon(localLuminanceAdd), maxInputValue(maxInputVal) {};

void operator()( const tbb::blocked_range<size_t>& r ) const {
const float *localLuminancePTR=localLuminance+r.begin();
const float *inputFramePTR=inputFrame+r.begin();
float *outputFramePTR=outputFrame+r.begin();
for (register unsigned int IDpixel=r.begin() ; IDpixel!=r.end() ; ++IDpixel, ++inputFramePTR, ++outputFramePTR)
virtual void operator()( const Range& r ) const {
const float *localLuminancePTR=localLuminance+r.start;
const float *inputFramePTR=inputFrame+r.start;
float *outputFramePTR=outputFrame+r.start;
for (register int IDpixel=r.start ; IDpixel!=r.end ; ++IDpixel, ++inputFramePTR, ++outputFramePTR)
{
float X0=*(localLuminancePTR++)*localLuminanceFactor+localLuminanceAddon;
// TODO : the following line can lead to a divide by zero ! A small offset is added, take care if the offset is too large in case of High Dynamic Range images which can use very small values...
Expand All @@ -594,7 +594,7 @@ class BasicRetinaFilter

//////////////////////////////////////////
/// Specific filtering methods which manage non const spatial filtering parameter (used By retinacolor and LogProjectors)
class Parallel_horizontalAnticausalFilter_Irregular
class Parallel_horizontalAnticausalFilter_Irregular: public cv::ParallelLoopBody
{
private:
float *outputFrame;
Expand All @@ -604,9 +604,9 @@ class BasicRetinaFilter
Parallel_horizontalAnticausalFilter_Irregular(float *bufferToProcess, const float *spatialConst, const unsigned int idEnd, const unsigned int nbCols)
:outputFrame(bufferToProcess), spatialConstantBuffer(spatialConst), IDrowEnd(idEnd), nbColumns(nbCols){}

void operator()( const tbb::blocked_range<size_t>& r ) const {
virtual void operator()( const Range& r ) const {

for (size_t IDrow=r.begin(); IDrow!=r.end(); ++IDrow)
for (int IDrow=r.start; IDrow!=r.end; ++IDrow)
{
register float* outputPTR=outputFrame+(IDrowEnd-IDrow)*(nbColumns)-1;
register const float* spatialConstantPTR=spatialConstantBuffer+(IDrowEnd-IDrow)*(nbColumns)-1;
Expand All @@ -620,7 +620,7 @@ void operator()( const tbb::blocked_range<size_t>& r ) const {
}
};

class Parallel_verticalCausalFilter_Irregular
class Parallel_verticalCausalFilter_Irregular: public cv::ParallelLoopBody
{
private:
float *outputFrame;
Expand All @@ -630,8 +630,8 @@ void operator()( const tbb::blocked_range<size_t>& r ) const {
Parallel_verticalCausalFilter_Irregular(float *bufferToProcess, const float *spatialConst, const unsigned int nbRws, const unsigned int nbCols)
:outputFrame(bufferToProcess), spatialConstantBuffer(spatialConst), nbRows(nbRws), nbColumns(nbCols){}

void operator()( const tbb::blocked_range<size_t>& r ) const {
for (unsigned int IDcolumn=r.begin(); IDcolumn!=r.end(); ++IDcolumn)
virtual void operator()( const Range& r ) const {
for (int IDcolumn=r.start; IDcolumn!=r.end; ++IDcolumn)
{
register float result=0;
register float *outputPTR=outputFrame+IDcolumn;
Expand Down
4 changes: 2 additions & 2 deletions modules/contrib/src/magnoretinafilter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -153,8 +153,8 @@ void MagnoRetinaFilter::setCoefficientsTable(const float parasolCells_beta, cons

void MagnoRetinaFilter::_amacrineCellsComputing(const float *OPL_ON, const float *OPL_OFF)
{
#ifdef HAVE_TBB
tbb::parallel_for(tbb::blocked_range<size_t>(0,_filterOutput.getNBpixels()), Parallel_amacrineCellsComputing(OPL_ON, OPL_OFF, &_previousInput_ON[0], &_previousInput_OFF[0], &_amacrinCellsTempOutput_ON[0], &_amacrinCellsTempOutput_OFF[0], _temporalCoefficient), tbb::auto_partitioner());
#ifdef MAKE_PARALLEL
cv::parallel_for_(cv::Range(0,_filterOutput.getNBpixels()), Parallel_amacrineCellsComputing(OPL_ON, OPL_OFF, &_previousInput_ON[0], &_previousInput_OFF[0], &_amacrinCellsTempOutput_ON[0], &_amacrinCellsTempOutput_OFF[0], _temporalCoefficient));
#else
register const float *OPL_ON_PTR=OPL_ON;
register const float *OPL_OFF_PTR=OPL_OFF;
Expand Down
24 changes: 12 additions & 12 deletions modules/contrib/src/magnoretinafilter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -192,14 +192,14 @@ class MagnoRetinaFilter: public BasicRetinaFilter

// amacrine cells filter : high pass temporal filter
void _amacrineCellsComputing(const float *ONinput, const float *OFFinput);
#ifdef HAVE_TBB
#ifdef MAKE_PARALLEL
/******************************************************
** IF TBB is useable, then, main loops are parallelized using these functors
** IF some parallelizing thread methods are available, then, main loops are parallelized using these functors
** ==> main idea paralellise main filters loops, then, only the most used methods are parallelized... TODO : increase the number of parallelised methods as necessary
** ==> functors names = Parallel_$$$ where $$$= the name of the serial method that is parallelised
** ==> functors constructors can differ from the parameters used with their related serial functions
*/
class Parallel_amacrineCellsComputing
class Parallel_amacrineCellsComputing: public cv::ParallelLoopBody
{
private:
const float *OPL_ON, *OPL_OFF;
Expand All @@ -209,15 +209,15 @@ class MagnoRetinaFilter: public BasicRetinaFilter
Parallel_amacrineCellsComputing(const float *OPL_ON_PTR, const float *OPL_OFF_PTR, float *previousInput_ON_PTR, float *previousInput_OFF_PTR, float *amacrinCellsTempOutput_ON_PTR, float *amacrinCellsTempOutput_OFF_PTR, float temporalCoefficientVal)
:OPL_ON(OPL_ON_PTR), OPL_OFF(OPL_OFF_PTR), previousInput_ON(previousInput_ON_PTR), previousInput_OFF(previousInput_OFF_PTR), amacrinCellsTempOutput_ON(amacrinCellsTempOutput_ON_PTR), amacrinCellsTempOutput_OFF(amacrinCellsTempOutput_OFF_PTR), temporalCoefficient(temporalCoefficientVal) {}

void operator()( const tbb::blocked_range<size_t>& r ) const {
register const float *OPL_ON_PTR=OPL_ON+r.begin();
register const float *OPL_OFF_PTR=OPL_OFF+r.begin();
register float *previousInput_ON_PTR= previousInput_ON+r.begin();
register float *previousInput_OFF_PTR= previousInput_OFF+r.begin();
register float *amacrinCellsTempOutput_ON_PTR= amacrinCellsTempOutput_ON+r.begin();
register float *amacrinCellsTempOutput_OFF_PTR= amacrinCellsTempOutput_OFF+r.begin();

for (unsigned int IDpixel=r.begin() ; IDpixel!=r.end(); ++IDpixel)
virtual void operator()( const Range& r ) const {
register const float *OPL_ON_PTR=OPL_ON+r.start;
register const float *OPL_OFF_PTR=OPL_OFF+r.start;
register float *previousInput_ON_PTR= previousInput_ON+r.start;
register float *previousInput_OFF_PTR= previousInput_OFF+r.start;
register float *amacrinCellsTempOutput_ON_PTR= amacrinCellsTempOutput_ON+r.start;
register float *amacrinCellsTempOutput_OFF_PTR= amacrinCellsTempOutput_OFF+r.start;

for (int IDpixel=r.start ; IDpixel!=r.end; ++IDpixel)
{

/* Compute ON and OFF amacrin cells high pass temporal filter */
Expand Down
4 changes: 2 additions & 2 deletions modules/contrib/src/parvoretinafilter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -204,8 +204,8 @@ void ParvoRetinaFilter::_OPL_OnOffWaysComputing() // WARNING : this method requi
// loop that makes the difference between photoreceptor cells output and horizontal cells
// positive part goes on the ON way, negative pat goes on the OFF way

#ifdef HAVE_TBB
tbb::parallel_for(tbb::blocked_range<size_t>(0,_filterOutput.getNBpixels()), Parallel_OPL_OnOffWaysComputing(&_photoreceptorsOutput[0], &_horizontalCellsOutput[0], &_bipolarCellsOutputON[0], &_bipolarCellsOutputOFF[0], &_parvocellularOutputON[0], &_parvocellularOutputOFF[0]), tbb::auto_partitioner());
#ifdef MAKE_PARALLEL
cv::parallel_for_(cv::Range(0,_filterOutput.getNBpixels()), Parallel_OPL_OnOffWaysComputing(&_photoreceptorsOutput[0], &_horizontalCellsOutput[0], &_bipolarCellsOutputON[0], &_bipolarCellsOutputOFF[0], &_parvocellularOutputON[0], &_parvocellularOutputOFF[0]));
#else
float *photoreceptorsOutput_PTR= &_photoreceptorsOutput[0];
float *horizontalCellsOutput_PTR= &_horizontalCellsOutput[0];
Expand Down
Loading

0 comments on commit 5a6114e

Please sign in to comment.