Numba类型不匹配报错:无法存储{i8*,i32,i8*,i8*,i32}*到i8*
问题分析与解决方案
核心错误原因
报错cannot store {i8*, i32, i8*, i8*, i32}* to i8*本质是Numba typed.List 和 reflected List 类型不匹配:
- 你定义的
new_genotype_type的value_type是types.ListType(types.int64),对应Python原生列表(reflected list); - 但在
create_full_tree里用List.empty_list(types.int64)创建的是Numba typed.List,两种类型在Numba的nopython模式下无法兼容,赋值时触发类型不匹配错误。
解决方案
方案1:统一使用Numba typed.List(推荐)
修改new_genotype_type的定义,将value_type改为Numba typed.List的类型,确保容器类型完全匹配:
from numba import types from numba.typed import Dict, List # 定义int64类型的typed.List类型 production_list_type = List.empty_list(types.int64)._numba_type_ # 重新定义genotype字典的类型 new_genotype_type = Dict.empty( key_type=types.unicode_type, value_type=production_list_type )
修改后,create_full_tree中用List.empty_list(types.int64)创建的列表可直接赋值给genotype[symbol],类型完全兼容。
方案2:使用原生列表(兼容旧逻辑)
若需保留reflected List的定义,在函数内创建原生列表而非typed.List:
@jit(nopython=True) def create_full_tree(grammar, genotype, first_symbol, ref_by_dict, count_refs_dict, non_terminals_set): non_terminals_list = list(non_terminals_set) for symbol_index in prange(len(non_terminals_list)): symbol = non_terminals_list[symbol_index] upper_bound = find_references(symbol, first_symbol, ref_by_dict, count_refs_dict) # 创建原生列表替代typed.List possible_productions = [0] * upper_bound genotype[symbol] = possible_productions
注意:原生列表在nopython模式下性能弱于typed.List,且部分操作受限,优先推荐方案1。
额外检查点
- 确认
find_references函数已用@jit(nopython=True)装饰,且返回值为int64类型,避免隐式类型转换; - Numba 0.57版本较旧,若方案无效可尝试升级至0.59+版本,新版本对typed容器的类型推断更完善;
- 使用
prange需搭配parallel=True参数才能启用并行:@jit(nopython=True, parallel=True) def create_full_tree(...): ...
内容的提问来源于stack exchange,提问作者Diogo Neiss
相关产品推荐
相关产品推荐

