VTK/Threaded Image Algorithms: Difference between revisions

From KitwarePublic
< VTK
Jump to navigationJump to search
No edit summary
Line 13: Line 13:
== Splitting the UPDATE_EXTENT among threads ==
== Splitting the UPDATE_EXTENT among threads ==


The algorithm is responsible for producing a vtkImageData object whose size and position within the entire data set described by the '''UPDATE_EXTENT'''.  But wait, what if we want to divide the work among several threads?  Then the '''UPDATE_EXTENT''' must be broken into several chunks, each of which is also an ''extent''.  For example, let's say that the update extent is  { <span style="color:#800000">128</span>, <span style="color:#800000">255</span>, <span style="color:#008000">0</span>, <span style="color:#008000">255</span>, <span style="color:#0000D0">1</span>, <span style="color:#8000D0">100</span> }:
The algorithm is responsible for producing a vtkImageData object whose size and position within the entire data set described by the '''UPDATE_EXTENT'''.  But wait, what if we want to divide the work among several threads?  Then the '''UPDATE_EXTENT''' must be broken into several chunks, each of which is also an ''extent''.  For example, let's say that the update extent is  { <span style="color:#800000">128</span>, <span style="color:#800000">255</span>, <span style="color:#008000">0</span>, <span style="color:#008000">255</span>, <span style="color:#0000E0">1</span>, <span style="color:#0000E0">100</span> }:


   UPDATE_EXTENT: { 128, 255, 0, 255, 1, 100 }
   UPDATE_EXTENT:     { 128, 255, 0, 255, 1, 100 }
   Thread 1 extent:  { 128, 255, 0, 255, 1, 25 }
   Thread 0 extent:  { 128, 255, 0, 255, 1, 25 }
   Thread 2 extent:  { 128, 255, 0, 255, 26, 50 }
   Thread 1 extent:  { 128, 255, 0, 255, 26, 50 }
   Thread 3 extent:  { 128, 255, 0, 255, 51, 75 }
   Thread 2 extent:  { 128, 255, 0, 255, 51, 75 }
   Thread 4 extent:  { 128, 255, 0, 255, 76, 100 }
   Thread 4 extent:  { 128, 255, 0, 255, 76, 100 }


In this example, the data has been divided along the Z direction.
In this example, the data has been divided along the Z direction.  There is, in fact, a specific method in vtkThreadedImageAlgorithm whose only responsibility is to split the data into pieces:
 
virtual int SplitExtent (int pieceExtent[6], int updateExtent[6], int piece, int total)
 
The ''total'' is the total number of pieces to divide the ''updateExtent'' into (this is always the number of threads to be used).  Each thread calls this SplitExtent method with ''piece'' set to a different number (in the above example, with numbers 0 through 3).  The SplitExtent method returns the the extent of data for that thread to operate on in the ''pieceExtent'' array.


== Multithreading ==
== Multithreading ==

Revision as of 04:40, 17 March 2015

Review of Streaming Pipeline

The job of a vtkAlgorithm is to perform some operation upon some data (specifically, upon some data encapsulated in a vtkDataObject). One important aspect of VTK's streaming pipeline is that the vtkDataObject that the algorithm operates on might be one part of a larger data set. For example, a vtkImageData object might only contain a few slices of a large stack of image slices.

The portion of a data set that is contained within one vtkImageData object is described by the Extent array, which provides a (first, last) index for each of the three dimensions:

Extent = { first_idx_x, last_idx_x, first_idx_y, last_idx_y, first_idx_z, last_idx_z }

The pipeline tells the algorithm two important pieces of information:

  1. How large the entire data set is (the WHOLE_EXTENT).
  2. What part of the data set the output vtkImageData object should contain after the algorithm runs (the UPDATE_EXTENT).

Splitting the UPDATE_EXTENT among threads

The algorithm is responsible for producing a vtkImageData object whose size and position within the entire data set described by the UPDATE_EXTENT. But wait, what if we want to divide the work among several threads? Then the UPDATE_EXTENT must be broken into several chunks, each of which is also an extent. For example, let's say that the update extent is { 128, 255, 0, 255, 1, 100 }:

 UPDATE_EXTENT:     { 128, 255, 0, 255, 1, 100 }
 Thread 0 extent:   { 128, 255, 0, 255, 1, 25 }
 Thread 1 extent:   { 128, 255, 0, 255, 26, 50 }
 Thread 2 extent:   { 128, 255, 0, 255, 51, 75 }
 Thread 4 extent:   { 128, 255, 0, 255, 76, 100 }

In this example, the data has been divided along the Z direction. There is, in fact, a specific method in vtkThreadedImageAlgorithm whose only responsibility is to split the data into pieces:

virtual int SplitExtent (int pieceExtent[6], int updateExtent[6], int piece, int total)

The total is the total number of pieces to divide the updateExtent into (this is always the number of threads to be used). Each thread calls this SplitExtent method with piece set to a different number (in the above example, with numbers 0 through 3). The SplitExtent method returns the the extent of data for that thread to operate on in the pieceExtent array.

Multithreading

Progress Reporting

Tricky Details

Future