Commit 33803912 authored by remicres's avatar remicres

ENH: Update node memory computation functions

parent f0f3d817
......@@ -90,6 +90,7 @@ private:
void GetAutomaticConfiguration();
void ComputeMaximumStabilityMargin(unsigned int width, unsigned int height, unsigned int &iter, unsigned int &margin);
unsigned int GetNodeMemory();
long unsigned int GetMaximumNumberOfNodesInMemory();
/* Parameters given by the user */
......
......@@ -154,7 +154,32 @@ void Controller<TSegmenter>::RunSegmentation()
}
/*
* Compute the memory occupied by one node
*/
template<class TSegmenter>
unsigned int Controller<TSegmenter>::GetNodeMemory()
{
// Create a unique node
typename ImageType::Pointer onePixelImage = ImageType::New();
typename ImageType::IndexType start;
start.Fill(0);
typename ImageType::SizeType size;
size.Fill(1);
typename ImageType::RegionType region(start, size);
onePixelImage->SetRegions(region);
onePixelImage->SetNumberOfComponentsPerPixel(m_InputImage->GetNumberOfComponentsPerPixel());
onePixelImage->Allocate();
TSegmenter segmenter;
segmenter.SetInput(onePixelImage);
lsrm::GraphOperations<TSegmenter>::InitNodes(onePixelImage,segmenter,FOUR);
return segmenter.GetGraphMemory();
}
/*
* Compute the maximum number of nodes which can fit in the system memory
*/
template<class TSegmenter>
long unsigned int Controller<TSegmenter>::GetMaximumNumberOfNodesInMemory()
{
......@@ -165,42 +190,39 @@ long unsigned int Controller<TSegmenter>::GetMaximumNumberOfNodesInMemory()
m_Memory /= 2; // For safety and can prevent out of memory troubles
TSegmenter segmenter;
segmenter.SetInput(m_InputImage);
unsigned int nodeMemory = segmenter.GetNodeMemory(4); // 4 neighborhood
return std::ceil(((float) m_Memory) / ((float) nodeMemory));
return std::ceil(((float) m_Memory) / ((float) GetNodeMemory()));
}
template<class TSegmenter>
void Controller<TSegmenter>::ComputeMaximumStabilityMargin(unsigned int width,
unsigned int height, unsigned int &niter, unsigned int &margin)
{
{
itkDebugMacro(<< "Computing maximum stability margin");
// Compute the stability margin. The naive strategy consider a margin value and a stable size equal.
unsigned int tileDimension = std::min(width, height);
niter = 1;
unsigned int maxMargin = tileDimension/2;
margin = static_cast<unsigned int>(pow(2, niter + 1) - 2);
unsigned int prevMargin = margin;
unsigned int maxMargin = std::min(width, height)/2;
unsigned int currMargin = static_cast<unsigned int>(pow(2, niter + 1) - 2);
margin = currMargin;
while(margin < maxMargin)
while(currMargin < maxMargin)
{
prevMargin = margin;
margin = currMargin;
niter++;
margin = static_cast<unsigned int>(pow(2, niter + 1) - 2);
currMargin = static_cast<unsigned int>(pow(2, niter + 1) - 2);
}
niter--;
itkDebugMacro(<< "Number of iterations=" << niter << " margin=" << margin);
}
}
/*
* Compute a tiling layout which minimizes a criterion based on tile compacity
* Compute a tiling layout which minimizes a criterion based on tile compactness
* and memory usage
*
* TODO: use the lsgrmSplitter to truly compute the largest tile of a given layout
*/
template<class TSegmenter>
void Controller<TSegmenter>::GetAutomaticConfiguration()
......@@ -217,8 +239,7 @@ void Controller<TSegmenter>::GetAutomaticConfiguration()
const unsigned int imageHeight = m_InputImage->GetLargestPossibleRegion().GetSize()[1];
const unsigned long int nbOfNodesInImage = imageWidth*imageHeight;
// Initialize layout with 1x1
unsigned int nbOfTiles = 1; // Number of tiles in the layout
// Default layout: 1x1
m_NbTilesX = 1;
m_NbTilesY = 1;
......@@ -306,7 +327,7 @@ void Controller<TSegmenter>::GetAutomaticConfiguration()
TSegmenter segmenter;
segmenter.SetInput(m_InputImage);
unsigned int nodeMemory = segmenter.GetNodeMemory(4); // 4 neighborhood
unsigned int nodeMemory = GetNodeMemory();
unsigned int memoryUsed = (m_TileHeight + 2*m_Margin)*(m_TileWidth + 2*m_Margin)*nodeMemory;
itkWarningMacro(<< "An amount of " << (memoryUsed / (1024.0*1024.0)) << " Mbytes of RAM will be used for regular tiles of size "
<< (m_TileWidth + 2*m_Margin) << "x" << (m_TileHeight + 2*m_Margin) );
......
......@@ -94,7 +94,7 @@ namespace lsrm
float ComputeMergingCost(NodePointerType n1, NodePointerType n2);
void UpdateSpecificAttributes(NodePointerType n1, NodePointerType n2);
void InitFromImage();
unsigned int GetNodeMemory(unsigned int nEdges);
unsigned int GetNodeMemory(NodePointerType &node);
};
} // end of namespace lsrm
......
......@@ -132,16 +132,16 @@ namespace lsrm
template<class TImage>
unsigned int
BaatzSegmenter<TImage>::GetNodeMemory(unsigned int nEdges)
BaatzSegmenter<TImage>::GetNodeMemory(NodePointerType &node)
{
unsigned int nBands = this->m_InputImage->GetNumberOfComponentsPerPixel();
long long unsigned int memory = 0;
memory += sizeof(NodePointerType); // size of the node pointer
memory += sizeof(NodeType); // size of the node
memory += sizeof(NodeType); // size of the node (actually, size of the base node)
memory += 4 * nBands * sizeof(float); // size of the 4 attributes, multiplied by the nb. of bands
memory += nEdges * sizeof(EdgeType); // size of the edges
memory += node->m_Edges.size() * sizeof(EdgeType); // size of the edges
return memory;
}
} // end of namespace lsrm
......
......@@ -84,7 +84,7 @@ namespace lsrm
/*
* Returns the memory (in bytes) occupied by one node of the graph
*/
virtual unsigned int GetNodeMemory(unsigned int nEdges) = 0;
virtual unsigned int GetNodeMemory(NodePointerType &node) = 0;
/*
* Returns the memory (in bytes) occupied by the entire graph
......@@ -96,7 +96,7 @@ namespace lsrm
for(auto& node : m_Graph.m_Nodes)
{
numberOfMoves += node->m_Contour.size();
memory += this->GetNodeMemory(node->m_Edges.size());
memory += this->GetNodeMemory(node);
}
memory += std::ceil(numberOfMoves / 4);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment