OTB  6.7.0
Orfeo Toolbox
otbStreamingManager.hxx
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
3  *
4  * This file is part of Orfeo Toolbox
5  *
6  * https://www.orfeo-toolbox.org/
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */
20 
21 #ifndef otbStreamingManager_hxx
22 #define otbStreamingManager_hxx
23 
24 #include "otbStreamingManager.h"
26 #include "itkExtractImageFilter.h"
27 
28 namespace otb
29 {
30 
31 template <class TImage>
33  : m_ComputedNumberOfSplits(0)
34  , m_DefaultRAM(0)
35 {
36 }
37 
38 template <class TImage>
40 {
41 }
42 
43 template <class TImage>
46 {
47  return m_Splitter;
48 }
49 
50 template <class TImage>
53 {
54  MemoryPrintType availableRAMInBytes = availableRAMInMB * 1024 * 1024;
55 
56  if (availableRAMInBytes == 0)
57  {
58  if (m_DefaultRAM != 0)
59  {
60  availableRAMInBytes = 1024*1024*m_DefaultRAM;
61  }
62  else
63  {
64  // Retrieve it from the configuration
65  availableRAMInBytes = 1024*1024*ConfigurationManager::GetMaxRAMHint();
66  }
67  }
68  return availableRAMInBytes;
69 }
70 
71 template <class TImage>
72 unsigned int
74  MemoryPrintType availableRAM,
75  double bias)
76 {
77  MemoryPrintType availableRAMInBytes = GetActualAvailableRAMInBytes(availableRAM);
78 
79  otb::PipelineMemoryPrintCalculator::Pointer memoryPrintCalculator;
80  memoryPrintCalculator = otb::PipelineMemoryPrintCalculator::New();
81 
82  // Trick to avoid having the resampler compute the whole
83  // displacement field
84  double regionTrickFactor = 1;
85  ImageType* inputImage = dynamic_cast<ImageType*>(input);
86 
87  MemoryPrintType pipelineMemoryPrint;
88  if (inputImage)
89  {
90 
91  typedef itk::ExtractImageFilter<ImageType, ImageType> ExtractFilterType;
92  typename ExtractFilterType::Pointer extractFilter = ExtractFilterType::New();
93  extractFilter->SetInput(inputImage);
94 
95  // Define a small region to run the memory footprint estimation,
96  // around the image center, 100 pixels wide in each dimension
97  SizeType smallSize;
98  smallSize.Fill(100);
99  IndexType index;
100  index[0] = region.GetIndex()[0] + region.GetSize()[0]/2 - 50;
101  index[1] = region.GetIndex()[1] + region.GetSize()[1]/2 - 50;
102 
103  RegionType smallRegion;
104  smallRegion.SetSize(smallSize);
105  smallRegion.SetIndex(index);
106 
107  // In case the image is smaller than 100 pixels in a direction
108  smallRegion.Crop(region);
109 
110  extractFilter->SetExtractionRegion(smallRegion);
111 
112  bool smallRegionSuccess = smallRegion.Crop(region);
113 
114  if (smallRegionSuccess)
115  {
116  // the region is well behaved, inside the largest possible region
117  memoryPrintCalculator->SetDataToWrite(extractFilter->GetOutput() );
118 
119  regionTrickFactor = static_cast<double>( region.GetNumberOfPixels() )
120  / static_cast<double>(smallRegion.GetNumberOfPixels() );
121 
122  memoryPrintCalculator->SetBiasCorrectionFactor(regionTrickFactor * bias);
123  }
124  else
125  {
126  // the region is not well behaved
127  // use the full region
128  memoryPrintCalculator->SetDataToWrite(input);
129  memoryPrintCalculator->SetBiasCorrectionFactor(bias);
130  }
131 
132  memoryPrintCalculator->Compute();
133 
134  pipelineMemoryPrint = memoryPrintCalculator->GetMemoryPrint();
135 
136  if (smallRegionSuccess)
137  {
138  // remove the contribution of the ExtractImageFilter
139  MemoryPrintType extractContrib =
140  memoryPrintCalculator->EvaluateDataObjectPrint(extractFilter->GetOutput());
141 
142  pipelineMemoryPrint -= extractContrib;
143  }
144  }
145  else
146  {
147  // Use the original object to estimate memory footprint
148  memoryPrintCalculator->SetDataToWrite(input);
149  memoryPrintCalculator->SetBiasCorrectionFactor(1.0);
150 
151  memoryPrintCalculator->Compute();
152 
153  pipelineMemoryPrint = memoryPrintCalculator->GetMemoryPrint();
154  }
155 
156  unsigned int optimalNumberOfDivisions =
157  otb::PipelineMemoryPrintCalculator::EstimateOptimalNumberOfStreamDivisions(pipelineMemoryPrint, availableRAMInBytes);
158 
159  otbLogMacro(Info,<<"Estimated memory for full processing: "<<pipelineMemoryPrint * otb::PipelineMemoryPrintCalculator::ByteToMegabyte<<"MB (avail.: "<<availableRAMInBytes * otb::PipelineMemoryPrintCalculator::ByteToMegabyte<<" MB), optimal image partitioning: "<<optimalNumberOfDivisions<<" blocks");
160 
161  return optimalNumberOfDivisions;
162 }
163 
164 template <class TImage>
165 unsigned int
167 {
168  return m_ComputedNumberOfSplits;
169 }
170 
171 template <class TImage>
174 {
175  typename StreamingManager<TImage>::RegionType region( m_Region );
176  m_Splitter->GetSplit(i, m_ComputedNumberOfSplits, region);
177  return region;
178 }
179 
180 } // End namespace otb
181 
182 #endif
183 
static RAMValueType GetMaxRAMHint()
virtual unsigned int GetNumberOfSplits()
MemoryPrintType GetActualAvailableRAMInBytes(MemoryPrintType availableRAMInMB)
virtual unsigned int EstimateOptimalNumberOfDivisions(itk::DataObject *input, const RegionType &region, MemoryPrintType availableRAMInMB, double bias=1.0)
RegionType::IndexType IndexType
const AbstractSplitterType * GetSplitter() const
virtual RegionType GetSplit(unsigned int i)
RegionType::SizeType SizeType
#define otbLogMacro(level, msg)
Definition: otbMacro.h:54
otb::PipelineMemoryPrintCalculator::MemoryPrintType MemoryPrintType
ImageType::RegionType RegionType
static unsigned long EstimateOptimalNumberOfStreamDivisions(MemoryPrintType memoryPrint, MemoryPrintType availableMemory)