choderalab / bayesian-itc

Python tools for the analysis and modeling of isothermal titration calorimetry (ITC) experiments.
GNU General Public License v3.0
5 stars 10 forks source link

Optimize CompetitiveBindingModel #48

Open bas-rustenburg opened 9 years ago

bas-rustenburg commented 9 years ago

Did a little profiling.. here is by total internal time spent working. Pint units are a big thing. I was running verbose, so arrayprint is also a top hit.

workdir/bitc.profile% sort tottime
workdir/bitc.profile% stats 10
Wed Feb 18 21:55:14 2015    workdir/bitc.profile

         158007904 function calls (156067107 primitive calls) in 209.440 seconds

   Ordered by: internal time
   List reduced from 5159 to 10 due to restriction <10>

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
   683637   21.679    0.000   41.510    0.000 /home/bas/anaconda/lib/python2.7/site-packages/numpy/core/arrayprint.py:547(fillFormat)
   987718   15.600    0.000   93.743    0.000 /home/bas/anaconda/lib/python2.7/site-packages/Pint-0.6-py2.7.egg/pint/quantity.py:981(__getattr__)
 34221455   11.034    0.000   12.454    0.000 {isinstance}
  2321267   10.394    0.000   10.394    0.000 {method 'reduce' of 'numpy.ufunc' objects}
4236243/4184919    7.559    0.000   21.419    0.000 /home/bas/anaconda/lib/python2.7/site-packages/Pint-0.6-py2.7.egg/pint/quantity.py:78(__new__)
   515637    6.364    0.000   11.861    0.000 /home/bas/anaconda/lib/python2.7/site-packages/numpy/core/arrayprint.py:598(__call__)
3343844/1844002    6.022    0.000   17.725    0.000 /home/bas/anaconda/lib/python2.7/copy.py:66(copy)
  5391245    5.252    0.000   12.280    0.000 /home/bas/anaconda/lib/python2.7/site-packages/Pint-0.6-py2.7.egg/pint/compat/__init__.py:85(_to_magnitude)
   956909    5.054    0.000   32.232    0.000 /home/bas/anaconda/lib/python2.7/site-packages/Pint-0.6-py2.7.egg/pint/quantity.py:559(_mul_div)
  2398555    4.586    0.000   10.041    0.000 /home/bas/anaconda/lib/python2.7/site-packages/numpy/core/numeric.py:2320(seterr)

And here is cumulatively, the lambda, expected heats and equilibrium concentrations functions are taking a long time.

workdir/bitc.profile% sort cumulative
workdir/bitc.profile% stats 10
Wed Feb 18 21:55:14 2015    workdir/bitc.profile

         158007904 function calls (156067107 primitive calls) in 209.440 seconds

   Ordered by: cumulative time
   List reduced from 5159 to 10 due to restriction <10>

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.002    0.002  209.520  209.520 scripts/bitc_util.py:28(<module>)
      201    0.001    0.000  207.866    1.034 bitc/models.py:463(<lambda>)
      201    0.626    0.003  207.865    1.034 bitc/models.py:622(expected_injection_heats)
      154    0.001    0.000  202.349    1.314 /home/bas/anaconda/lib/python2.7/site-packages/pymc/Node.py:25(logp_of_set)
     1267    0.002    0.000  202.348    0.160 /home/bas/anaconda/lib/python2.7/site-packages/pymc/PyMCObjects.py:903(get_logp)
1786/1385    0.003    0.000  202.346    0.146 {method 'get' of 'pymc.LazyFunction.LazyFunction' objects}
1917/1090    0.002    0.000  202.338    0.186 /home/bas/anaconda/lib/python2.7/site-packages/pymc/Container.py:539(get_value)
1917/1090    0.004    0.000  202.336    0.186 {method 'run' of 'pymc.Container_values.DCValue' objects}
      519    0.002    0.000  202.334    0.390 /home/bas/anaconda/lib/python2.7/site-packages/pymc/PyMCObjects.py:464(get_value)
     5762    0.351    0.000  185.745    0.032 bitc/models.py:506(equilibrium_concentrations)
bas-rustenburg commented 9 years ago

Plans:

pgrinaway commented 9 years ago

I haven't verified in detail, but perhaps the ode function can be written to use numexpr to speed it up?

bas-rustenburg commented 9 years ago
workdir/bitc.profile% stats \bode\b
Wed Feb 18 21:55:14 2015    workdir/bitc.profile

         158007904 function calls (156067107 primitive calls) in 209.440 seconds

   Ordered by: cumulative time
   List reduced from 5159 to 2 due to restriction <'\\bode\\b'>

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
   131803    2.548    0.000  139.944    0.001 bitc/models.py:601(ode)
        1    0.000    0.000    0.000    0.000 /home/bas/anaconda/lib/python2.7/site-packages/scipy/integrate/_ode.py:103(ode)

Will give that a shot.

pgrinaway commented 9 years ago

I think dc_n = - c_n[:] + Ka_n[:] * (x_Ln[:]/V - c_n[:]) * (x_R/V - c_n[:].sum())

can become something like

import numexpr as ne
dc_n = ne.evaluate('-c_n + Ka_n*(x_Ln/V - c_n) *  (x_R/V - sum(c_n))')
bas-rustenburg commented 9 years ago
  File "/home/bas/anaconda/lib/python2.7/site-packages/numexpr/necompiler.py", line 726, in evaluate
    a = global_dict[name]
KeyError: 'V'
pgrinaway commented 9 years ago

AFAICT numexpr takes its variables from the surrounding context, perhaps V is not accessible?

editing to avoid spamming the thread: maybe it would be easier to rewrite the equilibrium_concentration function to not have nested functions?

bas-rustenburg commented 9 years ago

Will have to remodel the way the function receives the arguments. I think V is a var defined one level above the function. Will let you know if I try something else.

bas-rustenburg commented 9 years ago

Removed references to experiment. Now at 4.5 steps /min instead of 2.5 steps per min. Will open a work-in-progress pull request in a minute.

bas-rustenburg commented 9 years ago

49

bas-rustenburg commented 9 years ago

Closed #49, in favor of #50.

bas-rustenburg commented 9 years ago

I'm playing around with cython a little. I took the expected_injection_heats and equilibrium_concentrations methods out of CompetitiveBindingModel and compiled the plain python code as cython. This sped it up from ~140 steps to ~ 160 steps per minute.

Bigger improvement would be expected once I define my types statically, will open a PR once I have time to figure out how to do this. Cython is still unfamiliar to me.

jchodera commented 9 years ago

That improvement probably isn't worth the hassle, but a speedup of 10x would be notable and worthwhile if it could ve achieved!