Commit 33803912 authored by remicres's avatar remicres
Browse files

ENH: Update node memory computation functions

Showing with 46 additions and 24 deletions
+46 -24
...@@ -90,6 +90,7 @@ private: ...@@ -90,6 +90,7 @@ private:
void GetAutomaticConfiguration(); void GetAutomaticConfiguration();
void ComputeMaximumStabilityMargin(unsigned int width, unsigned int height, unsigned int &iter, unsigned int &margin); void ComputeMaximumStabilityMargin(unsigned int width, unsigned int height, unsigned int &iter, unsigned int &margin);
unsigned int GetNodeMemory();
long unsigned int GetMaximumNumberOfNodesInMemory(); long unsigned int GetMaximumNumberOfNodesInMemory();
/* Parameters given by the user */ /* Parameters given by the user */
......
...@@ -154,7 +154,32 @@ void Controller<TSegmenter>::RunSegmentation() ...@@ -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> template<class TSegmenter>
long unsigned int Controller<TSegmenter>::GetMaximumNumberOfNodesInMemory() long unsigned int Controller<TSegmenter>::GetMaximumNumberOfNodesInMemory()
{ {
...@@ -165,42 +190,39 @@ 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 m_Memory /= 2; // For safety and can prevent out of memory troubles
TSegmenter segmenter; return std::ceil(((float) m_Memory) / ((float) GetNodeMemory()));
segmenter.SetInput(m_InputImage);
unsigned int nodeMemory = segmenter.GetNodeMemory(4); // 4 neighborhood
return std::ceil(((float) m_Memory) / ((float) nodeMemory));
} }
template<class TSegmenter> template<class TSegmenter>
void Controller<TSegmenter>::ComputeMaximumStabilityMargin(unsigned int width, void Controller<TSegmenter>::ComputeMaximumStabilityMargin(unsigned int width,
unsigned int height, unsigned int &niter, unsigned int &margin) unsigned int height, unsigned int &niter, unsigned int &margin)
{ {
itkDebugMacro(<< "Computing maximum stability margin"); itkDebugMacro(<< "Computing maximum stability margin");
// Compute the stability margin. The naive strategy consider a margin value and a stable size equal. // 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; niter = 1;
unsigned int maxMargin = tileDimension/2; unsigned int maxMargin = std::min(width, height)/2;
margin = static_cast<unsigned int>(pow(2, niter + 1) - 2); unsigned int currMargin = static_cast<unsigned int>(pow(2, niter + 1) - 2);
unsigned int prevMargin = margin; margin = currMargin;
while(margin < maxMargin) while(currMargin < maxMargin)
{ {
prevMargin = margin; margin = currMargin;
niter++; niter++;
margin = static_cast<unsigned int>(pow(2, niter + 1) - 2); currMargin = static_cast<unsigned int>(pow(2, niter + 1) - 2);
} }
niter--; niter--;
itkDebugMacro(<< "Number of iterations=" << niter << " margin=" << margin); 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 * and memory usage
*
* TODO: use the lsgrmSplitter to truly compute the largest tile of a given layout
*/ */
template<class TSegmenter> template<class TSegmenter>
void Controller<TSegmenter>::GetAutomaticConfiguration() void Controller<TSegmenter>::GetAutomaticConfiguration()
...@@ -217,8 +239,7 @@ void Controller<TSegmenter>::GetAutomaticConfiguration() ...@@ -217,8 +239,7 @@ void Controller<TSegmenter>::GetAutomaticConfiguration()
const unsigned int imageHeight = m_InputImage->GetLargestPossibleRegion().GetSize()[1]; const unsigned int imageHeight = m_InputImage->GetLargestPossibleRegion().GetSize()[1];
const unsigned long int nbOfNodesInImage = imageWidth*imageHeight; const unsigned long int nbOfNodesInImage = imageWidth*imageHeight;
// Initialize layout with 1x1 // Default layout: 1x1
unsigned int nbOfTiles = 1; // Number of tiles in the layout
m_NbTilesX = 1; m_NbTilesX = 1;
m_NbTilesY = 1; m_NbTilesY = 1;
...@@ -306,7 +327,7 @@ void Controller<TSegmenter>::GetAutomaticConfiguration() ...@@ -306,7 +327,7 @@ void Controller<TSegmenter>::GetAutomaticConfiguration()
TSegmenter segmenter; TSegmenter segmenter;
segmenter.SetInput(m_InputImage); 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; 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 " 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) ); << (m_TileWidth + 2*m_Margin) << "x" << (m_TileHeight + 2*m_Margin) );
......
...@@ -94,7 +94,7 @@ namespace lsrm ...@@ -94,7 +94,7 @@ namespace lsrm
float ComputeMergingCost(NodePointerType n1, NodePointerType n2); float ComputeMergingCost(NodePointerType n1, NodePointerType n2);
void UpdateSpecificAttributes(NodePointerType n1, NodePointerType n2); void UpdateSpecificAttributes(NodePointerType n1, NodePointerType n2);
void InitFromImage(); void InitFromImage();
unsigned int GetNodeMemory(unsigned int nEdges); unsigned int GetNodeMemory(NodePointerType &node);
}; };
} // end of namespace lsrm } // end of namespace lsrm
......
...@@ -132,16 +132,16 @@ namespace lsrm ...@@ -132,16 +132,16 @@ namespace lsrm
template<class TImage> template<class TImage>
unsigned int unsigned int
BaatzSegmenter<TImage>::GetNodeMemory(unsigned int nEdges) BaatzSegmenter<TImage>::GetNodeMemory(NodePointerType &node)
{ {
unsigned int nBands = this->m_InputImage->GetNumberOfComponentsPerPixel(); unsigned int nBands = this->m_InputImage->GetNumberOfComponentsPerPixel();
long long unsigned int memory = 0; long long unsigned int memory = 0;
memory += sizeof(NodePointerType); // size of the node pointer 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 += 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; return memory;
} }
} // end of namespace lsrm } // end of namespace lsrm
......
...@@ -84,7 +84,7 @@ namespace lsrm ...@@ -84,7 +84,7 @@ namespace lsrm
/* /*
* Returns the memory (in bytes) occupied by one node of the graph * 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 * Returns the memory (in bytes) occupied by the entire graph
...@@ -96,7 +96,7 @@ namespace lsrm ...@@ -96,7 +96,7 @@ namespace lsrm
for(auto& node : m_Graph.m_Nodes) for(auto& node : m_Graph.m_Nodes)
{ {
numberOfMoves += node->m_Contour.size(); numberOfMoves += node->m_Contour.size();
memory += this->GetNodeMemory(node->m_Edges.size()); memory += this->GetNodeMemory(node);
} }
memory += std::ceil(numberOfMoves / 4); memory += std::ceil(numberOfMoves / 4);
......
Supports Markdown
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