sdiehl / numpile

A tiny 1000 line LLVM-based numeric specializer for scientific Python code.
http://dev.stephendiehl.com/numpile/
MIT License
404 stars 52 forks source link

WIP: patch for llvmlite + python3 #4

Closed kousu closed 5 years ago

kousu commented 6 years ago

I am trying to address #3 by rewriting autojit to work against llvmpy's successor, llvmlite.

For a first pass, I use their compat layer, but it's not enough. The ee module is missing, so it's impossible to actually run the code. I did get it to generate code, or at least generate an LLVM AST, which you can see (I think?) if you turn on DEBUG = True:

$ python test.py 
================================================================================
[<numpile.TApp object at 0x112117940>, <numpile.TApp object at 0x1121178d0>] -> $c
================================================================================
{'$e': <numpile.TCon object at 0x1120efd30>, '$f': <numpile.TCon object at 0x1120efd68>, '$d': <numpile.TCon object at 0x1120efd30>, '$a': <numpile.TApp object at 0x112117940>, '$b': <numpile.TApp object at 0x1121178d0>, '$g': <numpile.TVar object at 0x112117400>, '$c': <numpile.TVar object at 0x112117400>, '$retty': <numpile.TVar object at 0x112117400>, '$h': <numpile.TVar object at 0x112117400>}
================================================================================
[(<numpile.TApp object at 0x1121174e0>, <numpile.TApp object at 0x1121175c0>), (<numpile.TVar object at 0x112117550>, <numpile.TCon object at 0x1120efd30>), (<numpile.TCon object at 0x1120efd30>, <numpile.TCon object at 0x1120efd30>), (<numpile.TVar object at 0x112117630>, <numpile.TCon object at 0x1120efd68>), (<numpile.TVar object at 0x112117470>, <numpile.TCon object at 0x1120efd30>), (<numpile.TVar object at 0x1121172e8>, <numpile.TApp object at 0x112117748>), (<numpile.TCon object at 0x1120efd30>, <numpile.TCon object at 0x1120efd30>), (<numpile.TVar object at 0x112117358>, <numpile.TApp object at 0x112117828>), (<numpile.TCon object at 0x1120efd30>, <numpile.TCon object at 0x1120efd30>), (<numpile.TVar object at 0x1121176d8>, <numpile.TVar object at 0x1121177b8>), (<numpile.TVar object at 0x112117400>, <numpile.TVar object at 0x1121177b8>), (<numpile.TVar object at 0x1121177b8>, <numpile.TVar object at 0x112117400>), (<numpile.TVar object at 0x1121177b8>, <numpile.TVar object at 0x1120facf8>)]
================================================================================
('Fun',
 {'args': [('arg', {'annotation': None, 'arg': "'a'"}),
           ('arg', {'annotation': None, 'arg': "'b'"})],
  'body': [('Assign',
            {'ref': "'c'",
             'type': <numpile.TVar object at 0x112117400>,
             'val': ('LitInt', {'n': 0})}),
           ('Assign',
            {'ref': "'n'",
             'type': <numpile.TVar object at 0x112117470>,
             'val': ('Index',
                     {'ix': ('LitInt', {'n': 0}),
                      'val': ('Prim',
                              {'args': [('Var', {'id': "'a'", 'type': None})],
                               'fn': "'shape#'"})})}),
           ('Loop',
            {'begin': ('LitInt', {'n': 0}),
             'body': [('Assign',
                       {'ref': "'c'",
                        'type': <numpile.TVar object at 0x1121177b8>,
                        'val': ('Prim',
                                {'args': [('Var',
                                           {'id': "'c'",
                                            'type': <numpile.TVar object at 0x112117400>}),
                                          ('Prim',
                                           {'args': [('Index',
                                                      {'ix': ('Var',
                                                              {'id': "'i'",
                                                               'type': <numpile.TCon object at 0x1120efd30>}),
                                                       'val': ('Var',
                                                               {'id': "'a'",
                                                                'type': <numpile.TVar object at 0x1121172e8>})}),
                                                     ('Index',
                                                      {'ix': ('Var',
                                                              {'id': "'i'",
                                                               'type': <numpile.TCon object at 0x1120efd30>}),
                                                       'val': ('Var',
                                                               {'id': "'b'",
                                                                'type': <numpile.TVar object at 0x112117358>})})],
                                            'fn': "'mult#'"})],
                                 'fn': "'add#'"})})],
             'end': ('Var',
                     {'id': "'n'",
                      'type': <numpile.TVar object at 0x112117470>}),
             'var': ('Var',
                     {'id': "'i'",
                      'type': <numpile.TCon object at 0x1120efd30>})}),
           ('Return',
            {'val': ('Var',
                     {'id': "'c'",
                      'type': <numpile.TVar object at 0x1121177b8>})})],
  'fname': "'dot'"})
================================================================================
Specialized Function: [<numpile.TApp object at 0x1120fa5f8>, <numpile.TApp object at 0x1120fa7b8>] -> Int32
Traceback (most recent call last):
  File "test.py", line 15, in <module>
    print(dot(a,b))
  File "numpile.py", line 960, in _wrapper
    llfunc = codegen(ast, specializer, retty, argtys)
  File "numpile.py", line 980, in codegen
    mod = cgen.visit(ast)
  File "numpile.py", line 802, in visit
    return getattr(self, name)(node)
  File "numpile.py", line 664, in visit_Fun
    self.start_function(func_name, module, rettype, argtypes)
  File "numpile.py", line 597, in start_function
    builder = lc.Builder.new(entry_block)
AttributeError: type object 'Builder' has no attribute 'new'

This is the edge of my ability here, but maybe someone with a better understanding of this stuff can take this and run with it.

Being able to JIT CPython would be very intriguing.

pfalcon commented 5 years ago

This is the edge of my ability here, but maybe someone with a better understanding of this stuff can take this and run with it.

FYI, I have both "add" and "dot" examples from http://dev.stephendiehl.com/numpile/ running with a version quick-patched for python3 and llvmlite ("dot" shows nice integer-overflow, yeah). It likely will take some time before I clean up those changes though. And actually extent of cleanup depends on whether it will be possible to summon @sdiehl from the depth of Haskell cabal and see if he's interested in maintaining this repo and how. (I for example completely disinterested in those "notebook" thingies.)

cdeil commented 5 years ago

Close PR?

(looks like master is already using llvmlite)

pfalcon commented 5 years ago

Close PR?

Yes, @kousu (or @sdiehl), please do that.

kousu commented 5 years ago

Wow, I do not remember writing this code. I guess I did! Sorry I never addressed your feedback, sometimes I miss notifications from github while other threads get through fine. I don't know what's up with that, maybe my greylister? Maybe I've somehow disabled certain notifications.

Anyway, I guess my initial desire is solved so A+ to everyone.