# ITKElastix: SetNumberOfThreads() segfaults with bspline parameter map

**URL:** https://discourse.itk.org/t/itkelastix-setnumberofthreads-segfaults-with-bspline-parameter-map/6650
**Category:** Engineering
**Tags:** python
**Created:** [May 21, 2024, 7:44am UTC](https://discourse.itk.org/t/itkelastix-setnumberofthreads-segfaults-with-bspline-parameter-map/6650 "2024-05-21T07:44:31Z")
**Posts on this page:** 3
**Page:** 1

<div class="post-metadata">

### Author: ![Pieter-VB](https://discourse.itk.org/user_avatar/discourse.itk.org/pieter-vb/32/4069_2.png) [@Pieter-VB](https://discourse.itk.org/u/Pieter-VB)
#### Post date: [May 21, 2024, 7:44am UTC](https://discourse.itk.org/t/itkelastix-setnumberofthreads-segfaults-with-bspline-parameter-map/6650/1 "2024-05-21T07:44:31Z")

</div>

When increasing the number of threads (\> 1) of the itk.ElastixRegistrationMethod, the registration method segfaults when using the bspline default parameter map.  
This already fails with the given example: [bspline example](https://github.com/InsightSoftwareConsortium/ITKElastix/blob/main/examples/ITK_UnitTestExample3_BsplineRegistration.ipynb)

Code to change:

```auto
// Call registration function
elastix_object = itk.ElastixRegistrationMethod.New(fixed_image_bspline, moving_image_bspline)
elastix_object.SetParameterObject(parameter_object)
elastix_object.SetLogToConsole(True)
elastix_object.SetNumberOfThreads(8) # DOESNT WORK WITH BSPLINE
elastix_object.SetOutputDirectory("output")
elastix_object.UpdateLargestPossibleRegion()

result_image_bspline = elastix_object.GetOutput()
result_transform_parameters = elastix_object.GetTransformParameterObject()

//result_image_bspline, result_transform_parameters = itk.elastix_registration_method(
// fixed_image_bspline, moving_image_bspline,
// parameter_object=parameter_object,
// log_to_console=True)

```

Even when lowering the MaximumNumberOfSamplingAttempts (as it suggests), it still segfaults.

Output:

> WARNING: The parameter “FixedInternalImagePixelType”, requested at entry number 0, does not exist at all.  
> The default value “float” is used instead.  
> WARNING: The parameter “MovingInternalImagePixelType”, requested at entry number 0, does not exist at all.  
> The default value “float” is used instead.  
> Installing all components.  
> InstallingComponents was successful.
> 
> ELASTIX version: 5.1.0  
> Command line options from ElastixBase:  
> -out output/  
> -threads 8  
> WARNING: The parameter “UseDirectionCosines”, requested at entry number 0, does not exist at all.  
> The default value “true” is used instead.
> 
> WARNING: The option “UseDirectionCosines” was not found in your parameter file.  
> From elastix 4.8 it defaults to true!  
> This may change the behavior of your registrations considerably.
> 
> Command line options from TransformBase:  
> -t0 unspecified, so no initial transform used  
> WARNING: The parameter “BSplineTransformSplineOrder”, requested at entry number 0, does not exist at all.  
> The default value “3” is used instead.  
> WARNING: The parameter “UseCyclicTransform”, requested at entry number 0, does not exist at all.  
> The default value “false” is used instead.
> 
> Reading images…  
> Reading images took 0 ms.
> 
> WARNING: the fixed pyramid schedule is not fully specified!  
> A default pyramid schedule is used.  
> WARNING: the moving pyramid schedule is not fully specified!  
> A default pyramid schedule is used.  
> Initialization of all components (before registration) took: 0 ms.  
> Preparation of the image pyramids took: 4 ms.
> 
> Resolution: 0  
> WARNING: The parameter “ShowExactMetricValue”, requested at entry number 0, does not exist at all.  
> The default value “false” is used instead.  
> WARNING: The parameter “UseMultiThreadingForMetrics”, requested at entry number 0, does not exist at all.  
> The default value “true” is used instead.  
> WARNING: The parameter “ShowExactMetricValue”, requested at entry number 0, does not exist at all.  
> The default value “false” is used instead.  
> WARNING: The parameter “UseMultiThreadingForMetrics”, requested at entry number 0, does not exist at all.  
> The default value “true” is used instead.  
> Setting the fixed masks took: 0 ms.  
> Setting the moving masks took: 0 ms.  
> WARNING: The parameter “UseRelativeWeights”, requested at entry number 0, does not exist at all.  
> The default value “false” is used instead.  
> WARNING: The parameter “FixedImageBSplineInterpolationOrder”, requested at entry number 0, does not exist at all.  
> The default value “1” is used instead.  
> WARNING: The parameter “UseRandomSampleRegion”, requested at entry number 0, does not exist at all.  
> The default value “false” is used instead.  
> WARNING: The parameter “NumberOfHistogramBins”, requested at entry number 0, does not exist at all.  
> The default value “32” is used instead.  
> WARNING: The parameter “NumberOfFixedHistogramBins”, requested at entry number 0, does not exist at all.  
> The default value “32” is used instead.  
> WARNING: The parameter “NumberOfMovingHistogramBins”, requested at entry number 0, does not exist at all.  
> The default value “32” is used instead.  
> WARNING: The parameter “FixedLimitRangeRatio”, requested at entry number 0, does not exist at all.  
> The default value “0.01” is used instead.  
> WARNING: The parameter “MovingLimitRangeRatio”, requested at entry number 0, does not exist at all.  
> The default value “0.01” is used instead.  
> WARNING: The parameter “FixedKernelBSplineOrder”, requested at entry number 0, does not exist at all.  
> The default value “0” is used instead.  
> WARNING: The parameter “MovingKernelBSplineOrder”, requested at entry number 0, does not exist at all.  
> The default value “3” is used instead.  
> WARNING: The parameter “UseFastAndLowMemoryVersion”, requested at entry number 0, does not exist at all.  
> The default value “true” is used instead.  
> WARNING: The parameter “UseJacobianPreconditioning”, requested at entry number 0, does not exist at all.  
> The default value “false” is used instead.  
> WARNING: The parameter “FiniteDifferenceDerivative”, requested at entry number 0, does not exist at all.  
> The default value “false” is used instead.  
> WARNING: The parameter “NumberOfSamplesForSelfHessian”, requested at entry number 0, does not exist at all.  
> The default value “100000” is used instead.  
> WARNING: The parameter “SP\_A”, requested at entry number 0, does not exist at all.  
> The default value “20” is used instead.
> 
> WARNING: You have set MaximumNumberOfSamplingAttempts to 8.  
> This functionality is known to cause problems (stack overflow) for large values.  
> If elastix stops or segfaults for no obvious reason, reduce this value.  
> You may select the RandomSparseMask image sampler to fix mask-related problems.
> 
> WARNING: The parameter “SigmoidInitialTime”, requested at entry number 0, does not exist at all.  
> The default value “0” is used instead.  
> WARNING: The parameter “MaxBandCovSize”, requested at entry number 0, does not exist at all.  
> The default value “192” is used instead.  
> WARNING: The parameter “NumberOfBandStructureSamples”, requested at entry number 0, does not exist at all.  
> The default value “10” is used instead.  
> WARNING: The parameter “UseAdaptiveStepSizes”, requested at entry number 0, does not exist at all.  
> The default value “true” is used instead.  
> WARNING: The parameter “UseConstantStep”, requested at entry number 0, does not exist at all.  
> The default value “false” is used instead.  
> WARNING: The parameter “MaximumStepLengthRatio”, requested at entry number 0, does not exist at all.  
> The default value “1” is used instead.  
> WARNING: The parameter “MaximumStepLength”, requested at entry number 0, does not exist at all.  
> The default value “1” is used instead.  
> WARNING: The parameter “NumberOfGradientMeasurements”, requested at entry number 0, does not exist at all.  
> The default value “0” is used instead.  
> WARNING: The parameter “NumberOfJacobianMeasurements”, requested at entry number 0, does not exist at all.  
> The default value “1000” is used instead.  
> WARNING: The parameter “SigmoidScaleFactor”, requested at entry number 0, does not exist at all.  
> The default value “0.1” is used instead.  
> Elastix initialization of all components (for this resolution) took: 0 ms.  
> Initialization of AdvancedMattesMutualInformation metric took: 1 ms.  
> Initialization of TransformBendingEnergy metric took: 0 ms.  
> Starting automatic parameter estimation for AdaptiveStochasticGradientDescent …  
> WARNING: The parameter “ASGDParameterEstimationMethod”, requested at entry number 0, does not exist at all.  
> The default value “Original” is used instead.  
> Computing JacobianTerms …  
> Computing the Jacobian terms took 0.005527s  
> NumberOfGradientMeasurements to estimate sigma\_i: 3  
> Sampling gradients …  
> Segmentation fault (core dumped)

---

<div class="post-metadata">

### Author: ![Pieter-VB](https://discourse.itk.org/user_avatar/discourse.itk.org/pieter-vb/32/4069_2.png) [@Pieter-VB](https://discourse.itk.org/u/Pieter-VB)
#### Post date: [May 21, 2024, 7:49am UTC](https://discourse.itk.org/t/itkelastix-setnumberofthreads-segfaults-with-bspline-parameter-map/6650/2 "2024-05-21T07:49:08Z")

</div>

Full code to reproduce:

```py
import itk
import numpy as np
import matplotlib.pyplot as plt

def image_generator(x1, x2, y1, y2, bspline=False):
    image = np.zeros([100, 100], np.float32)
    for x in range(x1, x2):
        for y in range(y1, y2):
            if bspline:
                y += x
                if x > 99 or y > 99:
                    pass
                else:
                    image[y, x] = 1
            else:
                image[y, x] = 1
    image = itk.image_view_from_array(image)
    return image

# Create test images
fixed_image_bspline = image_generator(25,65,25,65)
moving_image_bspline = image_generator(5,55,5,40, bspline=True)

# Import Default Parameter Map
parameter_object = itk.ParameterObject.New()
default_affine_parameter_map = parameter_object.GetDefaultParameterMap('affine',4)
default_affine_parameter_map['FinalBSplineInterpolationOrder'] = ['1']
#parameter_object.AddParameterMap(default_affine_parameter_map)
default_bspline_parameter_map = parameter_object.GetDefaultParameterMap('bspline',4)
default_bspline_parameter_map['FinalBSplineInterpolationOrder'] = ['1']
parameter_object.AddParameterMap(default_bspline_parameter_map)
#parameter_object.SetParameter("MaximumNumberOfSamplingAttempts", "2") 

# Call registration function
elastix_object = itk.ElastixRegistrationMethod.New(fixed_image_bspline, moving_image_bspline)
elastix_object.SetParameterObject(parameter_object)
elastix_object.SetLogToConsole(True)
elastix_object.SetNumberOfThreads(8) # DOESNT WORK WITH BSPLINE
elastix_object.SetOutputDirectory("output")
elastix_object.UpdateLargestPossibleRegion() # REQUIRED

result_image_bspline = elastix_object.GetOutput()
result_transform_parameters = elastix_object.GetTransformParameterObject()

#result_image_bspline, result_transform_parameters = itk.elastix_registration_method(
# fixed_image_bspline, moving_image_bspline,
# parameter_object=parameter_object,
# log_to_console=True)

# Load Transformix Object
transformix_object = itk.TransformixFilter.New(moving_image_bspline)
transformix_object.SetTransformParameterObject(result_transform_parameters)

# Update object (required)
transformix_object.UpdateLargestPossibleRegion()

# Results of Transformation
result_image_transformix = transformix_object.GetOutput()

# Plot images
fig, axs = plt.subplots(1,4, sharey=True, figsize=[30,30])
plt.figsize=[100,100]
axs[0].imshow(result_image_bspline)
axs[0].set_title('Result', fontsize=30)
axs[1].imshow(fixed_image_bspline)
axs[1].set_title('Fixed', fontsize=30)
axs[2].imshow(moving_image_bspline)
axs[2].set_title('Moving', fontsize=30)
axs[3].imshow(result_image_transformix)
axs[3].set_title('Transformix', fontsize=30)
plt.show()

```

---

<div class="post-metadata">

### Author: ![Pieter-VB](https://discourse.itk.org/user_avatar/discourse.itk.org/pieter-vb/32/4069_2.png) [@Pieter-VB](https://discourse.itk.org/u/Pieter-VB)
#### Post date: [May 21, 2024, 9:06am UTC](https://discourse.itk.org/t/itkelastix-setnumberofthreads-segfaults-with-bspline-parameter-map/6650/3 "2024-05-21T09:06:08Z")

</div>

I did some further testing and yes the multithreading works with the elastix binary (version 5.1.0) through the commandline for the default bspline parameter map.  
It doesnt work with the itk-elastix pip package (version 0.19.2).
