Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Unable to run example notebooks #52

Closed
llangholz89 opened this issue Jul 30, 2020 · 27 comments
Closed

Unable to run example notebooks #52

llangholz89 opened this issue Jul 30, 2020 · 27 comments
Assignees

Comments

@llangholz89
Copy link

llangholz89 commented Jul 30, 2020

Attempting to run the example notebooks causes the kernel to die when executing the registration step.

After running into issues attempting my own registrations, I gave the examples a try without any luck. Not sure that the issues are necessarily related, but figured I'd start here with the examples.

I'm using the python package for itk: itk 5.1.0.post3 (<-- perhaps this is the issue???) and the most recent ITKElastix (0.6.2).

Perhaps I'm missing something simple, but any help, tips, or guidance is appreciated! Thanks!

@thewtex
Copy link
Member

thewtex commented Aug 6, 2020

@llangholz89 there is a known issue with the current NumPy notebook and ITKElastix, 0.6.2 -- is this the issue you are encountering?

@llangholz89
Copy link
Author

@thewtex I'm not familiar with the issue you're referencing, but as I've encountered this issue on the other notebooks as well I'd guess it's probably not the same. Looking at the elastic output logs, it seems that the registration process actually completes, but then hangs when trying to write out or return the resulting image (this was the case on the notebook examples and on my attempts with my own data, though attempts to write out intermediate images in my own example worked...).

I thought perhaps it could be related to #51??

@thewtex
Copy link
Member

thewtex commented Aug 12, 2020

@llangholz89 the notebook and itk-elastix has been updated. Please try itk-elastix-0.6.3 or newer.

@thewtex thewtex closed this as completed Aug 12, 2020
@llangholz89
Copy link
Author

@thewtex thanks for the update. Unfortunately I'm still seeing the same behavior. Across each of the example notebooks (and my own attempts), things crash during the itk.elastix_registration_method(...) call. This is using the latest versions (itk 5.1.1 and itk-elastix 0.6.3).

Perhaps there's something else I'm missing, because the examples seem to work fine for you, correct?

If there's a relevant log or something else you'd like me to try, let me know!

@thewtex thewtex reopened this Aug 13, 2020
@thewtex
Copy link
Member

thewtex commented Aug 13, 2020

@llangholz89 thanks for the follow-up note.

Yes, the examples are working fine for me locally, and they are tested with every change following #54

I am wondering if there is something different with your system -- what is your operating system, Python version, Python distribution, and processor?

@llangholz89
Copy link
Author

Strange...
I'm on macOS High Sierra 1013.6, using python 3.7.3 through pyenv, and 2.5 GHz Intel Core i7 processor.

@llangholz89
Copy link
Author

As a follow up, I tried running the same registration presented in the HelloRegistrationWorld notebook in a regular python session. The code was very simple:

import itk

fixed_img = itk.imread('./data/CT_2D_head_fixed.mha', itk.F)
moving_img = itk.imread('./data/CT_2D_head_moving.mha', itk.F)
log_file = 'log.txt'
reg_img, params = itk.elastix_registration_method(fixed_img, moving_img, log_to_file=True, log_file_name=log_file, output_directory='.')

And get a Segmentation fault: 11 error

Looking at the output log, it seems like everything completed and processed as expected. I'll skip most of it, but the last few lines read:

Time spent in resolution 3 (ITK initialization and iterating): 0.388 s.
Stopping condition: Maximum number of iterations has been reached.
Settings of AdaptiveStochasticGradientDescent in resolution 3:
( SP_a 129.121309 )
( SP_A 20.000000 )
( SP_alpha 1.000000 )
( SigmoidMax 1.000000 )
( SigmoidMin -0.595049 )
( SigmoidScale 0.000136 )

From what I can tell it processes fine, but does not return correctly. In fact, I tried adjusting the parameters to write intermediate images, and those get produced just fine as well.

Maybe you have some ideas on what could be causing the seg fault?

@ViktorvdValk
Copy link
Collaborator

The segfault is a Mac issue, a workaround can be found in the newly added notebooks, but a fix for the segfault is still in progress.

@dvdm
Copy link

dvdm commented Oct 7, 2020

I have the same issue running MacOS 10.15.7 (Catalina). Within Jupyter Notebook, the kernel gets restarted once calling the registration module. Running as a regular python file results in a segmentation fault.

