Numba嵌套jitclass编译失败,寻求问题原因及解决方法
问题原因与解决办法
问题原因
- 类型定义不匹配:此处不存在类间循环引用(
Particle无需依赖Particles),却使用了deferred_type声明Particle类型,导致Particlesspec中particles字段的DeferredType与实际创建的ListType[Particle]无法兼容,触发类型转换错误。 - 列表推导式的类型推断限制:在jitclass的
__init__方法中直接用列表推导式生成Particle实例并初始化numba.typed.List,Numba的nopython模式无法正确推导该表达式的类型,进一步加剧了类型不匹配问题。
解决代码
修改后的可运行代码如下:
import numba import numpy as np from numba import int32, float64, types from numba.experimental import jitclass import constants p_spec = [ ('x', float64), ('y', float64), ] @jitclass(p_spec) class Particle(object): def __init__(self, x, y): self.x = x self.y = y # 直接使用Particle的实例类型定义列表类型,无需deferred_type particle_list_type = types.ListType(Particle.class_type.instance_type) ps_spec = [ ('size', int32), ('particles', particle_list_type), ] @jitclass(ps_spec) class Particles(object): def __init__(self, size): self.size = size # 创建指定类型的空列表,再循环添加元素 self.particles = numba.typed.List.empty_list(Particle.class_type.instance_type) xs = np.random.uniform(0, constants.WIDTH, size) ys = np.random.uniform(0, constants.HEIGHT, size) for x, y in zip(xs, ys): self.particles.append(Particle(x, y)) p = Particles(20)
关键修改说明
- 移除
deferred_type:由于两类无循环依赖,直接用Particle.class_type.instance_type定义列表类型即可,避免类型不兼容问题。 - 改用空列表初始化+循环添加:通过
numba.typed.List.empty_list()创建明确类型的空列表,再逐个添加Particle实例,绕过列表推导式的类型推断限制,确保类型完全匹配。
内容的提问来源于stack exchange,提问作者Amir Afghani
相关产品推荐
相关产品推荐

