NSLS-II / PyXRF

Fluorescence fitting GUI.
http://nsls-ii.github.io/PyXRF
BSD 3-Clause "New" or "Revised" License
31 stars 23 forks source link

Fails with numba v0.56.x #288

Closed dmgav closed 2 years ago

dmgav commented 2 years ago

Numba is pinned to <0.56. The issue needs to be investigated.

The result of one of many failing tests (test_fit_xrf_block):

../../miniconda3/envs/pyxrf-dev-py310/lib/python3.10/site-packages/numba/core/dispatcher.py:409: TypingError
______________________________________________________________ test_fit_xrf_block[True-50-100-dataset_params0] ______________________________________________________________

dataset_params = {'n_data_dimensions': (8, 1)}, add_pts_before = 50, add_pts_after = 100, use_snip = True

    @pytest.mark.parametrize("dataset_params", [
        {"n_data_dimensions": (8, 1)},
        {"n_data_dimensions": (1, 8)},
        {"n_data_dimensions": (4, 4)},
        {"n_data_dimensions": (3, 5)},
    ])
    @pytest.mark.parametrize("add_pts_before, add_pts_after", [(0, 0), (50, 100)])
    @pytest.mark.parametrize("use_snip", [False, True])
    # fmt: on
    def test_fit_xrf_block(dataset_params, add_pts_before, add_pts_after, use_snip):

        ft = _FitXRFMapTesting(
            dataset_params=dataset_params,
            use_snip=use_snip,
            add_pts_before=add_pts_before,
            add_pts_after=add_pts_after,
        )

>       data_out = _fit_xrf_block(
            ft.data_input,
            data_sel_indices=ft.data_sel_indices,
            matv=ft.spectra,
            snip_param=ft.snip_param,
            use_snip=use_snip,
        )

pyxrf/core/tests/test_map_processing.py:851: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
pyxrf/core/map_processing.py:685: in _fit_xrf_block
    bg_sel = np.apply_along_axis(
<__array_function__ internals>:180: in apply_along_axis
    ???
../../miniconda3/envs/pyxrf-dev-py310/lib/python3.10/site-packages/numpy/lib/shape_base.py:379: in apply_along_axis
    res = asanyarray(func1d(inarr_view[ind0], *args, **kwargs))
../../miniconda3/envs/pyxrf-dev-py310/lib/python3.10/site-packages/numba/core/dispatcher.py:468: in _compile_for_args
    error_rewrite(e, 'typing')
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

e = TypingError('Failed in nopython mode pipeline (step: nopython frontend)\n\x1b[1m\x1b[1m\x1b[1mNo implementation of fun...   <source elided>\n    # smooth the background\n\x1b[1m    s = np.ones(con_val)\n\x1b[0m    \x1b[1m^\x1b[0m\x1b[0m\n')
issue_type = 'typing'

    def error_rewrite(e, issue_type):
        """
        Rewrite and raise Exception `e` with help supplied based on the
        specified issue_type.
        """
        if config.SHOW_HELP:
            help_msg = errors.error_extras[issue_type]
            e.patch_message('\n'.join((str(e).rstrip(), help_msg)))
        if config.FULL_TRACEBACKS:
            raise e
        else:
>           raise e.with_traceback(None)
E           numba.core.errors.TypingError: Failed in nopython mode pipeline (step: nopython frontend)
E           No implementation of function Function(<function ones at 0x7f6865b17e20>) found for signature:
E            
E            >>> ones(OptionalType(int64))
E            
E           There are 2 candidate implementations:
E             - Of which 2 did not match due to:
E             Overload in function 'ol_np_ones': File: numba/np/arrayobj.py: Line 4227.
E               With argument(s): '(OptionalType(int64))':
E              Rejected as the implementation raised a specific error:
E                TypingError: Failed in nopython mode pipeline (step: nopython frontend)
E              No implementation of function Function(<built-in function empty>) found for signature:
E               
E               >>> empty(OptionalType(int64), dtype=none)
E               
E              There are 2 candidate implementations:
E                    - Of which 2 did not match due to:
E                    Overload in function 'ol_np_empty': File: numba/np/arrayobj.py: Line 4054.
E                      With argument(s): '(OptionalType(int64), dtype=none)':
E                     Rejected as the implementation raised a specific error:
E                       TypingError: Cannot parse input types to function np.empty(OptionalType(int64), none)
E                raised from /home/dgavrilov/miniconda3/envs/pyxrf-dev-py310/lib/python3.10/site-packages/numba/np/arrayobj.py:4073
E              
E              During: resolving callee type: Function(<built-in function empty>)
E              During: typing of call at /home/dgavrilov/miniconda3/envs/pyxrf-dev-py310/lib/python3.10/site-packages/numba/np/arrayobj.py (4234)
E              
E              
E              File "../../miniconda3/envs/pyxrf-dev-py310/lib/python3.10/site-packages/numba/np/arrayobj.py", line 4234:
E                  def impl(shape, dtype=None):
E                      arr = np.empty(shape, dtype=dtype)
E                      ^
E           
E             raised from /home/dgavrilov/miniconda3/envs/pyxrf-dev-py310/lib/python3.10/site-packages/numba/core/typeinfer.py:1086
E           
E           During: resolving callee type: Function(<function ones at 0x7f6865b17e20>)
E           During: typing of call at /home/dgavrilov/Projects/PyXRF/pyxrf/core/map_processing.py (1234)
E           
E           
E           File "pyxrf/core/map_processing.py", line 1234:
E           def snip_method_numba(
E               <source elided>
E               # smooth the background
E               s = np.ones(con_val)
E               ^
dmgav commented 2 years ago

@tacaswell Does it look familiar to you in any way?

tacaswell commented 2 years ago

I would try explicitly setting the dtype to help numba do a better job picking which function to use.

dmgav commented 2 years ago

@tacaswell Specifying type does not help much. There is some issue with np.empty() and all related functions. What helps is replacing s = np.ones(con_val, background.dtype) with s = np.array([1.0] * con_val, background.dtype). I don't know how much less efficient this is.

dmgav commented 2 years ago

s = np.ones(int(con_val), background.dtype) seems to fix the problem as well. Numba recognizes con_val type as int64, which v0.56.x does not associate with int.

dmgav commented 2 years ago

Addressed in PR https://github.com/NSLS-II/PyXRF/pull/287