Mentions légales du service

Skip to content
Snippets Groups Projects
Commit ee3cb1e5 authored by Nicolas Bellot's avatar Nicolas Bellot Committed by hhakim
Browse files

wrapper python test comptime

parent 2389c6b4
No related branches found
No related tags found
No related merge requests found
...@@ -41,6 +41,8 @@ import sys ...@@ -41,6 +41,8 @@ import sys
print "python version : "+str(sys.version_info.major)+'.'+str(sys.version_info.minor) print "python version : "+str(sys.version_info.major)+'.'+str(sys.version_info.minor)
output_value=0 output_value=0
###### NECESSARY MODULE ######
try: try:
import numpy import numpy
print('Python module numpy is installed') print('Python module numpy is installed')
...@@ -54,5 +56,14 @@ try: ...@@ -54,5 +56,14 @@ try:
except ImportError: except ImportError:
print('Python module Cython is missing !') print('Python module Cython is missing !')
output_value=1 output_value=1
###### OPTIONAL MODULE ######
try:
import scipy as sp
print('Python module Scipy is installed')
except ImportError:
print('Python module Scipy is not present, no time comparison with scipy will be made')
output_value=2
exit(output_value) exit(output_value)
...@@ -82,16 +82,22 @@ message(STATUS "------------------------------------------------") ...@@ -82,16 +82,22 @@ message(STATUS "------------------------------------------------")
message(STATUS " ") message(STATUS " ")
message(STATUS "------------------------------------------------") message(STATUS "------------------------------------------------------")
message(STATUS "--- Looking for Python module (cython,numpy) ---") message(STATUS "--- Looking for Python module (cython,numpy,scipy) ---")
message(STATUS "------------------------------------------------") message(STATUS "------------------------------------------------------")
exec_program("${PYTHON_EXE} ${PROJECT_SOURCE_DIR}/CMake/check_python.py" OUTPUT_VARIABLE LIST_PYTHON_MODULE RETURN_VALUE PYTHON_MODULE_MISSING) exec_program("${PYTHON_EXE} ${PROJECT_SOURCE_DIR}/CMake/check_python.py" OUTPUT_VARIABLE LIST_PYTHON_MODULE RETURN_VALUE PYTHON_MODULE_MISSING)
message("${LIST_PYTHON_MODULE}") message("${LIST_PYTHON_MODULE}")
if(${PYTHON_MODULE_MISSING})
message(FATAL_ERROR "At least one python module is missing") set(PYTHON_MODULE_SCIPY ON)
if(${PYTHON_MODULE_MISSING} EQUAL -1)
message(FATAL_ERROR "necessary python module (numpy or cython) are missing !!!")
elseif(${PYTHON_MODULE_MISSING} EQUAL 1)
message(STATUS "optional python module scipy is missing, no time comparison with scipy will be made")
set(PYTHON_MODULE_SCIPY ON)
else(${PYTHON_MODULE_MISSING}) else(${PYTHON_MODULE_MISSING})
message(STATUS "All the Python module are installed") message(STATUS "all the python module are installed (numpy,cython and scipy)")
endif(${PYTHON_MODULE_MISSING}) endif(${PYTHON_MODULE_MISSING})
message(STATUS "------------------------------------------------") message(STATUS "------------------------------------------------")
message(STATUS " ") message(STATUS " ")
################################################################## ##################################################################
......
...@@ -163,6 +163,10 @@ endif(BUILD_WRAPPER_MATLAB) ...@@ -163,6 +163,10 @@ endif(BUILD_WRAPPER_MATLAB)
#PYTHON WRAPPER #PYTHON WRAPPER
if (BUILD_WRAPPER_PYTHON) if (BUILD_WRAPPER_PYTHON)
add_test(NAME PYTHON_FAUST COMMAND ${PYTHON_EXE} ${FAUST_SRC_TEST_SRC_DIR}/test_pyFaust.py ${FAUST_PYTHON_BIN_DIR}) add_test(NAME PYTHON_FAUST COMMAND ${PYTHON_EXE} ${FAUST_SRC_TEST_SRC_DIR}/test_pyFaust.py ${FAUST_PYTHON_BIN_DIR})
if(PYTHON_MODULE_SCIPY)
add_test(NAME PYTHON_FAUST_TIME COMMAND ${PYTHON_EXE} ${FAUST_SRC_TEST_SRC_DIR}/test_pyFaust_time.py ${FAUST_PYTHON_BIN_DIR} ${FAUST_BIN_TEST_FIG_DIR})
endif(PYTHON_MODULE_SCIPY)
endif(BUILD_WRAPPER_PYTHON) endif(BUILD_WRAPPER_PYTHON)
......
##############################################################################
## Description: ##
## Test the Python wrapper (time comparison for multiplication ##
## ##
## For more information on the FAuST Project, please visit the website ##
## of the project : <http://faust.gforge.inria.fr> ##
## ##
## License: ##
## Copyright (2016): Nicolas Bellot, Adrien Leman, Thomas Gautrais, ##
## Luc Le Magoarou, Remi Gribonval ##
## INRIA Rennes, FRANCE ##
## http://www.inria.fr/ ##
## ##
## The FAuST Toolbox is distributed under the terms of the GNU Affero ##
## General Public License. ##
## This program is free software: you can redistribute it and/or modify ##
## it under the terms of the GNU Affero General Public License as ##
## published by the Free Software Foundation. ##
## ##
## This program is distributed in the hope that it will be useful, but ##
## WITHOUT ANY WARRANTY; without even the implied warranty of ##
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ##
## See the GNU Affero General Public License for more details. ##
## ##
## You should have received a copy of the GNU Affero General Public ##
## License along with this program. ##
## If not, see <http://www.gnu.org/licenses/>. ##
## ##
## Contacts: ##
## Nicolas Bellot : nicolas.bellot@inria.fr ##
## Adrien Leman : adrien.leman@inria.fr ##
## Thomas Gautrais : thomas.gautrais@inria.fr ##
## Luc Le Magoarou : luc.le-magoarou@inria.fr ##
## Remi Gribonval : remi.gribonval@inria.fr ##
##############################################################################
# test multiplication time
import sys
if len(sys.argv) != 3 :
raise ValueError('test_pyFaust.py : invalid number of input arguments')
FaustPath=sys.argv[1]
sys.path.append(FaustPath)
FigPath=sys.argv[2]
from scipy import sparse as sp
import numpy as np
import matplotlib.pyplot as plt
import time
import PyFaust
# function : multiplication par un faust sous Scipy
def faust_multiply(list_factor,x):
y=x
#for fact in list_factor:
for fact in reversed(list_factor):
y=fact*y
return y
nb_mult=100
nb_factor=4
#dim=4096
RCG=10
density=1/RCG
density_per_fact=density/nb_factor
# comparaison dans la justesse des resultats (obliger de travailler avec des entiers)
result_comparison=0;
dim_2pow_list=[8,9,10,11,12,13]
#dim_2pow_list=[8,9,10]
nb_dim=len(dim_2pow_list)
dim_list=[0]*nb_dim
for i in range(nb_dim):
dim_list[i]=pow(2,dim_2pow_list[i])
print "******* CONFIGURATION ***********"
print "dimension matrix : "+str(dim_list)
print "nb factor : "+str(nb_factor)
print "RCG : "+str(RCG)
print "nbr multiplication : "+str(nb_mult)
print "*********************************\n"
t_list=np.zeros((nb_mult,nb_dim,3))#dense,scipy,faust
t_scipy=[0]*nb_mult
t_Faust=[0]*nb_mult,
print "** FAUST VECTOR MULTIPLICATON ***"
for j in range(nb_dim):
dim=dim_list[j]
print "dim : "+str(dim)
list_factor_sp=[0]*nb_factor
list_factor_dense=[0]*nb_factor
int_max=100
#initialisation
for i in range(nb_factor):
list_factor_sp[i]=int_max*sp.random(dim,dim,density=density_per_fact,format='csr',dtype=np.float64)
#transforme en entier
if result_comparison:
list_factor_sp[i]=np.floor(list_factor_sp[i])
list_factor_dense[i]=list_factor_sp[i].todense()
#print list_factor_dense[i]
#print "factor"+str(i)+":"
#print list_factor_sp[i]
#print "list_factor_dense"
#for fact in list_factor_dense:
# print "factor "
# print fact
F=PyFaust.Faust(list_factor_dense)
F_dense=F.todense()
if(F.getNbRow() != dim) or (F.getNbCol() != dim):
raise ValueError('invalid Faust size')
for i in range(nb_mult):
#print str(i)+"/"+str(nb_mult)
x=np.random.randint(int_max, size=(dim,1))
t=time.time()
y_dense=F_dense.dot(x)
t_list[i,j,0]=time.time()-t
t=time.time()
y_scipy=faust_multiply(list_factor_sp,x)
t_list[i,j,1]=time.time()-t
t=time.time()
y_Faust=F*x
t_list[i,j,2]=time.time()-t
#print F_dense
#print "t_Faust "+str(t_Faust)
#print "t_scipy "+str(t_scipy)
#print "t_dense "+str(t_dense)
if result_comparison:
if not (y_Faust==y_scipy).all():
raise ValueError('multiplication : invalid ouput vector Y')
if not (y_Faust==y_dense).all():
print "Error"
print y_Faust
print y_dense
raise ValueError('multiplication : dense_multiplication different from Faust one')
#print t_list
t_list_mean=np.mean(t_list,0)
t_dense=t_list_mean[:,0]
t_scipy=t_list_mean[:,1]
t_faust=t_list_mean[:,2]
print "************ RESULT *************"
print "dim "+str(dim_list)
print "t_Faust "+str(t_faust)
print "t_scipy "+str(t_scipy)
print "t_dense "+str(t_dense)
speed_up_Faust=t_dense/t_faust
speed_up_Scipy=t_dense/t_scipy
print "speed-up Faust : "+str(speed_up_Faust)
print "speed-up scipy : "+str(speed_up_Scipy)
#print "size dim :"+str(dim_list.shape)
print "t_dense :"+str(t_dense.shape)
## AFFICHAGE
print "saving figure in "+FigPath
tickness=4
size_font=18
font_style='bold'
plt.loglog(dim_list,t_dense, 'r', basex=2,label='dense (Numpy)',linewidth=tickness)
plt.loglog(dim_list,t_faust, 'b', basex=2,label='Faust (PyFaust)',linewidth=tickness)
plt.loglog(dim_list,t_scipy, 'g', basex=2,label='Faust (Scipy)',linewidth=tickness)
plt.title('Time Comparison : Faust-Vector multiplication',fontweight=font_style)
plt.legend(loc=2)
plt.xlabel('dimension',fontsize=size_font,fontweight=font_style)
plt.ylabel('time (sec)',fontsize=size_font,fontweight=font_style)
plt.grid(linestyle="--",which="both")
plt.grid(linestyle="-")
plt.savefig(FigPath+'/time_comparison.png')
plt.clf()
plt.loglog(dim_list,speed_up_Faust, 'b', basex=2,label='Faust (PyFaust)',linewidth=tickness)
plt.loglog(dim_list,speed_up_Scipy, 'g', basex=2,label='Faust (Scipy)',linewidth=tickness)
plt.title('Speed-up : Faust-Vector multiplication',fontweight=font_style)
plt.legend(loc=2)
plt.xlabel('dimension',fontsize=size_font,fontweight=font_style)
plt.ylabel('speed-up',fontsize=size_font,fontweight=font_style)
plt.grid(linestyle="--",which="both")
plt.grid(linestyle="-")
plt.savefig(FigPath+'/speed-up.png')
print "*********************************"
...@@ -47,3 +47,4 @@ cdef extern from "FaustCpp.h" : ...@@ -47,3 +47,4 @@ cdef extern from "FaustCpp.h" :
void multiply(FPP* value_y,int nbrow_y,int nbcol_y,FPP* value_x,int nbrow_x,int nbcol_x,bool isTranspose); void multiply(FPP* value_y,int nbrow_y,int nbcol_y,FPP* value_x,int nbrow_x,int nbcol_x,bool isTranspose);
unsigned int getNbRow() const; unsigned int getNbRow() const;
unsigned int getNbCol() const; unsigned int getNbCol() const;
void setOp(const bool isTransposed,unsigned int& nbRowOp, unsigned int& nbColOp)const;
...@@ -62,7 +62,7 @@ class FaustCpp ...@@ -62,7 +62,7 @@ class FaustCpp
unsigned int getNbRow() const{return transform.getNbRow();} unsigned int getNbRow() const{return transform.getNbRow();}
unsigned int getNbCol() const{return transform.getNbCol();} unsigned int getNbCol() const{return transform.getNbCol();}
void multiply(FPP* value_y,int nbrow_y,int nbcol_y,FPP* value_x,int nbrow_x,int nbcol_x,bool isTranspose)const; void multiply(FPP* value_y,int nbrow_y,int nbcol_y,FPP* value_x,int nbrow_x,int nbcol_x,bool isTranspose)const;
void setOp(const bool isTransposed,unsigned int& nbRowOp, unsigned int& nbColOp)const;
private : private :
Faust::Transform<FPP,Cpu> transform; Faust::Transform<FPP,Cpu> transform;
......
...@@ -86,3 +86,23 @@ void FaustCpp<FPP>::multiply(FPP* value_y,int nbrow_y,int nbcol_y,FPP* value_x,i ...@@ -86,3 +86,23 @@ void FaustCpp<FPP>::multiply(FPP* value_y,int nbrow_y,int nbcol_y,FPP* value_x,i
} }
template<typename FPP>
void FaustCpp<FPP>::setOp(const bool isTransposed,unsigned int& nbRowOp, unsigned int& nbColOp)const
{
char trans_flag('N');
if (isTransposed)
trans_flag='T';
faust_unsigned_int nb_row,nb_col;
this->transform.setOp(trans_flag,nb_row,nb_col);
nbRowOp=(unsigned int) nb_row;
nbColOp=(unsigned int) nb_col;
}
...@@ -52,6 +52,7 @@ cdef class Faust: ...@@ -52,6 +52,7 @@ cdef class Faust:
#### ATTRIBUTE ######## #### ATTRIBUTE ########
# classe Cython # classe Cython
cdef CyFaust.FaustCpp[double] m_faust cdef CyFaust.FaustCpp[double] m_faust
cdef bool m_transpose_flag
#### CONSTRUCTOR #### #### CONSTRUCTOR ####
#def __cinit__(self,np.ndarray[double, mode="fortran", ndim=2] mat): #def __cinit__(self,np.ndarray[double, mode="fortran", ndim=2] mat):
...@@ -71,21 +72,33 @@ cdef class Faust: ...@@ -71,21 +72,33 @@ cdef class Faust:
# print nbrow # print nbrow
# print nbcol # print nbcol
self.m_faust.push_back(&data[0,0],nbrow,nbcol); self.m_faust.push_back(&data[0,0],nbrow,nbcol);
self.m_transpose_flag=0
#print 'apres boucle' #print 'apres boucle'
#### METHOD #### #### METHOD ####
def getNbRow(self): def getNbRow(self):
return self.m_faust.getNbRow(); #return self.m_faust.getNbRow();
(dim1,dim2)=self.shape();
return dim1
def getNbCol(self): def getNbCol(self):
return self.m_faust.getNbCol(); (dim1,dim2)=self.shape();
return dim2
def shape(self): def shape(self):
return (self.m_faust.getNbRow(),self.m_faust.getNbRow()) #return (self.m_faust.getNbRow(),self.m_faust.getNbRow())
cdef unsigned int nbrow
cdef unsigned int nbcol
self.m_faust.setOp(self.m_transpose_flag,nbrow,nbcol)
return (nbrow,nbcol)
# def transpose(self):
# F_trans=self;
# F_trans.m_tranpose_flag=1;
# return F_trans;
...@@ -103,6 +116,7 @@ cdef class Faust: ...@@ -103,6 +116,7 @@ cdef class Faust:
def multiply(self,x): def multiply(self,x):
if not isinstance(x, (np.ndarray) ): if not isinstance(x, (np.ndarray) ):
raise NameError('input x must a numpy ndarray') raise NameError('input x must a numpy ndarray')
#transform into float F continous matrix
x=x.astype(float,'F') x=x.astype(float,'F')
if not x.dtype=='float': if not x.dtype=='float':
raise NameError('input x must be double array') raise NameError('input x must be double array')
...@@ -152,3 +166,10 @@ cdef class Faust: ...@@ -152,3 +166,10 @@ cdef class Faust:
# y = F * x ,with F a Faust # y = F * x ,with F a Faust
def __mul__(self, x): def __mul__(self, x):
return self.multiply(x) return self.multiply(x)
def todense(self):
identity=np.eye(self.getNbRow(),self.getNbCol());
self_dense=self*identity
return self_dense
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment