[Insight-developers] Develop ITK : Why dynamic_cast should never be used in Generic Programming.
Luis Ibanez
luis.ibanez at kitware.com
Tue Jul 7 10:16:49 EDT 2009
Nikos,
1) What ImageMetric are you using ?
2) Do you have enabled the flag:
ITK_USE_OPTIMIZED_REGISTRATION_METHODS ?
If so,
you may be a victim of a mistake that was committed
in the ImageMetrics.
Inside the image metrics we are making the mistake
of using dynamic_cast in order to figure out when
the user is connecting a BSplineDeformable transform,
and in that case we treat that Transform differently.
Your renaming of the Transforms may be preventing
this dynamic_cast to succeed, and the code that has
been customized for BSplineDeformable transforms is
not being used in your case.
This exposes two errors in our current code:
* Violation of encapsulation:
The Metrics try to know too much about Transforms
* Violation of Generic Programming agnostic
The Metric should only rely on the API of
Transforms, instead of expecting them to
be of a specific type or hierarchy.
You will find the offending code at
Insight/Code/Review/
itkOptImageToImageMetric.txx
in lines 1371-1386:
m_TransformIsBSpline = true;
BSplineTransformType * testPtr2 = dynamic_cast<BSplineTransformType *>(
this->m_Transform.GetPointer() );
if( !testPtr2 )
{
m_TransformIsBSpline = false;
m_BSplineTransform = NULL;
itkDebugMacro( "Transform is not BSplineDeformable" );
}
else
{
m_BSplineTransform = testPtr2;
m_NumBSplineWeights = m_BSplineTransform->GetNumberOfWeights();
itkDebugMacro( "Transform is BSplineDeformable" );
}
This code, and all the subsequent "if( transform is BSpline )"
are improper use of generic programming and should be refactored.
The problem that you are facing illustrates one of the reasons
why Generic Programming SHOULD NOT use "dynamic_cast" at all.
Please log a bug on this issue at
http://public.kitware.com/Bug/my_view_page.php
In the short term,
you can get around this mistake in our code, by renaming
the type in line 419 of
Insight/Code/Review/
itkOptImageToImageMetric.h
Replace the declaration of that Transform with the one
that you are creating, and pay attention to its template
arguments. The type must be *identical*, (and that's
another of the handicaps introduced by dynamic_casting).
Thanks
Luis
-----------------------
Nikolaos Dikaios wrote:
> Hi Luis,
>
> Yes. When i include the renamed files (i attached in my previous
> message) it becomes significantly slower compared to when i include the
> original itk ones.
>
> Nikos
>
> On Mon, 2009-07-06 at 12:41 -0400, Luis Ibanez wrote:
>
>>Hi Nikos,
>>
>>
>>Are you saying that just renaming the classes
>>(without any other modification to their code)
>>results in a slowdown of the program ?
>>
>>
>>
>>Please confirm,
>>
>>
>> Thanks
>>
>>
>> Luis
>>
>>
>>--------------------
>>Nikolaos Dikaios wrote:
>>
>>>Hi Luis, Daniel
>>>
>>>I have attached the files i included, they are identical to the itk ones
>>>i simply renamed them from itkBSpline... to ip_BSpline....
>>>
>>>At this stage i haven't passed my code so there shouldn't be any
>>>inefficiencies. This is the reason i cannot explain why it has become so
>>>slow compared to when i used the itk ones.
>>>
>>>I'll try to run one of the profilers you suggested.
>>>
>>>Thank you very much for your help,
>>>
>>>Nikos
>>>
>>>PS. This is the build mode i use
>>>
>>>
>>>
>>>>>ccmake .
>>>
>>>
>>> CMAKE_BACKWARDS_COMPATIBILITY 2.4
>>> CMAKE_BUILD_TYPE Release
>>> CMAKE_INSTALL_PREFIX /usr/local
>>> EXECUTABLE_OUTPUT_PATH
>>> ITK_DIR ~/itk3.8
>>> LIBRARY_OUTPUT_PATH
>>>
>>>then
>>>
>>>
>>>
>>>>>make
>>>
>>>
>
>
More information about the Insight-developers
mailing list