You mentioned a workaround, but where do I find it?

@ViktorvdValk
Copy link
Collaborator

ViktorvdValk commented Oct 7, 2020

@dvdm
Copy link

dvdm commented Oct 7, 2020

@ViktorvdValk : Thanks for the prompt reply. I had only tested the0_HelloRegistrationWorld.ipynb notebook which does not contain the important import statement

from itk import itkElastixRegistrationMethodPython

which makes it running on MacOS.
With this import statement added at the beginning, all seems to run fine!

@thewtex
Copy link
Member

thewtex commented Nov 9, 2020

For more information, and a script to run on the Python package binaries and elastix, see the commit messages in:

@ViktorvdValk
Copy link
Collaborator

The segmentation fault is triggered by the Update() and UpdateLargestPossibleRegion() functions of the itk.ElastixRegistrationMethod, these are inherited from the iktProcessObject. In the Update() functions the GetPrimaryOutput function is called, which returns a DataObject.
In ITK the DataObject class has this macro: "class ITK_FORCE_EXPORT_MACRO(ITKCommon) DataObject : public Object"
And the itkProcessObject class has this macro: "class ITKCommon_EXPORT ProcessObject : public Object"

However in the itkDataObject.h the classes are given this macro aswell:
"// Forward reference because of circular dependencies
class ITK_FORWARD_EXPORT ProcessObject;
class ITK_FORWARD_EXPORT DataObject;"

Could this be the reason for the segfault on macos? Should these classes have the macro ITK_TEMPLATE_EXPORT aswell?

@thewtex
Copy link
Member

thewtex commented Dec 7, 2020

👍 good progress.

A few next steps:

@ViktorvdValk
Copy link
Collaborator

The full backtrace of the segfault with lldb gives this:

2020-12-28 10:29:23.448298+0100 python[1300:29062] dynamic_cast error 1: Both of the following type_info's should have public visibility. At least one of them is hidden. N3itk10DataObjectE, N3itk5ImageIfLj2EEE.
2020-12-28 10:29:23.448362+0100 python[1300:29062] dynamic_cast error 2: One or more of the following type_info's has hidden visibility or is defined in more than one translation unit. They should all have public visibility. N3itk10DataObjectE, N3itk5ImageIfLj2EEE, N3itk9ImageBaseILj2EEE.
etc .......

The complete list of type info's that should have public visibility for regular registration (Euler Transform) call is the following:

N3itk10DataObjectE
N3itk5ImageIfLj2EEE
N3itk9ImageBaseILj2EEE
N3itk6ObjectE

N7elastix21EulerTransformElastixINS_15ElastixTemplateIN3itk5ImageIfLj2EEES4_EEEE
N7elastix13TransformBaseINS_15ElastixTemplateIN3itk5ImageIfLj2EEES4_EEEE
N7elastix27BSplineResampleInterpolatorINS_15ElastixTemplateIN3itk5ImageIfLj2EEES4_EEEE
N7elastix24ResampleInterpolatorBaseINS_15ElastixTemplateIN3itk5ImageIfLj2EEES4_EEEE
N7elastix21FixedSmoothingPyramidINS_15ElastixTemplateIN3itk5ImageIfLj2EEES4_EEEE
N7elastix21FixedImagePyramidBaseINS_15ElastixTemplateIN3itk5ImageIfLj2EEES4_EEEE.

This would mean that it's both ITK and Elastix that lack the public visibility, right?

My attempts of improving this visibility in both ITK and Elastix haven't been fruitful so far, but I'll keep on debugging.
Suggestions are welcome.

@ViktorvdValk
Copy link
Collaborator

ViktorvdValk commented Jan 5, 2021

thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
frame #0: 0x00000001192e3c2c _ElastixPython.so___lldb_unnamed_symbol14569$$_ElastixPython.so + 156
frame #1: 0x00000001192e362c _ElastixPython.so___lldb_unnamed_symbol14568$$_ElastixPython.so + 540
frame #2: 0x00000001192563b8 _ElastixPython.so___lldb_unnamed_symbol13727$$_ElastixPython.so + 760
frame #3: 0x0000000119252f80 _ElastixPython.so___lldb_unnamed_symbol13719$$_ElastixPython.so + 2352
frame #4: 0x000000011923ac4d _ElastixPython.soelastix::ElastixMain::Run() + 3741
frame #5: 0x00000001189c9aae _ElastixPython.so___lldb_unnamed_symbol784$$_ElastixPython.so + 6990
frame #6: 0x0000000118ba3766 _ElastixPython.soitk::ProcessObject::UpdateOutputData(itk::DataObject*) + 262
frame #7: 0x000000010d28626b _ITKCommonPython.so___lldb_unnamed_symbol8760$$_ITKCommonPython.so + 58
frame #8: 0x000000010002c843 python_PyMethodDef_RawFastCallKeywords + 131
frame #9: 0x000000010002c1e6 python_PyObject_FastCallKeywords + 598
frame #10: 0x0000000100164a87 pythoncall_function + 455
frame #11: 0x000000010015c4c4 python_PyEval_EvalFrameDefault + 20180
frame #12: 0x0000000100155dc4 python_PyEval_EvalCodeWithName + 532
frame #13: 0x000000010002c5eb python_PyFunction_FastCallKeywords + 395
frame #14: 0x0000000100164977 pythoncall_function + 183
frame #15: 0x000000010015c43b python_PyEval_EvalFrameDefault + 20043
frame #16: 0x0000000100155dc4 python_PyEval_EvalCodeWithName + 532
frame #17: 0x000000010002aafc python_PyFunction_FastCallDict + 444
frame #18: 0x000000010015cdf7 python_PyEval_EvalFrameDefault + 22535
frame #19: 0x0000000100155dc4 python_PyEval_EvalCodeWithName + 532
frame #20: 0x000000010002c5eb python_PyFunction_FastCallKeywords + 395
frame #21: 0x0000000100164977 pythoncall_function + 183
frame #22: 0x000000010015cd10 python_PyEval_EvalFrameDefault + 22304
frame #23: 0x0000000100155dc4 python_PyEval_EvalCodeWithName + 532
frame #24: 0x00000001001c1a0b pythonPyRun_FileExFlags + 235
frame #25: 0x00000001001c13d6 pythonPyRun_SimpleFileExFlags + 502
frame #26: 0x00000001001edd34 pythonpymain_run_file + 164
frame #27: 0x00000001001ed62b pythonpymain_run_filename + 123
frame #28: 0x00000001001ece11 pythonpymain_run_python + 145
frame #29: 0x00000001001eca8b pythonpymain_main + 27
frame #30: 0x00000001000016c9 pythonmain + 89
frame #31: 0x00007fff20363621 libdyld.dylibstart + 1

This is the lldb backtrace for the ITKElastix Debug build.
I also "set(CTEST_BUILD_CONFIGURATION "Debug")" to use a debug version of elastix as well.

Still some symbols are unnamed like:
'frame #7: 0x000000010d28626b _ITKCommonPython.so`___lldb_unnamed_symbol8760$$_ITKCommonPython.so + 58'

@thewtex these are part of ITK, right?

@thewtex
Copy link
Member

thewtex commented Jan 5, 2021

@thewtex these are part of ITK, right?

@ViktorvdValk correct. However, the CMake setting that should be set to Debug on the ITK build and the elastix build should be CMAKE_BUILD_TYPE as opposed to CTEST_BUILD_CONFIGURATION. This can help reveal more symbol names.

@thewtex
Copy link
Member

thewtex commented Jan 5, 2021

The full backtrace of the segfault with lldb gives this:

2020-12-28 10:29:23.448298+0100 python[1300:29062] dynamic_cast error 1: Both of the following type_info's should have public visibility. At least one of them is hidden. N3itk10DataObjectE, N3itk5ImageIfLj2EEE.
2020-12-28 10:29:23.448362+0100 python[1300:29062] dynamic_cast error 2: One or more of the following type_info's has hidden visibility or is defined in more than one translation unit. They should all have public visibility. N3itk10DataObjectE, N3itk5ImageIfLj2EEE, N3itk9ImageBaseILj2EEE.
etc .......

The complete list of type info's that should have public visibility for regular registration (Euler Transform) call is the following:

N3itk10DataObjectE
N3itk5ImageIfLj2EEE
N3itk9ImageBaseILj2EEE
N3itk6ObjectE

