Need insight on code design choices. Context: scipy.integrate.odeint, Numba, and Python classes
0 views
Skip to first unread message
bhmer...@gmail.com
unread,
May 4, 2015, 11:47:06 AM5/4/15
Reply to author
Sign in to reply to author
Forward
Sign in to forward
Delete
You do not have permission to delete messages in this group
Copy link
Report message
Sign in to report message
Show original message
Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message
to numba...@continuum.io
Hi everyone,
scipy.integrate.odeint (http://docs.scipy.org/doc/scipy-0.15.1/reference/generated/scipy.integrate.odeint.html) requires as its first argument, a function that computes the derivatives of the variables we want to integrate over (which I'll refer to as d_func, for "derivative function" from now on). d_func has to be written by the user, in Python code. A great way to get a boost of performance using Numba is to @jit the d_func (because d_func is called *many* times during integration).
I have a question about how this optimization will work when d_func is complicated enough that it needs a Python class object behind it.
Here is a "cartoon" of my code:
there is a module called DynamicBox.py
inside this module is a Python class, DynamicBox
DynamicBox has a bunch of attributes
some of these attributes are "phase variables" -- that is, I am interested in how they evolve in time
some of these attributes are "parameters" -- that is, I use them to calculate the derivatives of the phase variables
Now, I will have a bunch of functions that will take DynamixBox phase variable or parameter attributes, in order to calculate relevant terms in the derivatives. That is:
I will have a d_func
d_func itself will call lots of little helper functions to calculate relevant terms in the derivative, using DynamixBox attributes
So, I have to make a choice, with the following options:
either I can make d_func and all its helper functions methods of DynamicBox;
or I can make only d_func a method of DynamicBox, and all of its helper functions are in the same module as DynamicBox, but not methods of DynamicBox;
or only the helper functions are methods of DynamicBox, but d_func is just in the same module (DynamicBox.py), and not a method of DynamicBox;
or neither the helper functions, nor d_func, are methods of DynamicBox.
I do not know enough about Python to figure out which choice is best. Is it expensive to make instance attribute calls to get attributes? Is it expensive only if you are in a function that is not a method of the class? Questions like that is what I need insight on. What if Numba is in play? For instance, will Numba like it better if I am @jit-ting normal functions instead of class methods?
Can you help?
Kind regards,
Brian
Jason Sachs
unread,
May 4, 2015, 12:04:33 PM5/4/15
Reply to author
Sign in to reply to author
Forward
Sign in to forward
Delete
You do not have permission to delete messages in this group
Copy link
Report message
Sign in to report message
Show original message
Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message
to numba...@continuum.io
I don't know the answer to this one, but it makes a REALLY interesting
use case that would be a great writeup of how to use Numba effectively
for a nontrivial task.
@jit def helper() return x_arr # This is a compile time constant
@jit def rhs(t, y) return helper()
@jit def rhs2(t, y) return helper2(x_arr)
if switch return rhs else return rhs2
This is a good approach if the parameters in your box don't change too often (or even depending on the phase evolution), as you would need to generate a new d_func every time.
Brian Merchant
unread,
May 5, 2015, 10:06:39 PM5/5/15
Reply to author
Sign in to reply to author
Forward
Sign in to forward
Delete
You do not have permission to delete messages in this group
Copy link
Report message
Sign in to report message
Show original message
Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message
to numba...@continuum.io
Hi everyone. I also set up the same question on StackOverflow, along with a huge bounty (+350), so you might consider writing a nice answer there (and here -- in any case, I'll post any answer I get that's really cool over here).
Some questions for the replies posted so far:
Uwe: did you end up testing the case where the inner loops were methods, not functions?
Frank: I am still not sure I understand why we need a function factory -- is this in order to keep Numba from constantly generating the RHS function again and again? Doesn't Numba generate only once at compile time?
Uwe Fechner
unread,
May 6, 2015, 2:50:48 AM5/6/15
Reply to author
Sign in to reply to author
Forward
Sign in to forward
Delete
You do not have permission to delete messages in this group
Copy link
Report message
Sign in to report message
Show original message
Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message
to numba...@continuum.io
As far as I know, numba 0.18 cannot compile methods at all. I tried to use functions, where I pass a reference to the object as first parameter to numba compiled functions, but this was very slow.
Currently only functions with scalars or numpy-arrays as parameters work well with numba.