TomographicImaging / CIL

A versatile python framework for tomographic imaging
https://tomographicimaging.github.io/CIL/
Apache License 2.0
98 stars 45 forks source link

CIL for MacOS (ARM) with astra-2.2.0 CPU #1973

Open epapoutsellis opened 2 weeks ago

epapoutsellis commented 2 weeks ago

Description

No Tigre, no Ipp, no ccpi-regularisation toolkit Related #1916

Example Usage

:heart: Thanks for your contribution!

epapoutsellis commented 2 weeks ago

There is a problem with numpy>=2.0. Running test_PluginsAstra_CPU.py, we get TypeError: Input type mismatch: got float32 expecting float64

In the code below, dtype changes from float32 to float64.

With numpy 2.0:

from cil.framework import AcquisitionGeometry
from cil.utilities.dataexample import SIMULATED_CONE_BEAM_DATA, SIMULATED_PARALLEL_BEAM_DATA
from cil.utilities.display import show2D
from cil.plugins.astra import ProjectionOperator
import numpy as np

data = SIMULATED_CONE_BEAM_DATA.get()
# data = SIMULATED_PARALLEL_BEAM_DATA.get()
data.log(out=data)
data *=-1
print(data.dtype)

data2D = data.get_slice(vertical="centre")
print(data2D.dtype)

returns

float32
float64

with numpy 1.26.4 py311h69ead2a_0 conda-forge

float32
float32

Running again all the tests with numpy 1.26, there is no error about dtypes, but there are errors (expected) with libcilacc. For example:

======================================================================
ERROR: test_process_data_container (test_DataProcessor.TestBinner.test_process_data_container)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/jovyan/work/test_DataProcessor.py", line 649, in test_process_data_container
    data_out = proc.process()
               ^^^^^^^^^^^^^^
  File "/opt/conda/lib/python3.11/site-packages/cil/processors/Slicer.py", line 431, in process
    self._process_data(data, data_out)
  File "/opt/conda/lib/python3.11/site-packages/cil/processors/Binner.py", line 183, in _process_data
    self._bin_array_acc(dc_in.array, dc_out.array)
  File "/opt/conda/lib/python3.11/site-packages/cil/processors/Binner.py", line 171, in _bin_array_acc
    binner_ipp = Binner_IPP(self._shape_in, self._shape_out_full, indices_start, bins)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/conda/lib/python3.11/site-packages/cil/processors/cilacc_binner.py", line 51, in __init__
    cilacc.Binner_new.argtypes = [c_size_t_p,c_size_t_p,c_size_t_p,c_size_t_p]
    ^^^^^^^^^^^^^^^^^
  File "/opt/conda/lib/python3.11/ctypes/__init__.py", line 389, in __getattr__
    func = self.__getitem__(name)
           ^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/conda/lib/python3.11/ctypes/__init__.py", line 394, in __getitem__
    func = self._FuncPtr((name_or_ordinal, self))
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: /opt/conda/lib/python3.11/lib-dynload/../../libcilacc.so: undefined symbol: Binner_new

There are also some precision errors:

======================================================================
FAIL: test_update (test_algorithms.TestCGLS.test_update)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/jovyan/work/test_algorithms.py", line 664, in test_update
    self.assertNumpyArrayEqual(self.alg.p.as_array(), ((self.data - self.initial-alpha*(self.data-self.initial))+beta*(self.data-self.initial)).as_array())
  File "/home/jovyan/work/testclass.py", line 56, in assertNumpyArrayEqual
    np.testing.assert_array_equal(first, second)
  File "/opt/conda/lib/python3.11/site-packages/numpy/testing/_private/utils.py", line 920, in assert_array_equal
    assert_array_compare(operator.__eq__, x, y, err_msg=err_msg,
  File "/opt/conda/lib/python3.11/contextlib.py", line 81, in inner
    return func(*args, **kwds)
           ^^^^^^^^^^^^^^^^^^^
  File "/opt/conda/lib/python3.11/site-packages/numpy/testing/_private/utils.py", line 797, in assert_array_compare
    raise AssertionError(msg)
AssertionError: 
Arrays are not equal

Mismatched elements: 5 / 20 (25%)
Max absolute difference: 5.9604645e-08
Max relative difference: 9.92183e-08
 x: array([[-0.505957, -0.873821, -0.403988, -0.50656 , -0.519976, -0.600742,
        -0.713493, -0.341544, -0.628265, -0.657714],
       [-0.339873, -0.422397, -0.77635 , -0.436359, -0.731622, -0.192571,
        -0.130996, -0.453709, -0.137646, -0.82563 ]], dtype=float32)
 y: array([[-0.505957, -0.873821, -0.403988, -0.50656 , -0.519976, -0.600742,
        -0.713493, -0.341544, -0.628265, -0.657714],
       [-0.339873, -0.422397, -0.77635 , -0.436359, -0.731622, -0.192571,
        -0.130996, -0.453709, -0.137646, -0.82563 ]], dtype=float32)

But also one Astra error

======================================================================
ERROR: test_AstraProjector2D_cpu (test_PluginsAstra_Projectors.TestAstraProjectors.test_AstraProjector2D_cpu)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/jovyan/work/test_PluginsAstra_Projectors.py", line 108, in test_AstraProjector2D_cpu
    A = AstraProjector2D(self.ig, self.ag, device = 'cpu')
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/conda/lib/python3.11/site-packages/cil/plugins/astra/operators/AstraProjector2D.py", line 54, in __init__
    self.fp = AstraForwardProjector2D(volume_geometry=image_geometry,
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/conda/lib/python3.11/site-packages/cil/plugins/astra/processors/AstraForwardProjector2D.py", line 71, in __init__
    self.set_projector(astra.create_projector('line', proj_geom, vol_geom) )
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/conda/lib/python3.11/site-packages/astra/creators.py", line 568, in create_projector
    return projector.create(cfg)
           ^^^^^^^^^^^^^^^^^^^^^
  File "/opt/conda/lib/python3.11/site-packages/astra/projector.py", line 36, in create
    return p.create(config)
           ^^^^^^^^^^^^^^^^
  File "astra/projector_c.pyx", line 68, in astra.projector_c.create
astra.log.AstraError: Unable to initialize Projector2D: Configuration error in Projector2D. VolumeGeometry not initialized.
paskino commented 2 weeks ago

Maybe the dtype problem is due to numpy.take

https://github.com/TomographicImaging/CIL/blob/5d569dc054759a8c137ca72611fc7be07be6080e/Wrappers/Python/cil/framework/data_container.py#L179

However, according to numpy's docs for both 1.26 and 2.0

the returned array has the same type as [the input]

@epapoutsellis can you please test the following:

from cil.framework import AcquisitionGeometry
from cil.utilities.dataexample import SIMULATED_CONE_BEAM_DATA, SIMULATED_PARALLEL_BEAM_DATA
from cil.utilities.display import show2D
from cil.plugins.astra import ProjectionOperator
import numpy as np

data = SIMULATED_CONE_BEAM_DATA.get()
print (f"Orig data dtype {data.array.dtype} {data.dtype} {data.geometry.dtype}")
data.log(out=data)
print (f"Log dtype {data.array.dtype} {data.dtype} {data.geometry.dtype}")
data *=-1
print (f"Minus 1 dtype {data.array.dtype} {data.dtype} {data.geometry.dtype}")

axis = data.dimension_labels_list.index("vertical")
slicearr = np.take(data.array, axis=axis, indices=0)
print (f"numpy take {slicearr.dtype}")

data2D = data.get_slice(vertical=0)
print(data2D.dtype)