VTK/Threaded Image Algorithms
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:
- How large the entire data set is (the WHOLE_EXTENT).
- 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.