jakeret / hope

HOPE: A Python Just-In-Time compiler for astrophysical computations
GNU General Public License v3.0
382 stars 28 forks source link

Not working for sum function #13

Closed noodlebreak closed 9 years ago

noodlebreak commented 9 years ago

I tried to see the performance, but it doesn't even compile. Maybe I'm doing something wrong?

Here's my code:

import time

from hope import jit

def normsum(n):
    return sum((i for i in xrange(n)))

@jit
def hopesum(n):
    return sum([i for i in range(n)])

st = time.time()
s = normsum(100000000)
print "Simple sum time: ", time.time()-st
print s

st = time.time()
hopesum(100000000)
print "Hope sum time: ", time.time()-st
print s

This is the output:

Simple sum time:  3.57045102119
4999999950000000
Traceback (most recent call last):
  File "hope_test.py", line 21, in <module>
    hopesum(100000000)
  File "/usr/local/lib/python2.7/dist-packages/hope-0.3.0-py2.7.egg/hope/_wrapper.py", line 66, in _hope_callback
    return self(*args) if self.cache is None else self.cache(*args)
  File "/usr/local/lib/python2.7/dist-packages/hope-0.3.0-py2.7.egg/hope/_wrapper.py", line 72, in __call__
    ASTTransformer(self.modtoken).module_visit(self.fkt, args)
  File "/usr/local/lib/python2.7/dist-packages/hope-0.3.0-py2.7.egg/hope/_transformer.py", line 633, in module_visit
    parsed = self.visit(fktast)
  File "/usr/lib/python2.7/ast.py", line 241, in visit
    return visitor(node)
  File "/usr/local/lib/python2.7/dist-packages/hope-0.3.0-py2.7.egg/hope/_transformer.py", line 570, in visit_FunctionDef
    self.token.body = self.body_visit(node.body) 
  File "/usr/local/lib/python2.7/dist-packages/hope-0.3.0-py2.7.egg/hope/_transformer.py", line 583, in body_visit
    self.exprs.append(self.visit(stmt))            
  File "/usr/lib/python2.7/ast.py", line 241, in visit
    return visitor(node)
  File "/usr/local/lib/python2.7/dist-packages/hope-0.3.0-py2.7.egg/hope/_transformer.py", line 537, in visit_Return
    value = self.visit(node.value)
  File "/usr/lib/python2.7/ast.py", line 241, in visit
    return visitor(node)
  File "/usr/local/lib/python2.7/dist-packages/hope-0.3.0-py2.7.egg/hope/_transformer.py", line 450, in visit_Call
    raise Exception("Function '{0}' not accessible form global scope of function '{1}': ({2})".format(node.func.id, self.fkt.__name__, ast.dump(node)))
Exception: Function 'sum' not accessible form global scope of function 'hopesum': (Call(func=Name(id='sum', ctx=Load()), args=[ListComp(elt=Name(id='i', ctx=Load()), generators=[comprehension(target=Name(id='i', ctx=Store()), iter=Call(func=Name(id='range', ctx=Load()), args=[Name(id='n', ctx=Load())], keywords=[], starargs=None, kwargs=None), ifs=[])])], keywords=[], starargs=None, kwargs=None))
in body return sum([i for i in range(n)])
cosmo-ethz commented 9 years ago

HOPE does neither support the built-in sum function nor generators or list comprehensions. Instead we try to always use the NumPy functionality.

I slightly adapted your example:

import time
import numpy as np

import hope
hope.config.verbose = True

def normsum(a):
    return sum(a)

@hope.jit
def hopesum(a):
    return np.sum(a)

n = 100000000
a = np.arange(n)

st = time.time()
s = normsum(a)
print "Simple sum time: ", time.time()-st
print s

st = time.time()
hopesum(a)
print "Hope sum time: ", time.time()-st
print s

And the output looks like this after the function has been compiled:

Simple sum time:  7.55920100212
4999999950000000
Hope sum time:  0.0635640621185
4999999950000000
noodlebreak commented 9 years ago

That's not even a real competition. Pitching numpy's sum against the python's sum isn't what I'm after.

Run this below, numpy sum vs numpy sum with jit. More time is taken for latter.

def numpysum(a):
    return np.sum(a)

@jit
def hopenpsum(a):
    return np.sum(a)

a = np.arange(100000000)

st = time.time()
s = numpysum(a)
print "Simple sum time: ", time.time()-st
print s

st = time.time()
hopenpsum(a)
print "Hope sum time: ", time.time()-st
print s

Output:

Simple sum time:  0.0824999809265
4999999950000000
Hope sum time:  0.0911591053009
4999999950000000
cosmo-ethz commented 9 years ago

Of course this isn’t a real competition and it wasn’t intended as such. The code should show what has to be changed in order to get rid of the compilation exception.

When I run your code the first time the jitted function takes more time to execute due to the translation and compilation overhead. Subsequent calls take slightly less time compared to np.sum on my machine.

The question is what you’d like to benchmark with this? Essentially it’s C vs. C in this case.

noodlebreak commented 9 years ago
Subsequent calls take slightly less time compared to np.sum on my machine.

Yes indeed. I did not think of that.

The question is what you’d like to benchmark with this? Essentially it’s C vs. C in this case.

Again, this makes sense. I actually just wanted to see if this could be used to speed up non numpy type code. And I mostly work with Django and OpenCV. Guess that won't work out.

cosmo-ethz commented 9 years ago

HOPE focuses on a subset of the language and targets towards numerical codes, which typically make heavy use of NumPy.

However, depending on how time-consuming your computations are, you could convert the data into NumPy data types, run the jitted calculations and convert the data back into the original data types. If the speed up is sufficiently large, the overhead coming from converting the data could be neglected.