Mentions légales du service

Skip to content
Snippets Groups Projects
Commit 1170b9e4 authored by Olivier Commowick's avatar Olivier Commowick
Browse files

Correct threading errors

parent ee770c9e
Branches
No related tags found
No related merge requests found
......@@ -25,8 +25,8 @@
Copyright (c) Insight Software Consortium. All rights reserved.
See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notices for more information.
=========================================================================*/
......@@ -34,7 +34,6 @@
#define __itkDenseFiniteDifferenceImageFilter2_h_
#include "itkFiniteDifferenceImageFilter.h"
#include "itkMultiThreader.h"
namespace itk {
......@@ -49,22 +48,22 @@ namespace itk {
* iterative finite difference algorithm:
*
* \par
* \f$u_{\mathbf{i}}^{n+1}=u^n_{\mathbf{i}}+\Delta u^n_{\mathbf{i}}\Delta t\f$
* \f$u_{\mathbf{i}}^{n+1}=u^n_{\mathbf{i}}+\Delta u^n_{\mathbf{i}}\Delta t\f$
*
* \par
* The generic code for performing iterations and updates at each time
* step is inherited from the parent class. This class defines an update
* buffer for \f$ \Delta \f$ and the methods CalculateChange() and
* ApplyUpdate(). These methods are designed to automatically thread their
* execution. \f$ \Delta \f$ is defined as an image of identical size and type
* execution. \f$ \Delta \f$ is defined as an image of identical size and type
* as the output image.
*
* \par
* As we descend through each layer in the hierarchy, we know more and more
* about the specific application of our filter. At this level, we
* have committed to iteration over each pixel in an image. We take advantage
* of that knowledge to multithread the iteration and update methods.
*
* of that knowledge to multithread the iteration and update methods.
*
* \par Inputs and Outputs
* This is an image to image filter. The specific types of the images are not
* fixed at this level in the hierarchy.
......@@ -75,130 +74,133 @@ namespace itk {
* it does not define the stopping criteria (Halt method). To use this class,
* subclass it to a specific instance that supplies a function and Halt()
* method.
*
*
* \ingroup TensorToolKit
* \sa FiniteDifferenceImageFilter */
template <class TInputImage, class TOutputImage>
class ITK_EXPORT DenseFiniteDifferenceImageFilter2
: public FiniteDifferenceImageFilter<TInputImage, TOutputImage>
: public FiniteDifferenceImageFilter<TInputImage, TOutputImage>
{
public:
/** Standard class typedefs */
typedef DenseFiniteDifferenceImageFilter2 Self;
typedef FiniteDifferenceImageFilter<TInputImage, TOutputImage> Superclass;
typedef SmartPointer<Self> Pointer;
typedef SmartPointer<const Self> ConstPointer;
/** Run-time type information (and related methods) */
itkTypeMacro(DenseFiniteDifferenceImageFilter2, ImageToImageFilter );
/** Convenient typedefs */
typedef typename Superclass::InputImageType InputImageType;
typedef typename Superclass::OutputImageType OutputImageType;
typedef typename Superclass::FiniteDifferenceFunctionType
FiniteDifferenceFunctionType;
/** Dimensionality of input and output data is assumed to be the same.
/** Standard class typedefs */
typedef DenseFiniteDifferenceImageFilter2 Self;
typedef FiniteDifferenceImageFilter<TInputImage, TOutputImage> Superclass;
typedef SmartPointer<Self> Pointer;
typedef SmartPointer<const Self> ConstPointer;
/** Run-time type information (and related methods) */
itkTypeMacro(DenseFiniteDifferenceImageFilter2, ImageToImageFilter );
/** Convenient typedefs */
typedef typename Superclass::InputImageType InputImageType;
typedef typename Superclass::OutputImageType OutputImageType;
typedef typename Superclass::FiniteDifferenceFunctionType
FiniteDifferenceFunctionType;
/** Dimensionality of input and output data is assumed to be the same.
* It is inherited from the superclass. */
itkStaticConstMacro(ImageDimension, unsigned int,Superclass::ImageDimension);
itkStaticConstMacro(ImageDimension, unsigned int,Superclass::ImageDimension);
/** The pixel type of the output image will be used in computations.
/** The pixel type of the output image will be used in computations.
* Inherited from the superclass. */
typedef typename Superclass::PixelType PixelType;
typedef typename Superclass::PixelType PixelType;
/** The value type of a time step. Inherited from the superclass. */
typedef typename Superclass::TimeStepType TimeStepType;
/** The value type of a time step. Inherited from the superclass. */
typedef typename Superclass::TimeStepType TimeStepType;
/** The container type for the update buffer. */
typedef OutputImageType UpdateBufferType;
protected:
DenseFiniteDifferenceImageFilter2()
{ m_UpdateBuffer = UpdateBufferType::New(); }
~DenseFiniteDifferenceImageFilter2() {}
void PrintSelf(std::ostream& os, Indent indent) const;
/** The container type for the update buffer. */
typedef OutputImageType UpdateBufferType;
/** A simple method to copy the data from the input to the output. ( Supports
protected:
DenseFiniteDifferenceImageFilter2()
{
m_UpdateBuffer = UpdateBufferType::New();
this->DynamicMultiThreadingOff();
}
~DenseFiniteDifferenceImageFilter2() {}
void PrintSelf(std::ostream& os, Indent indent) const;
/** A simple method to copy the data from the input to the output. ( Supports
* "read-only" image adaptors in the case where the input image type converts
* to a different output image type. ) */
virtual void CopyInputToOutput();
virtual void CopyInputToOutput();
/** This method applies changes from the m_UpdateBuffer to the output using
/** This method applies changes from the m_UpdateBuffer to the output using
* the ThreadedAPplyUpdate() method and a multithreading mechanism. "dt" is
* the time step to use for the update of each pixel. */
virtual void ApplyUpdate(const TimeStepType &dt);
virtual void ApplyUpdate(const TimeStepType &dt);
/** Method to allow subclasses to get direct access to the update
/** Method to allow subclasses to get direct access to the update
* buffer */
virtual UpdateBufferType* GetUpdateBuffer()
virtual UpdateBufferType* GetUpdateBuffer()
{ return m_UpdateBuffer; }
private:
DenseFiniteDifferenceImageFilter2(const Self&); //purposely not implemented
void operator=(const Self&); //purposely not implemented
DenseFiniteDifferenceImageFilter2(const Self&); //purposely not implemented
void operator=(const Self&); //purposely not implemented
/** Structure for passing information into static callback methods. Used in
/** Structure for passing information into static callback methods. Used in
* the subclasses' threading mechanisms. */
struct DenseFDThreadStruct
{
DenseFiniteDifferenceImageFilter2 *Filter;
TimeStepType TimeStep;
std::vector <TimeStepType> TimeStepList;
std::vector <bool> ValidTimeStepList;
};
/** The type of region used for multithreading */
typedef typename UpdateBufferType::RegionType ThreadRegionType;
/** This method allocates storage in m_UpdateBuffer. It is called from
struct DenseFDThreadStruct
{
DenseFiniteDifferenceImageFilter2 *Filter;
TimeStepType TimeStep;
std::vector <TimeStepType> TimeStepList;
std::vector <bool> ValidTimeStepList;
};
/** The type of region used for multithreading */
typedef typename UpdateBufferType::RegionType ThreadRegionType;
/** This method allocates storage in m_UpdateBuffer. It is called from
* Superclass::GenerateData(). */
virtual void AllocateUpdateBuffer();
/** This callback method uses ImageSource::SplitRequestedRegion to acquire an
virtual void AllocateUpdateBuffer();
/** This callback method uses ImageSource::SplitRequestedRegion to acquire an
* output region that it passes to ThreadedApplyUpdate for processing. */
static ITK_THREAD_RETURN_TYPE ApplyUpdateThreaderCallback( void *arg );
/** This method populates an update buffer with changes for each pixel in the
static ITK_THREAD_RETURN_FUNCTION_CALL_CONVENTION ApplyUpdateThreaderCallback( void *arg );
/** This method populates an update buffer with changes for each pixel in the
* output using the ThreadedCalculateChange() method and a multithreading
* mechanism. Returns value is a time step to be used for the update. */
virtual TimeStepType CalculateChange();
virtual TimeStepType CalculateChange();
/** This callback method uses SplitUpdateContainer to acquire a region
/** This callback method uses SplitUpdateContainer to acquire a region
* which it then passes to ThreadedCalculateChange for processing. */
static ITK_THREAD_RETURN_TYPE CalculateChangeThreaderCallback( void *arg );
/** Split the UpdateBuffer into "num" pieces, returning region "i" as
static ITK_THREAD_RETURN_FUNCTION_CALL_CONVENTION CalculateChangeThreaderCallback( void *arg );
/** Split the UpdateBuffer into "num" pieces, returning region "i" as
* "splitRegion". This method is called "num" times to return non-overlapping
* regions. The method returns the number of pieces that the UpdateBuffer
* can be split into by the routine. i.e. return value is less than or equal
* to "num".
* \sa ImageSource */
// virtual
// int SplitUpdateContainer(int i, int num, ThreadRegionType& splitRegion);
// virtual
// int SplitUpdateContainer(int i, int num, ThreadRegionType& splitRegion);
/** Does the actual work of updating the output from the UpdateContainer over
/** Does the actual work of updating the output from the UpdateContainer over
* an output region supplied by the multithreading mechanism.
* \sa ApplyUpdate
* \sa ApplyUpdateThreaderCallback */
virtual
void ThreadedApplyUpdate(TimeStepType dt,
const ThreadRegionType &regionToProcess,
ThreadIdType threadId);
// FOR ALL: iterator(output, splitRegion), iterator(update, splitRegion)
/** Does the actual work of calculating change over a region supplied by
* \sa ApplyUpdateThreaderCallback */
virtual
void ThreadedApplyUpdate(TimeStepType dt,
const ThreadRegionType &regionToProcess,
ThreadIdType threadId);
// FOR ALL: iterator(output, splitRegion), iterator(update, splitRegion)
/** Does the actual work of calculating change over a region supplied by
* the multithreading mechanism.
* \sa CalculateChange
* \sa CalculateChangeThreaderCallback */
virtual
TimeStepType ThreadedCalculateChange(const ThreadRegionType &regionToProcess,
ThreadIdType threadId);
// FOR ALL : iterator(input, splitRegion), iterator(update, splitRegion)
virtual
TimeStepType ThreadedCalculateChange(const ThreadRegionType &regionToProcess,
ThreadIdType threadId);
// FOR ALL : iterator(input, splitRegion), iterator(update, splitRegion)
/** The buffer that holds the updates for an iteration of the algorithm. */
typename UpdateBufferType::Pointer m_UpdateBuffer;
/** The buffer that holds the updates for an iteration of the algorithm. */
typename UpdateBufferType::Pointer m_UpdateBuffer;
};
}// end namespace itk
......
......@@ -100,26 +100,25 @@ DenseFiniteDifferenceImageFilter2<TInputImage, TOutputImage>
DenseFDThreadStruct str;
str.Filter = this;
str.TimeStep = dt;
this->GetMultiThreader()->SetNumberOfThreads(this->GetNumberOfThreads());
this->GetMultiThreader()->SetNumberOfWorkUnits(this->GetNumberOfWorkUnits());
this->GetMultiThreader()->SetSingleMethod(this->ApplyUpdateThreaderCallback,
&str);
// Multithread the execution
this->GetMultiThreader()->SingleMethodExecute();
}
template<class TInputImage, class TOutputImage>
ITK_THREAD_RETURN_TYPE
ITK_THREAD_RETURN_FUNCTION_CALL_CONVENTION
DenseFiniteDifferenceImageFilter2<TInputImage, TOutputImage>
::ApplyUpdateThreaderCallback( void * arg )
{
DenseFDThreadStruct * str;
int total, threadId, threadCount;
threadId = ((MultiThreader::ThreadInfoStruct *)(arg))->ThreadID;
threadCount = ((MultiThreader::ThreadInfoStruct *)(arg))->NumberOfThreads;
threadId = ((MultiThreaderBase::WorkUnitInfo *)(arg))->WorkUnitID;
threadCount = ((MultiThreaderBase::WorkUnitInfo *)(arg))->NumberOfWorkUnits;
str = (DenseFDThreadStruct *)(((MultiThreader::ThreadInfoStruct *)(arg))->UserData);
str = (DenseFDThreadStruct *)(((MultiThreaderBase::WorkUnitInfo *)(arg))->UserData);
// Execute the actual method with appropriate output region
// first find out how many pieces extent can be split into.
......@@ -133,7 +132,7 @@ DenseFiniteDifferenceImageFilter2<TInputImage, TOutputImage>
str->Filter->ThreadedApplyUpdate(str->TimeStep, splitRegion, threadId);
}
return ITK_THREAD_RETURN_VALUE;
return ITK_THREAD_RETURN_DEFAULT_VALUE;
}
template <class TInputImage, class TOutputImage>
......@@ -150,14 +149,14 @@ DenseFiniteDifferenceImageFilter2<TInputImage, TOutputImage>
str.Filter = this;
str.TimeStep = NumericTraits<TimeStepType>::Zero; // Not used during the
// calculate change step.
this->GetMultiThreader()->SetNumberOfThreads(this->GetNumberOfThreads());
this->GetMultiThreader()->SetNumberOfWorkUnits(this->GetNumberOfWorkUnits());
this->GetMultiThreader()->SetSingleMethod(this->CalculateChangeThreaderCallback,
&str);
// Initialize the list of time step values that will be generated by the
// various threads. There is one distinct slot for each possible thread,
// so this data structure is thread-safe.
threadCount = this->GetMultiThreader()->GetNumberOfThreads();
threadCount = this->GetMultiThreader()->GetNumberOfWorkUnits();
str.TimeStepList.resize(threadCount);
str.ValidTimeStepList.resize(threadCount);
str.ValidTimeStepList.resize( threadCount, false );
......@@ -178,17 +177,17 @@ DenseFiniteDifferenceImageFilter2<TInputImage, TOutputImage>
}
template <class TInputImage, class TOutputImage>
ITK_THREAD_RETURN_TYPE
ITK_THREAD_RETURN_FUNCTION_CALL_CONVENTION
DenseFiniteDifferenceImageFilter2<TInputImage, TOutputImage>
::CalculateChangeThreaderCallback( void * arg )
{
DenseFDThreadStruct * str;
int total, threadId, threadCount;
threadId = ((MultiThreader::ThreadInfoStruct *)(arg))->ThreadID;
threadCount = ((MultiThreader::ThreadInfoStruct *)(arg))->NumberOfThreads;
threadId = ((MultiThreaderBase::WorkUnitInfo *)(arg))->WorkUnitID;
threadCount = ((MultiThreaderBase::WorkUnitInfo *)(arg))->NumberOfWorkUnits;
str = (DenseFDThreadStruct *)(((MultiThreader::ThreadInfoStruct *)(arg))->UserData);
str = (DenseFDThreadStruct *)(((MultiThreaderBase::WorkUnitInfo *)(arg))->UserData);
// Execute the actual method with appropriate output region
// first find out how many pieces extent can be split into.
......@@ -205,7 +204,7 @@ DenseFiniteDifferenceImageFilter2<TInputImage, TOutputImage>
str->ValidTimeStepList[threadId] = true;
}
return ITK_THREAD_RETURN_VALUE;
return ITK_THREAD_RETURN_DEFAULT_VALUE;
}
template <class TInputImage, class TOutputImage>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment