100%(2)2 out of 2 people found this document helpful
This preview shows page 468 - 470 out of 777 pages.
real*8typeon the Fortran side. If you call older Fortran code with single precisionrealvariables,float32is the corresponding type in Python.13.F2PY may introduce time-consuming copying of arrays.NumPy arrays created in Python and sent to Fortran with the aid ofF2PY, will in the wrapper code be copied to new arrays with Fortran or-dering unless they already have been transformed to this storage scheme(see Chapters 9.3.2 and 9.3.3). To avoid overhead in such copying, thecalling Python code can explicitly call theasarrayfunction with theorder=’Fortran’argument to ensure array storage compatible with For-tran (see page 464 for an illustrating example). It is a good habit toexplicitly convert all arrays to Fortran storage prior to calling the For-tran code.14.Calling C++ classes via SWIG involves proxy classes.C++ extension modules created by SWIG have their classes mirrored inPython. However, the class used from Python is actually a proxy classimplemented in Python and performing calls to pure C++ wrapper func-tions. There is some overhead with the proxy class so calling the under-lying C++ wrapper functions directly from Python improves eﬃciency.15.wrap2callablemay be expensive.The convenientwrap2callabletool from Chapter 12.2.2 may introducesignificant overhead when you wrap a constant or discrete data, seepage 6184.108.40.206Case Study on Numerical EﬃciencyWe shall in the following investigate the numerical eﬃciency of several im-plementations of a matrix-vector product. Various techniques for speedingup Python loops will be presented, including rewrite withreduceandmap,
4468. Advanced Pythonmigration of code to Fortran 77, use of run-time compiler tools such as Psycoand Weave, and of course calling a built-in NumPy function for the task. Allthe implementations and the test suite are available in the filesrc/py/examples/efficiency/pyefficiency.pyPure Python Loops.Here is a straightforward implementation of a matrix-vector product in pure Python:def prod1(m, v):nrows, ncolumns = m.shaperes = zeros(nrows)for i in xrange(nrows):for j in xrange(ncolumns):res[i] += m[i,j]*v[j]return resRewrite withmapandreduce.Loops can often be replaced by certain com-binations of the Python functionsmap,reduce, andfilter. Here is a first trywhere we express the matrix-vector product as a sum of the scalar productsbetween each row and the vector:def prod2(m, v):nrows = m.shaperes = zeros(nrows)for i in range(nrows):res[i] = reduce(lambda x,y: x+y,map(lambda x,y: x*y, m[i,:], v))return resBelow is an improved version where we rely on the NumPy matrix multipli-cation operator to perform the scalar product and a newreduceto replacetheiloop:def prod3(m, v):nrows = m.shapeindex = xrange(nrows)return array(map(lambda i:reduce(lambda x,y: x+y, m[i,:]*v),index))Theprod2function runs slightly faster thanprod1, whileprod3runs almostthree times faster thanprod1.