log-sum-exp performance comparison notebok on Cython, weaver, Numba etc

335 views
Skip to first unread message

Sebastien Bratieres

unread,
Nov 25, 2013, 10:02:18 AM11/25/13
to cython...@googlegroups.com
Hi, 
I tried a performance comparison on a log-sum-exp function. I was disconcerted with bad performance in my Weave and Cython implementations. 
My IPython notebook is here: http://nbviewer.ipython.org/285184b4a808dfea7070  (sorry for the long Numba debug output which I don't know how to suppress). Cf the bottom for a recap.
How can I speed up my Cython (and Weaver, in case you would know) versions ?

Thanks !
Regards,
Sebastien

Daniele Nicolodi

unread,
Nov 25, 2013, 10:45:50 AM11/25/13
to cython...@googlegroups.com
On 25/11/2013 16:02, Sebastien Bratieres wrote:
> Hi,
> I tried a performance comparison on a log-sum-exp function. I was
> disconcerted with bad performance in my Weave and Cython implementations.

I tested only the numpy, the scipy and the Cythin version of the
function and the timings I obtain are radically different than yours,
with the Cython version being the fastest.

Furthermore, the scipy.misc.logsumexp() function does not simply compute
the equivalent of np.log(np.exp(a).sum()), but something slightly more
complex.

The only advantage of computing np.log(np.exp(a).sum()) in a cython
function is the removal of the temporary array allocated to store the
result of np.exp(a) therefore the speed up depends on the size of the
input array. 20e3 elements are not that many and the speed up is not
evident, also because the small array is all contained in the processor
cache. For a 20e6 elements array, the Cython implementation is twice as
fast as the numpy one, in my test.

Cheers,
Daniele

Nathaniel Smith

unread,
Nov 25, 2013, 11:03:54 AM11/25/13
to cython...@googlegroups.com
BTW, this is also available as a function built-in to numpy --
np.logaddexp.reduce

(This follows the general rule that all binary ufuncs have .reduce
methods -- so np.sum is a convenience wrapper around np.add.reduce,
etc.)

-n

Daniele Nicolodi

unread,
Nov 25, 2013, 11:14:20 AM11/25/13
to cython...@googlegroups.com
On 25/11/2013 17:03, Nathaniel Smith wrote:
> On Mon, Nov 25, 2013 at 7:02 AM, Sebastien Bratieres
> <sebastien...@gmail.com> wrote:
>> Hi,
>> I tried a performance comparison on a log-sum-exp function. I was
>> disconcerted with bad performance in my Weave and Cython implementations.
>> My IPython notebook is here:
>> http://nbviewer.ipython.org/285184b4a808dfea7070 (sorry for the long Numba
>> debug output which I don't know how to suppress). Cf the bottom for a recap.
>> How can I speed up my Cython (and Weaver, in case you would know) versions ?
>
> BTW, this is also available as a function built-in to numpy --
> np.logaddexp.reduce

I'm not sure this is equivalent.

Given that np.logaddexp() computes np.exp(np.log(x1) + np.log(x2)) I
believe that what np.logaddexp.reduce() computes is something like:

r = 0.0
for x in v:
r = np.exp(np.log(r) + np.log(x))
return r

and not

t = 0.0
for x in v:
t = t + np.log(x)
r = np.exp(t)
return r

Therefore the np.log() function is called N-1 times instead of 1.

Timing the function seems to confirm this.

Cheers,
Daniele

Nathaniel Smith

unread,
Nov 25, 2013, 12:39:13 PM11/25/13
to cython...@googlegroups.com

On 25 Nov 2013 08:14, "Daniele Nicolodi" <dan...@grinta.net> wrote:
>
> On 25/11/2013 17:03, Nathaniel Smith wrote:
> > On Mon, Nov 25, 2013 at 7:02 AM, Sebastien Bratieres
> > <sebastien...@gmail.com> wrote:
> >> Hi,
> >> I tried a performance comparison on a log-sum-exp function. I was
> >> disconcerted with bad performance in my Weave and Cython implementations.
> >> My IPython notebook is here:
> >> http://nbviewer.ipython.org/285184b4a808dfea7070  (sorry for the long Numba
> >> debug output which I don't know how to suppress). Cf the bottom for a recap.
> >> How can I speed up my Cython (and Weaver, in case you would know) versions ?
> >
> > BTW, this is also available as a function built-in to numpy --
> > np.logaddexp.reduce
>
> I'm not sure this is equivalent.
>
> Given that np.logaddexp() computes np.exp(np.log(x1) + np.log(x2)) I

I think you have the log and exp reversed, but yes, .reduce may not be as fast as special purpose functions. It does compute the same value, though (modulo rounding errors).

-n

Sebastien Bratieres

unread,
Nov 26, 2013, 6:55:52 AM11/26/13
to cython...@googlegroups.com
Hi Daniele, 
thanks for testing that !

function and the timings I obtain are radically different than yours,
with the Cython version being the fastest.

Aha! That was my point. Any hint why this is so? I have described my configuration in the notebook (mingw from Anaconda, Win 8). Where can the difference come from/ where to start diagnosing what's going on?

Regards,
Sebastien
Reply all
Reply to author
Forward
0 new messages