[Insight-users] Resampling 64-bit crash

Florian Pierron F.Pierron at exeter.ac.uk
Thu Feb 15 05:12:25 EST 2007


Hi Robert,

Thank you for your tests.

I think I found the problem. I did a smaller test where I only try to 
allocate an image of 5 GB:

**********
  const     unsigned int   Dimension = 2;
  typedef   unsigned char  InputPixelType;
  typedef   unsigned char  OutputPixelType;
  typedef itk::Image< InputPixelType,  Dimension >   InputImageType;
  typedef itk::Image< OutputPixelType, Dimension >   OutputImageType;

  InputImageType::Pointer myImage = InputImageType::New ();

  InputImageType::IndexType index = {{0, 0}};
  InputImageType::SizeType  size;

  size[0] = 5 * 1000 * 1000;
  size[1] = 1 * 1000;

  InputImageType::RegionType region;
  region.SetIndex (index);
  region.SetSize (size);
  myImage->SetRegions (region);
  myImage->Allocate ();
**********

And here is my comments:
1) On my computer, sizeof (long) = 4 bytes. (Is there a way to tell the 
compiler to make it 8 bytes?)
2) When trying to allocate the image, myImage->Allocate () calls 
ImageBase<VImageDimension>::ComputeOffsetTable() and the variable num is 
declared as OffsetValueType num. This variable is used to store the size 
of the image which is 5GB (> 2^32) and OffsetValueType is a typedef of 
unsigned long. So that's one of the reason I couldn't allocate more than 
4 GB.
3) I changed the typedef of OffsetValueType in itkOffset.h file to long 
long to solve the problem above.
4) Then in Image::Allocate (), another num variable is declared as 
unsigned long, so I've changed it to unsigned long long.
5) Again in Image::Allocate (), there's a call to m_Buffer->Reserve(num) 
and the Reserve function is defined as ImportImageContainer< 
TElementIdentifier , TElement >::Reserve(ElementIdentifier size) where 
ElementIdentifier is templated as unsigned long, so I changed in itkImage.h:
typedef ImportImageContainer<unsigned long, PixelType> PixelContainer to 
be unsigned long long.

I was then able to allocate my image of 5GB ! :-) But unfortunately, 
when I try to run the previous example (resample 5 GB image), it still 
didn't work :-( So I think there are more changes to be done... Maybe if 
I find a way to tell the compile that I want long to be 8 bytes it could 
work... Is that possible with VC2005?

I think I will stop here for now.
Thanks to all of you for your help.
Regards,
Florian