N7elastix21EulerTransformElastixINS_15ElastixTemplateIN3itk5ImageIfLj2EEES4_EEEE
N7elastix13TransformBaseINS_15ElastixTemplateIN3itk5ImageIfLj2EEES4_EEEE
N7elastix27BSplineResampleInterpolatorINS_15ElastixTemplateIN3itk5ImageIfLj2EEES4_EEEE
N7elastix24ResampleInterpolatorBaseINS_15ElastixTemplateIN3itk5ImageIfLj2EEES4_EEEE
N7elastix21FixedSmoothingPyramidINS_15ElastixTemplateIN3itk5ImageIfLj2EEES4_EEEE
N7elastix21FixedImagePyramidBaseINS_15ElastixTemplateIN3itk5ImageIfLj2EEES4_EEEE.

This would mean that it's both ITK and Elastix that lack the public visibility, right?

@ViktorvdValk great work!

I am not sure why it is complaining about the itk::DataObject, itk::Object, etc. visibility, because these are set.

The other symbols identify issues that we can correct.

These are symbols that encode the API of the human-readable source code into the binary. You can decode them with the c++filt CLI:

 ~ % echo N3itk10DataObjectE | c++filt
itk::DataObject
 ~ % echo N3itk5ImageIfLj2EEE | c++filt
itk::Image<float, 2u>
~ % echo N7elastix21EulerTransformElastixINS_15ElastixTemplateIN3itk5ImageIfLj2EEES4_EEEE | c++filt
elastix::EulerTransformElastix<elastix::ElastixTemplate<itk::Image<float, 2u>, itk::Image<float, 2u> > 

Checking some of these associated classes, they need the ITK_TEMPLATE_EXPORT macro added.

https://github.com/SuperElastix/elastix/blob/11b6cff38cbb6ef30808934f2ccdc36f4f1306b3/Components/Transforms/EulerTransform/elxEulerTransform.h#L73-L78

https://github.com/SuperElastix/elastix/blob/2c00aede07f94e67e8cbca2736651d3026197539/Core/Kernel/elxElastixTemplate.h#L105-L107

For an example of what to add:

https://github.com/InsightSoftwareConsortium/ITK/blob/4e0f6cae3dd3e0bf6738d6b9d2d12f80e725e229/Modules/Core/Common/include/itkImage.h#L85-L87

@ViktorvdValk
Copy link
Collaborator

Yes, I tried that on this branch of elastix, but running an ITKElastix package build with that branch gave exactly the same errors and backtrace.
I also tried including the same macro definition in the CMakeList.txt of elastix, but again I got the same errors and backtrace.
Also changing the dynamic casts in elxElastixTemplate.hxx to static casts, didn't change anything. @N-Dekker

@thewtex
Copy link
Member

thewtex commented Jan 11, 2021

including the same macro definition in the CMakeList.txt of elastix,

We should just re-use the ITK_TEMPLATE_EXPORT macro defined in itkMacro.h.

@ViktorvdValk
Copy link
Collaborator

Yes I re-used that macro in elxMacro.h (I tried using in in CMakelist.txt as well).

@thewtex
Copy link
Member

thewtex commented Jan 12, 2021

It does not need to be copied at all -- it is available in itkMacro.h.

@thewtex
Copy link
Member

thewtex commented Feb 24, 2021

@llangholz89 @dvdm please try itk-elastix==0.11.1 and let us know how it goes.

@thewtex
Copy link
Member

thewtex commented Mar 9, 2021

This should be addressed now -- if not, please open another issue.

@thewtex thewtex closed this as completed Mar 9, 2021
@llangholz89
Copy link
Author

@thewtex thanks for the update. I haven't had a chance to test it yet as I'm currently battling issues with pip not being able to find version 0.11.1 even though I can see it on PyPi (0.10.0 is the latest I can get). It's not mission critical for me right now, so I'll take your word for it and try to test again later when I've got time to figure out why I can't pull that version (if anyone has any ideas on this I'm all ears! So far I've just tried adding the --no-cache-dir flag but still no luck)

Thanks for the updates and the work on this though!

@thewtex
Copy link
Member

thewtex commented Mar 10, 2021

@llangholz89 thanks for the update.

Something to try for the pip issues -- upgrade the version of pip with pip install --upgrade pip.

@llangholz89
Copy link
Author

Thanks for the tip, unfortunately that did not work either... My colleague was able to pull it though, and I don't want to pollute this thread with problem solving pip issues, so I'll try to figure it out (I appreciate the help though!).

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants