enum CELL_TYPE
{
NEURON,
ASTROCYTE,
OLIGODENDROCYTE
};
using CellContainerType = std::vector<CELL_TYPE>;
using CellCountType = std::map<CELL_TYPE, unsigned int>;
template <class TAssociate>
class ComputeCellCountThreader :
public itk::DomainThreader<itk::ThreadedIndexedContainerPartitioner, TAssociate>
{
public:
using Self = ComputeCellCountThreader;
using DomainType = typename Superclass::DomainType;
itkNewMacro(Self);
protected:
ComputeCellCountThreader() = default;
private:
void
{
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;
}
}
void
{
{
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;
}
}
}
void
{
{
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:
using Self = CellCounter;
using ComputeCellCountThreaderType = ComputeCellCountThreader<Self>;
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 (auto & cell : cells)
{
switch (cell)
{
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;
}