View Issue Details Jump to Notes ] Print ]
IDProjectCategoryView StatusDate SubmittedLast Update
0010776ITKpublic2010-05-28 15:312010-11-10 15:02
ReporterBradley Lowekamp 
Assigned ToJim Miller 
PrioritynormalSeverityminorReproducibilityhave not tried
StatusassignedResolutionopen 
PlatformOSOS Version
Product Version 
Target VersionFixed in Version 
Summary0010776: Pipeline's excessive GenerateOutputInformation causes unnecessary GenerateData
Description
This bug I found causes the pipeline to re-executed under "normal" (non-streaming, non-release data, non-inplace, aka normal) situations. I have attached an example which shows the problem I have discovered. The output is as follows:

--------------- First Update ---------------
-------- Start ShrinkImageFilter "shrinking" ShrinkImageFilter (0x1015b3660)
Progress | 0 | ... 0.994886 | 1
Filter took 0.000846148 seconds.
-------- End ShrinkImageFilter "shrinking"
I0: 223
F0: 10
I1: 227
F1: 23
I2: 231
F2: 41
--------------- Second UpdateOutputInformation ( no modification should occour )---------------
I0: 223
F0: 10
I1: 235 [<- modified!]
F1: 23
I2: 231
F2: 41
--------------- Second Update ( no generation should occour )---------------
-------- Start ShrinkImageFilter "shrinking" ShrinkImageFilter (0x1015b3660)
Progress | 0 ... 0.994886 | 1
Filter took 0.000789046 seconds.
-------- End ShrinkImageFilter "shrinking"



This shows that the GenerateOutputInformation is executed a second time, and modifies the output of the shrink image filter. This then causes the remaining pipeline to re-execute! Because no parameters are changed, ProcessObject::GenerateOutputInformation was not expected to be executed.

Why is it executed?
The answer lies in ProcessObject::UpdateOutputInformation. This method essentially compares the modified time of the input, to the time the GenerateOutputInformation was last called. The GenerateData methods are called after the UpdateOutputInformation phase of the pipeline, which means that after an "Update" ProcessObject::m_OutputInformationMTime is always less then the input's modified time ( if the input was connected to a filter which previously execute). This means that all pipelined ImageToImage filters always call ProcessObject::GenerateOutputInformation for every pipeline Update!

Why is this not always a problem?
The default implementation of ImageToImageFilter::GenerateOutputInformation copies the input information to the output. The first time this methods is executed it sets the correct information, and modifies the time. However, the second time the smart set methods, notices the current value matches the value to be set, and does not modify the time. Therefore, filters who use the default implementation of GenerateOutputInformation do not exhibit this bug.

Which ones do?
The filters who call Superclass::GenerateOutputInformation, and then change the values. Because these filters set the output information to the input, then change the value to an internally calculated one, the output will be modified. Causing the pipeline to be re-executed! The ShrinkImageFilter is one example, many of the filters which change spacing or size will cause this issue as well.

Solutions?
I see two approaches. 1) Don't let the methods be executed excessively. This would likely require a output information time stamp in DataObjects. 2) Don't let the GenerateOutputInformation methods change the time if not needed. I could envision some type of save current output information, set new stuff, then if it didn't change set the old modified time.


I think solution #1 is better. It does assume that the output information only depends on other output information.



Thoughts on if this is really a bug, if you think that the GenerateOutputInformation should usually be called or other views are appreciated!


Brad
TagsNo tags attached.
Resolution Date
Sprint
Sprint Status
Attached Filescxx file icon itkGenerateOutputInformationTest1.cxx [^] (3,276 bytes) 2010-05-28 15:31

 Relationships

  Notes
(0020873)
Dzenan Zukic (developer)
2010-05-31 08:07

I might be running into the same problem with a different filter, but in my case that causes crash.

typedef itk::TriangleMeshToSimplexMeshFilter<MeshType,SimplexType> triangle2simplexType;
typedef itk::SimplexMeshToTriangleMeshFilter<SimplexType,MeshType> simplex2triangeType;
typedef itk::DeformableSimplexMesh3DFilter<SimplexType,SimplexType> deformableSimplexType;

MeshType::Pointer mesh, dMesh;
SimplexType::Pointer sMesh;

mesh=qe2itkMesh(qe);
triangle2simplexType::Pointer t2simplex=triangle2simplexType::New();
t2simplex->SetInput(mesh);
//t2simplex->Update();
sMesh=t2simplex->GetOutput();

deformableSimplexType::Pointer defSimplex=deformableSimplexType::New();
defSimplex->SetGradient(gradientMapFilter->GetOutput());
defSimplex->SetInput(sMesh);
defSimplex->SetIterations(100);
//defSimplex->Update();
sMesh=defSimplex->GetOutput();

simplex2triangeType::Pointer simplex2t=simplex2triangeType::New();
simplex2t->SetInput(sMesh);
simplex2t->Update();
dMesh=simplex2t->GetOutput();

If I uncomment the two updates above, the program crashes in \InsightToolkit-3.18.0\Code\BasicFilters\itkTriangleMeshToSimplexMeshFilter.txx, on line 95, during second execution of that filter (when second update is called). Furthermore, on line 97 of itkTriangleMeshToSimplexMeshFilter.txx there is a misspelling (tp[0] instead of tp[2]) which can cause confusion.
(0023028)
Hans Johnson (developer)
2010-11-07 08:55

Brad,

Could you please find somebody willing to take ownership of this task, and then assign it to them?

Thanks,
Hans
(0023150)
Bradley Lowekamp (developer)
2010-11-10 15:02

Jim,

It looks like I wrote a long description an included a test for this issue. And came up with two solutions to the issue. I am wondering how you think this should be solved the best.

Brad

 Issue History
Date Modified Username Field Change
2010-05-28 15:31 Bradley Lowekamp New Issue
2010-05-28 15:31 Bradley Lowekamp File Added: itkGenerateOutputInformationTest1.cxx
2010-05-31 08:07 Dzenan Zukic Note Added: 0020873
2010-11-07 08:54 Hans Johnson Status new => assigned
2010-11-07 08:54 Hans Johnson Assigned To => Bradley Lowekamp
2010-11-07 08:55 Hans Johnson Note Added: 0023028
2010-11-10 14:59 Bradley Lowekamp Assigned To Bradley Lowekamp => Jim Miller
2010-11-10 15:02 Bradley Lowekamp Note Added: 0023150


Copyright © 2000 - 2018 MantisBT Team