[Numpy-discussion] Numpy performance vs Matlab.
Nicolas ROUX
nicolas.roux at st.com
Fri Jan 9 09:56:08 EST 2009
Sorry my previous mail was probalby not clear.
This mail was following the tread we had before, so with some discussion
legacy.
I simplified the code to focus only on "what I" need, rather to bother you
with the full code.
I wrote below a code closer to what I need, where you will agree that
vectorization/broadcasting is needed to avoid nested loops.
As I wrote in the 1st mail (added at the end), what is important is to keep
the code not too ugly due to vectorization syntax.
(As written below I try to demonstrate that vectorization/broadcast code
could be as readable as twice nested loop )
The real code we have is even more complex, with processing the array
element using 5x5 neighbours, instead of 3x3.
######################################################
def test6():
w = 3096
h = 2048
a = numpy.zeros((h,w)) #Normally loaded with real data
b = numpy.zeros((h,w,3))
w0 = numpy.ogrid[0:w-2]
w1 = numpy.ogrid[1:w-1]
w2 = numpy.ogrid[2:w]
h0 = numpy.ogrid[0:h-2]
h1 = numpy.ogrid[1:h-1]
h2 = numpy.ogrid[2:h]
p00, p10, p20 = [h0,w0], [h1,w0],[h2,w0]
p01, p11, p21 = [h0,w1], [h1,w1],[h2,w1]
p02, p12, p22 = [h0,w2], [h1,w2],[h2,w2]
b[p11,1] = a[p11] + 1.23*a[p22] \
- numpy.min([a[p11]-a[p00],
a[p11]-a[p01],
a[p11]-a[p02],
a[p11]-a[p10],
a[p11]-a[p12],
a[p11]-a[p20],
a[p11]-a[p21],
a[p11]-a[p22]]) \
+ 0.123*numpy.max([a[p11]-a[p00],
a[p11]-a[p01],
a[p11]-a[p02],
a[p11]-a[p10],
a[p11]-a[p12],
a[p11]-a[p20],
a[p11]-a[p21],
a[p11]-a[p22]])
######################################################
This code above is the one I wish to write but is not working.
I hope you better understand my issue context ;-)
Did I missed something ?
Thanks for your help.
Cheers,
Nicolas.
> I understand the weakness of the missing JITcompiler in Python vs Matlab,
> that's why I invistigated numpy vectorization/broadcast.
> (hoping to find a cool way to write our code in fast Numpy)
>
> I used the page http://www.scipy.org/PerformancePython to write my code
> efficiently in Numpy.
> While doing it I found one issue.
>
> To have pretty code, I created p0 and p1 arrays of indexes.
I must admit I don't quite understand what you are trying to do, and what
your problem is.
If you just want to do
Out[:,:] = In[:,:]
there is no need for meshgrids (ogrid), for-loops, or whatever.
It is brain dead to use nested for-loops or ogrid for this purpose in
NumPy. It is equally foolish to use nested for loops or meshgrid for this
purpose in Matlab. If you do, I would seriously question your competence.
By the way, you can index ogrid with more than one dimension:
p = numpy.ogrid[:m, :n]
Out[p] = In[p]
============================================================================
===============
============================================================================
===============
============================================================================
===============
Hi !
Thanks a lot for your fast/detailed reply.
A very good point for Numpy ;-)
I spent all my time trying to prepare my testcase to better share with you,
that's why I didn't reply fast.
I understand the weakness of the missing JITcompiler in Python vs Matlab,
that's why I invistigated numpy vectorization/broadcast.
(hoping to find a cool way to write our code in fast Numpy)
I used the page http://www.scipy.org/PerformancePython to write my code
efficiently in Numpy.
While doing it I found one issue.
To have pretty code, I created p0 and p1 arrays of indexes.
In "test8" I wished to see the commented line working, which is not the
case.
Having to use "ix_" is not pretty enough, and seems to not work with further
dimensions.
Why the comment line is not working ?
############################################
def test8():
m = 1024
n = 512
Out = numpy.zeros((m,n))
In = numpy.zeros((m,n))
p0 = numpy.ogrid[0:m]
p1 = numpy.ogrid[0:n]
Out[0:m,0:n] = In[0:m,0:n]
#Out[p0,p1] = In[p0,p1] #This doesn't work
Out[numpy.ix_(p0,p1)] = In[numpy.ix_(p0,p1)]
############################################
What is maybe not clear in the above code, is that I don't want to predefine
all possible ogrid/vector.
The number of possible ogrid/vector is big if in need to define all.
... And this vector definition become more paintful.
So Numpy vector style is fine if i can write something like:
Out[p0,p1] = In[p0,p1] #2 dimensions case
And
Out[p0,p1,1] = In[p0,p1,1] #3 dimensions case
But is not fine if i have to add ".ix_()" or to multiply the number of
vector definitions.
Below example with 3 dimensions instead of 2.
############################################
def test9():
m = 1024
n = 512
Out = numpy.zeros((m,n,3))
In = numpy.zeros((m,n,3))
p0 = numpy.ogrid[0:m]
p1 = numpy.ogrid[0:n]
Out[0:m,0:n,2] = In[0:m,0:n,2]
#Out[p0,p1,2] = In[p0,p1,2]
Out[numpy.ix_(p0,p1,2)] = In[numpy.ix_(p0,p1,2)]
############################################
Tanks again for your support ;-)
Cheers,
Nicolas.
============================================================================
===============
============================================================================
===============
============================================================================
===============
Hi,
I need help ;-)
I have here a testcase which works much faster in Matlab than Numpy.
The following code takes less than 0.9sec in Matlab, but 21sec in Python.
Numpy is 24 times slower than Matlab !
The big trouble I have is a large team of people within my company is ready
to replace Matlab by Numpy/Scipy/Matplotlib,
but I have to demonstrate that this kind of Python Code is executed with the
same performance than Matlab, without writing C extension.
This is becoming a critical point for us.
This is a testcase that people would like to see working without any code
restructuring.
The reasons are:
- this way of writing is fairly natural.
- the original code which showed me the matlab/Numpy performance differences
is much more complex,
and can't benefit from broadcasting or other numpy tips (I can later give
this code)
...So I really need to use the code below, without restructuring.
Numpy/Python code:
#####################################################################
import numpy
import time
print "Start test \n"
dim = 3000
a = numpy.zeros((dim,dim,3))
start = time.clock()
for i in range(dim):
for j in range(dim):
a[i,j,0] = a[i,j,1]
a[i,j,2] = a[i,j,0]
a[i,j,1] = a[i,j,2]
end = time.clock() - start
print "Test done, %f sec" % end
#####################################################################
Matlab code:
#####################################################################
'Start test'
dim = 3000;
tic;
a =zeros(dim,dim,3);
for i = 1:dim
for j = 1:dim
a(i,j,1) = a(i,j,2);
a(i,j,2) = a(i,j,1);
a(i,j,3) = a(i,j,3);
end
end
toc
'Test done'
#####################################################################
Any idea on it ?
Did I missed something ?
Thanks a lot, in advance for your help.
Cheers,
Nicolas.
_______________________________________________
Numpy-discussion mailing list
Numpy-discussion at scipy.org
http://projects.scipy.org/mailman/listinfo/numpy-discussion
More information about the NumPy-Discussion
mailing list