On 14/02/2007 19:08, Atwood, Robert C wrote:
> Hmm. The follwing program does not crash, but the output size is a bit
> strange.
> Similar results obtained in real-3d with x=1000, y=m*1000, z=1000
>
> In my test prog, below, the size is multiplied by the 3rd command line
> argument.
>
> --Robert
>
>
> ./ResampleBig bshell176.png t.mhd 10
> -rw-r--r--  1 rcatwood staff8 1.4G Feb 14 18:46 t.raw
> -rw-r--r--  1 rcatwood staff8  260 Feb 14 18:46 t.mhd
>
> ./ResampleBig bshell176.png t.mhd 5
> -rw-r--r--  1 rcatwood staff8  259 Feb 14 18:50 t.mhd
> -rw-r--r--  1 rcatwood staff8 673M Feb 14 18:50 t.raw
>
> ./ResampleBig bshell176.png t.mhd 2
> -rw-r--r--  1 rcatwood staff8  259 Feb 14 18:54 t.mhd
> -rw-r--r--  1 rcatwood staff8 1.9G Feb 14 18:54 t.raw
>
> So, it does appear that the amount of data in the image gets weird for
> large sizes.
>
> Alarmingly, using 3 or 4 gives an empty file:
>
>  ./ResampleBig bshell176.png t.mhd 4
> -rw-r--r--  1 rcatwood staff8    0 Feb 14 19:00 t.raw
> -rw-r--r--  1 rcatwood staff8  278 Feb 14 19:00 t.mhd
>  itk_example_build]$ file t.raw
> t.raw: empty
>
>
> //BEGINNING of program .. Based on ResampleImageFilter.cxx example
> #if defined(_MSC_VER)
> #pragma warning ( disable : 4786 )
> #endif
> #ifdef __BORLANDC__
> #define ITK_LEAN_AND_MEAN
> #endif
> #include "itkImage.h"
> #include "itkImageFileReader.h"
> #include "itkImageFileWriter.h"
> #include "itkResampleImageFilter.h"
> #include "itkAffineTransform.h"
> #include "itkNearestNeighborInterpolateImageFunction.h"
> int main( int argc, char * argv[] )
> {
>   if( argc < 4 )
>     {
>     std::cerr << "Usage: " << std::endl;
>     std::cerr << argv[0] << "  inputImageFile  outputImageFile"; 
>     std::cerr << "  multiplier " << std::endl;
>     return EXIT_FAILURE;
>     }
>   int mul = 1;
>  
>   if( argc >= 4 )
>     {
>     mul = atoi( argv[3] );
>     }
>   const     unsigned int   Dimension = 2;
>   typedef   unsigned char  InputPixelType;
>   typedef   unsigned char  OutputPixelType;
>   typedef itk::Image< InputPixelType,  Dimension >   InputImageType;
>   typedef itk::Image< OutputPixelType, Dimension >   OutputImageType;
>   typedef itk::ImageFileReader< InputImageType  >  ReaderType;
>   typedef itk::ImageFileWriter< OutputImageType >  WriterType;
>   ReaderType::Pointer reader = ReaderType::New();
>   WriterType::Pointer writer = WriterType::New();
>   reader->SetFileName( argv[1] );
>   writer->SetFileName( argv[2] );
>   typedef itk::ResampleImageFilter<InputImageType,OutputImageType>
> FilterType;
>   FilterType::Pointer filter = FilterType::New();
>   
>   typedef itk::AffineTransform< double, Dimension >  TransformType;
>   TransformType::Pointer transform = TransformType::New();
>   filter->SetTransform( transform );
>   
>   typedef itk::NearestNeighborInterpolateImageFunction< 
>                        InputImageType, double >  InterpolatorType;
>   InterpolatorType::Pointer interpolator = InterpolatorType::New();
>   filter->SetInterpolator( interpolator );
>   filter->SetDefaultPixelValue( 0 );
>   double spacing[ Dimension ];
>   spacing[0] = 1.0; // pixel spacing in millimeters along X
>   spacing[1] = 1.0; // pixel spacing in millimeters along Y
>   filter->SetOutputSpacing( spacing );
>   double origin[ Dimension ];
>   origin[0] = 0.0;  // X space coordinate of origin
>   origin[1] = 0.0;  // Y space coordinate of origin
>   filter->SetOutputOrigin( origin );
>   InputImageType::SizeType   size;
>   size[0] = 1000 * 1000;  // number of pixels along X
>   size[1] = mul * 1000;  // number of pixels along Y
>   std::cout << " Size = " << size[0] * size [1] << std::endl;
>   std::cout << " Size : " << size << std::endl;
>   filter->SetSize( size );
>   std::cout << " Filter : " << filter << std::endl;
>   filter->SetInput( reader->GetOutput() );
>   writer->SetInput( filter->GetOutput() );
>    try{
>             writer->Update();
>           } catch(itk::ExceptionObject & e) {
>               std::cerr << "FAILED writer update: " << e << std::endl;
>               return EXIT_FAILURE;
>           }
>
>   return EXIT_SUCCESS;
> }
> //END of program
>
>   
>> -----Original Message-----
>> From: Florian Pierron [mailto:F.Pierron at exeter.ac.uk] 
>> Sent: 14 February 2007 15:11
>> To: Atwood, Robert C; insight-users at itk.org
>> Subject: Re: [Insight-users] Resampling 64-bit crash
>>
>> Hi Robert,
>>
>> Thank you for your quick reply.
>>
>> I haven't changed the dimension, I'm still in 2D. And it's 
>> working fine 
>> for me when size[0] * size[1] is less than 2 GB but not when 
>> it's more 
>> than 3-4 GB :-(. So if you can try to make it work with a 
>> size of 5 GB 
>> on your configuration, it would be really good / helpful!
>>
>> Regards,
>> Florian
>>
>>
>> On 14/02/2007 14:58, Atwood, Robert C wrote:
>>     
>>>  Maybe I am being dumb here, but did you change 'dimension' to 3 as
>>> well, or not? (Line 127)
>>>
>>>  I don't think you can set 3d dimensions for a 2d filter? Maybe this
>>> causes a compiler/OS dependent crash behaviour? If I do as you say
>>> exactly, I get failure on output with weird messages (but maybe  you
>>> can't put a 3d image in a png file!) 'Reason: Success' 
>>>       
>> seems like kind
>>     
>>> of a bad reason to abort.
>>>
>>>
>>> Using linux RedHat , but also AMD64 Dual core processors, 
>>>       
>> and 16 Gb of
>>     
>>> physical RAM. 
>>>
>>> [itk_example_build]$ ./ResampleBig BrainSliceBinary.png
>>> BrainSliceBinaryOutput.png 0
>>> terminate called after throwing an instance of 
>>>       
>> 'itk::ExceptionObject'
>>     
>>>   what():  /sources/local/ITK_cvs/Code/IO/itkPNGImageIO.cxx:503:
>>> itk::ERROR: PNGImageIO(0xa00520): Error while writing Slice to file:
>>> BrainSliceBinaryOutput.png
>>> Reason: Success
>>> Aborted
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>   
>>>       
>>>> -----Original Message-----
>>>> From: insight-users-bounces+r.atwood=imperial.ac.uk at itk.org 
>>>> [mailto:insight-users-bounces+r.atwood=imperial.ac.uk at itk.org]
>>>>  On Behalf Of Florian Pierron
>>>> Sent: 14 February 2007 14:06
>>>> To: insight-users at itk.org
>>>> Subject: [Insight-users] Resampling 64-bit crash
>>>>
>>>> Dear ITK users and developers,
>>>>
>>>> We need to resample big data and we decided to port our 
>>>> application in 
>>>> 64-bit version. We're currently working on Windows Server 2003, 
>>>> Enterprise x64 Edition, Dual Core AMD Opteron and using 
>>>> ITK-3-0 branch 
>>>> with VC2005. Unfortunately our application crashes when trying to 
>>>> resample big data.
>>>>
>>>> We reproduced the crash with the ResampleImageFilter example 
>>>> (D:\InsightToolkit-3.0.0\Examples\Filtering\ResampleImageFilte
>>>> r.cxx) by 
>>>> changing the size of the output image to be more than 3-4 GB:
>>>> Line 279:    size[0] = 5 * 1000 * 1000;  // number of 
>>>>         
>> pixels along X
>>     
>>>> Line 280:    size[1] = 1 * 1000;  // number of pixels along Y
>>>>
>>>> We run this example by setting the working directory to 
>>>> "D:\InsightToolkit-3.0.0\Testing\Data\Input" and the command line 
>>>> arguments to
>>>> "BrainSliceBinary.png BrainSliceBinaryOutput.png 0" (a 
>>>>         
>> random image I 
>>     
>>>> found in the ITK folder).
>>>>
>>>> 1) If I run this example with the modified size above (5 GB), 
>>>> it crashes 
>>>> immediately in:
>>>>
>>>>   /** Set the pixel. */
>>>>   inline void Set(TType & output, const TType & input) const
>>>>     {output = input;}
>>>>
>>>> with this call stack:
>>>>
>>>>      ResampleImageFilter.exe!itk::DefaultPixelAccessor<unsigned 
>>>> char>::Set(unsigned char & output=, const unsigned char & 
>>>> input=0)  Line 
>>>> 67 + 0x1d bytes
>>>>      
>>>> ResampleImageFilter.exe!itk::DefaultPixelAccessorFunctor<itk::
>>>> Image<unsigned 
>>>> char,2> >::Set(unsigned char & output=, const unsigned char & 
>>>> input=0)  
>>>> Line 77
>>>>      
>>>> ResampleImageFilter.exe!itk::ImageLinearIteratorWithIndex<itk:
>>>> :Image<unsigned 
>>>> char,2> >::Set(const unsigned char & value=0)  Line 106 + 
>>>>         
>> 0x47 bytes
>>     
>>>>      
>>>>
>>>>         
>> ResampleImageFilter.exe!itk::ResampleImageFilter<itk::Image<unsigned 
>>     
>>>> char,2>,itk::Image<unsigned 
>>>> char,2>,double>::LinearThreadedGenerateData(const 
>>>> itk::ImageRegion<2> & 
>>>> outputRegionForThread={...}, int threadId=2)  Line 481
>>>>      
>>>>
>>>>         
>> ResampleImageFilter.exe!itk::ResampleImageFilter<itk::Image<unsigned 
>>     
>>>> char,2>,itk::Image<unsigned 
>>>> char,2>,double>::ThreadedGenerateData(const 
>>>> itk::ImageRegion<2> & outputRegionForThread={...}, int 
>>>> threadId=2)  Line 192
>>>>      ResampleImageFilter.exe!itk::ImageSource<itk::Image<unsigned 
>>>> char,2> >::ThreaderCallback(void * arg=0x0000000002c2f4f8) 
>>>>         
>>  Line 282
>>     
>>>>      
>>>> ResampleImageFilter.exe!itk::MultiThreader::SingleMethodProxy(void 
>>>> * arg=0x0000000002c2f4f8)  Line 748
>>>>      msvcr80d.dll!_callthreadstartex()  Line 348 + 0x17 bytes
>>>>      msvcr80d.dll!_threadstartex(void * 
>>>> ptd=0x0000000002c3c8f0)  Line 331
>>>>
>>>>
>>>> 2) If I change the size to be 2GB, it's running fine. The 
>>>> limit between 
>>>> crashing and not crashing seems to be between 2 and 3 GB 
>>>> (with 8 threads).
>>>>
>>>> 3) If I force the SetNumberOfTheads to 1, it doesn't crash 
>>>> immediately 
>>>> (I think it crashes later, but it's quite slow so most of 
>>>>         
>> the time I 
>>     
>>>> killed it before). The funny thing is that when the number of 
>>>> threads is 
>>>> equal to 1:
>>>> - if the size is 4 GB, then 4 GB of memory is allocated immediately
>>>> - but if the size is 5 GB, only 700 MB is allocated
>>>> - for 7 GB, 2.65 GB is allocated
>>>> - for 10 GB, 1.4 GB is allocated (which is weirdly twice the 5GB)
>>>> I have no idea if this is meaningful at all, I was just 
>>>>         
>> wondering if 
>>     
>>>> there's a problem during memory allocation when the 4GB limit 
>>>> is reached...
>>>>
>>>>
>>>> Any ideas?
>>>>
>>>> Cheers,
>>>> Florian
>>>>
>>>> _______________________________________________
>>>> Insight-users mailing list
>>>> Insight-users at itk.org
>>>> http://www.itk.org/mailman/listinfo/insight-users
>>>>
>>>>     
>>>>         
>>>   
>>>       
> _______________________________________________
> Insight-users mailing list
> Insight-users at itk.org
> http://www.itk.org/mailman/listinfo/insight-users
>
>   


More information about the Insight-users mailing list