【问题标题】:How to nest numba jitclass如何嵌套 numba jitclass
【发布时间】:2016-12-05 13:18:54
【问题描述】:

我试图了解 @jitclass 装饰器如何与嵌套类一起工作。我写了两个虚拟类:fifi 和 toto fifi 有一个 toto 属性。这两个类都有 @jitclass 装饰器,但编译失败。代码如下:

fifi.py

from numba import jitclass, float64
from toto import toto

spec = [('a',float64),('b',float64),('c',toto)]

@jitclass(spec)
class fifi(object):
  def __init__(self, combis):
    self.a = combis
    self.b = 2
    self.c = toto(combis)

  def mySqrt(self,x):
    s = x
    for i in xrange(self.a):
      s = (s + x/s) / 2.0
    return s

toto.py:

from numba import jitclass,int32

spec = [('n',int32)]

@jitclass(spec)
class toto(object):
  def __init__(self,n):
    self.n = 42 + n

  def work(self,y):
    return y + self.n

启动代码的脚本:

from datetime import datetime
from fifi import fifi
from numba import jit

@jit(nopython = True)
def run(n,results):
  for i in xrange(n):
    q = fifi(200)
    results[i+1] = q.mySqrt(i + 1)

if __name__ == '__main__':
  n = int(1e6)
  results = [0.0] * (n+1)
  starttime = datetime.now()
  run(n,results)
  endtime = datetime.now()

  print("Script running time: %s"%str(endtime-starttime))
  print("Sqrt of 144 is %f"%results[145])

当我运行脚本时,我得到 [...]

TypingError:未键入的全局名称“toto” 文件“fifi.py”,第 11 行

请注意,如果我删除 'fifi' 中对 'toto' 的任何引用,代码可以正常工作,并且由于 numba,我可以得到 x16 的加速。

【问题讨论】:

    标签: python jit numba


    【解决方案1】:

    可以将 jitclass 用作另一个 jitclass 的成员,尽管这样做的方式没有得到很好的记录。您需要使用 deferred_type 实例。这适用于 Numba 0.27 甚至更早版本。将fifi.py 更改为:

    from numba import jitclass, float64, deferred_type
    from toto import toto
    
    toto_type = deferred_type()
    toto_type.define(toto.class_type.instance_type)
    
    spec = [('a',float64),('b',float64),('c',toto_type)]
    
    @jitclass(spec)
    class fifi(object):
      def __init__(self, combis):
        self.a = combis
        self.b = 2
        self.c = toto(combis)
    
      def mySqrt(self,x):
        s = x
        for i in xrange(self.a):
          s = (s + x/s) / 2.0
        return s
    

    然后我得到输出:

    $ python test.py
    Script running time: 0:00:01.991600
    Sqrt of 144 is 12.041595
    

    这个功能可以在一些更高级的 jitclass 数据结构示例中看到,例如:

    【讨论】:

    • 在创建实例后,我试图通过在实例上使用 typeof 来将 jitclass 用作另一个 jitclass 的成员,但这不那么尴尬!
    • 请注意,只有自引用类才需要使用延迟机制,例如示例中的链接实现。您可以直接在 jitclass 规范中使用 toto.class_type.instance_type,即:spec = [('a',float64), ('b',float64), ('c',toto.class_type.instance_type)]。来自stackoverflow.com/questions/57640039
    • @mgmalheiros。谢谢你。这是正确的答案
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-08-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多