我需要创建一些被字典参数化的numba
函数。此字典位于工厂函数的命名空间中,我希望在实际函数中使用它。问题是我得到了一个NotImplemented错误,这个问题是否有一个解决方案,甚至只是一个解决办法?
我已经将我的代码简化为这个示例:
目标裁剪函数采取:
一个选择器,它决定字典中的哪个范围,它应该使用(series
)
from numba.core import types
from numba.typed import Dict
dict_ranges = Dict.empty(
key_type=types.int64,
value_type=types.Tuple((types.float64, types.float64))
)
dict_ranges[3] = (1, 3)
def MB_cut_factory(dict_ranges):
def cut(series, value):
return dict_ranges[series][0] < value < dict_ranges[series][1]
return cut
MB_cut_factory(dict_ranges)(3,2)
True
在纯Python中,它工作得很好。用numba
njit(MB_cut_factory(dict_ranges))(3,2)
---------------------------------------------------------------------------
NumbaNotImplementedError Traceback (most recent call last)
Cell In [107], line 1
----> 1 njit(MB_cut_factory(dict_ranges))(3,2)
File ~/micromamba/envs/root/lib/python3.8/site-packages/numba/core/dispatcher.py:468, in _DispatcherBase._compile_for_args(self, *args, **kws)
464 msg = (f"{str(e).rstrip()} \n\nThis error may have been caused "
465 f"by the following argument(s):\n{args_str}\n")
466 e.patch_message(msg)
--> 468 error_rewrite(e, 'typing')
469 except errors.UnsupportedError as e:
470 # Something unsupported is present in the user code, add help info
471 error_rewrite(e, 'unsupported_error')
File ~/micromamba/envs/root/lib/python3.8/site-packages/numba/core/dispatcher.py:409, in _DispatcherBase._compile_for_args.<locals>.error_rewrite(e, issue_type)
407 raise e
408 else:
--> 409 raise e.with_traceback(None)
NumbaNotImplementedError: Failed in nopython mode pipeline (step: native lowering)
<numba.core.base.OverloadSelector object at 0x7f8c054fefd0>, (DictType[int64,UniTuple(float64 x 2)]<iv=None>,)
During: lowering "$2load_deref.0 = freevar(dict_ranges: {3: (1.0, 3.0)})" at /tmp/ipykernel_2259/3022317309.py (3)
在参数是简单类型的简单情况下,这样做很好:
def MB_cut_factory(limit):
def cut(value):
return value < limit
return cut
MB_cut_factory(4)(3)
njit(MB_cut_factory(4))(3)
发布于 2022-10-24 19:52:55
我已经找到了适用于我的情况的解决方案,但使用了exec
。
def MB_cut_factory(dict_ranges):
exec("def cut(series, value):\n dict_ranges=" +\
dict_ranges.__str__() +\
"\n return dict_ranges[series][0] < value < dict_ranges[series][1]", globals())
return cut
MB_cut_factory(dict_ranges)(3,2)
True
njit(MB_cut_factory(dict_ranges))(3,2)
True
如果有人有一个不那么尴尬的解决这个问题,请!
https://stackoverflow.com/questions/74160505
复制相似问题