enum CELL_TYPE {
NEURON,
ASTROCYTE,
OLIGODENDROCYTE
};
typedef std::vector< CELL_TYPE > CellContainerType;
typedef std::map< CELL_TYPE, unsigned int > CellCountType;
template< class TAssociate >
class ComputeCellCountThreader :
itk::ThreadedIndexedContainerPartitioner, TAssociate >
{
public:
typedef ComputeCellCountThreader
Self;
typedef typename Superclass::DomainType
DomainType;
itkNewMacro( Self );
protected:
ComputeCellCountThreader() {}
private:
{
this->m_Associate->m_CellCount[NEURON] = 0;
this->m_Associate->m_CellCount[ASTROCYTE] = 0;
this->m_Associate->m_CellCount[OLIGODENDROCYTE] = 0;
this->m_CellCountPerThread.resize( numberOfThreads );
{
this->m_CellCountPerThread[ii][NEURON] = 0;
this->m_CellCountPerThread[ii][ASTROCYTE] = 0;
this->m_CellCountPerThread[ii][OLIGODENDROCYTE] = 0;
}
}
{
for( size_t ii = subDomain[0]; ii <= subDomain[1]; ++ii )
{
switch( this->m_Associate->m_Cells[ii] )
{
case NEURON:
++(this->m_CellCountPerThread[threadId][NEURON]);
break;
case ASTROCYTE:
++(this->m_CellCountPerThread[threadId][ASTROCYTE]);
break;
case OLIGODENDROCYTE:
++(this->m_CellCountPerThread[threadId][OLIGODENDROCYTE]);
break;
}
}
}
{
{
this->m_Associate->m_CellCount[NEURON] +=
this->m_CellCountPerThread[ii][NEURON];
this->m_Associate->m_CellCount[ASTROCYTE] +=
this->m_CellCountPerThread[ii][ASTROCYTE];
this->m_Associate->m_CellCount[OLIGODENDROCYTE] +=
this->m_CellCountPerThread[ii][OLIGODENDROCYTE];
}
}
std::vector< CellCountType > m_CellCountPerThread;
};
class CellCounter
{
public:
typedef CellCounter Self;
typedef ComputeCellCountThreader< Self > ComputeCellCountThreaderType;
CellCounter()
{
this->m_ComputeCellCountThreader = ComputeCellCountThreaderType::New();
}
void SetCells( const CellContainerType & cells )
{
this->m_Cells.resize( cells.size() );
for( size_t ii = 0; ii < cells.size(); ++ii )
{
this->m_Cells[ii] = cells[ii];
}
}
const CellCountType & ComputeCellCount()
{
ComputeCellCountThreaderType::DomainType completeDomain;
completeDomain[0] = 0;
completeDomain[1] = this->m_Cells.size() - 1;
this->m_ComputeCellCountThreader->Execute( this, completeDomain );
return this->m_CellCount;
}
private:
CellCountType m_CellCount;
CellContainerType m_Cells;
friend class ComputeCellCountThreader< Self >;
ComputeCellCountThreaderType::Pointer m_ComputeCellCountThreader;
};
int main( int, char* [] )
{
static const CELL_TYPE cellsArr[] =
{ NEURON, ASTROCYTE, ASTROCYTE, OLIGODENDROCYTE,
ASTROCYTE, NEURON, NEURON, ASTROCYTE, ASTROCYTE, OLIGODENDROCYTE };
CellContainerType cells( cellsArr,
cellsArr + sizeof(cellsArr) / sizeof(cellsArr[0]) );
CellCounter cellCounter;
cellCounter.SetCells( cells );
const CellCountType multiThreadedCellCount = cellCounter.ComputeCellCount();
std::cout << "Result of the multi-threaded cell count:\n";
std::cout << "\tNEURON: " <<
(*multiThreadedCellCount.find(NEURON)).second << "\n";
std::cout << "\tASTROCYTE: " <<
(*multiThreadedCellCount.find(ASTROCYTE)).second << "\n";
std::cout << "\tOLIGODENDROCYTE: " <<
(*multiThreadedCellCount.find(OLIGODENDROCYTE)).second << "\n";
CellCountType singleThreadedCellCount;
singleThreadedCellCount[NEURON] = 0;
singleThreadedCellCount[ASTROCYTE] = 0;
singleThreadedCellCount[OLIGODENDROCYTE] = 0;
for( size_t ii = 0; ii < cells.size(); ++ii )
{
switch( cells[ii] )
{
case NEURON:
++(singleThreadedCellCount[NEURON]);
break;
case ASTROCYTE:
++(singleThreadedCellCount[ASTROCYTE]);
break;
case OLIGODENDROCYTE:
++(singleThreadedCellCount[OLIGODENDROCYTE]);
break;
}
}
std::cout << "Result of the single-threaded cell count:\n";
std::cout << "\tNEURON: " <<
(*singleThreadedCellCount.find(NEURON)).second << "\n";
std::cout << "\tASTROCYTE: " <<
(*singleThreadedCellCount.find(ASTROCYTE)).second << "\n";
std::cout << "\tOLIGODENDROCYTE: " <<
(*singleThreadedCellCount.find(OLIGODENDROCYTE)).second << "\n";
if( (*multiThreadedCellCount.find(NEURON)).second !=
singleThreadedCellCount[NEURON] ||
(*multiThreadedCellCount.find(ASTROCYTE)).second !=
singleThreadedCellCount[ASTROCYTE] ||
(*multiThreadedCellCount.find(OLIGODENDROCYTE)).second !=
singleThreadedCellCount[OLIGODENDROCYTE] )
{
std::cerr << "Error: did not get the same results"
<< "for a single-threaded and multi-threaded calculation." << std::endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}