Commit 1a27ed9f authored by Sébastien Villemot's avatar Sébastien Villemot
Browse files

OpenMP support:

- removed build_matlab_multithread.m and isopenmp MEX file
- introduced a new option "--enable-openmp" in configure script
- when openmp support is compiled in, the default is still one thread; the user can set the number of threads with "set_dynare_threads(n)"
- closes #68
parent 477652c6
......@@ -149,16 +149,6 @@ number_of_mex_files = size(mex_status,1);
%% added dynare_v4/matlab with the subfolders. Matlab has to ignore these
%% subfolders if valid mex files exist.
matlab_path = path;
test = strfind(matlab_path,[dynareroot 'threads/single']);
if length(test)
rmpath([dynareroot 'threads/single']);
matlab_path = path;
end
test = strfind(matlab_path,[dynareroot 'threads/multi']);
if length(test)
rmpath([dynareroot 'threads/multi']);
matlab_path = path;
end
for i=1:number_of_mex_files
test = strfind(matlab_path,[dynareroot mex_status{i,2}]);
action = length(test);
......@@ -167,15 +157,8 @@ for i=1:number_of_mex_files
matlab_path = path;
end
end
%% Test if multithread mex files are available.
if exist('isopenmp')==3
addpath([dynareroot '/threads/multi/'])
number_of_threads = set_dynare_threads();
multithread_flag = number_of_threads-1;
else
addpath([dynareroot '/threads/single/'])
multithread_flag = 0;
end
%% Initialize number of threads
set_dynare_threads(1);
%% Test if valid mex files are available, if a mex file is not available
%% a matlab version of the routine is included in the path.
disp(' ')
......@@ -187,23 +170,14 @@ for i=1:number_of_mex_files
addpath([dynareroot mex_status{i,2}]);
message = '[m] ';
else
if multithread_flag && ( strcmpi(mex_status(i,1),'sparse_hessian_times_B_kronecker_C') || ...
strcmpi(mex_status(i,1),'A_times_B_kronecker_C') )
message = [ '[mex][multithread version, ' int2str(multithread_flag+1) ' threads are used] ' ];
else
message = '[mex] ';
end
message = '[mex] ';
end
disp([ message mex_status{i,3} '.' ])
end
% Test if bytecode DLL is present
if exist('bytecode', 'file') == 3
if ~multithread_flag
message = '[mex] ';
else
message = [ '[mex][multithread version, ' int2str(multithread_flag+1) ' threads are used] ' ];
end
message = '[mex] ';
else
message = '[no] ';
end
......
function i = isopmenmp()
% This file is called only if the mex files are not compiled with the openmp flag (mutithreaded computations).
function set_dynare_threads(n)
% This function sets the number of threads used by some MEX files when compiled
% with OpenMP support, i.e with --enable-openmp is given to configure.
% As of 2010-09-27, only A_times_B_kronecker_C and
% sparse_hessian_times_B_kronecker_C support this.
%
% INPUTS
% o n [integer] scalar specifying the number of threads to be used.
% Copyright (C) 2009 Dynare Team
% Copyright (C) 2009-2010 Dynare Team
%
% This file is part of Dynare.
%
......@@ -17,4 +23,5 @@ function i = isopmenmp()
%
% You should have received a copy of the GNU General Public License
% along with Dynare. If not, see <http://www.gnu.org/licenses/>.
i = 0;
\ No newline at end of file
setenv('DYNARE_NUM_THREADS',int2str(n));
function not = set_dynare_threads(n)
% This function sets the number of threads used by dynare's mex files.
%
% INPUTS
% o n [integer] scalar specifying the number of threads to be used.
%
% OUTPUTS
% o not [integer] scalar, number of threads.
%
% REMARKS The default value of n is the number of processors on the platform.
% Copyright (C) 2009 Dynare Team
%
% This file is part of Dynare.
%
% Dynare is free software: you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% Dynare 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 General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with Dynare. If not, see <http://www.gnu.org/licenses/>.
not = 1;
if ~isopenmp()% This version of Dynare does not use multithreaded mex files!
disp(' ')
disp('Multithreading is not available on your platform!')
disp(' ')
return
end
MaxNumberOfThreads = maxNumCompThreads();
if ~nargin% Default.
not = MaxNumberOfThreads;
setenv('DYNARE_NUM_THREADS',int2str(MaxNumberOfThreads));
else
if (n>MaxNumberOfThreads)
disp(['You want to use ' int2str(n) ' threads but your platform has only ' int2str(MaxNumberOfThreads) ' processors!'])
reply = input(['Do you really want to use ' int2str(n) ' threads ? Yes/[No]: '],'s');
if isempty(reply)
reply = 'No';
end
if strcmpi(reply,'No')
nn = input(['Choose a number of threads between 1 and [' int2str(MaxNumberOfThreads) ']: ']);
if isempty(nn)
nn = MaxNumberOfThreads;
end
if (nn>MaxNumberOfThreads)
disp(['To my knowledge ' int2str(nn) ' is greater than ' int2str(MaxNumberOfThreads) '!...'])
disp(' ')
not = set_dynare_threads(n);
return
end
not = nn;
setenv('DYNARE_NUM_THREADS',int2str(nn));
elseif strcmpi(reply,'Yes')
not = n;
setenv('DYNARE_NUM_THREADS',int2str(n));
else
disp(['You have to answer by Yes or No...'])
disp(' ')
not = set_dynare_threads(n);
return
end
else
not = n;
setenv('DYNARE_NUM_THREADS',int2str(n));
end
end
\ No newline at end of file
......@@ -91,6 +91,14 @@ else
BUILD_SWZ_MEX_MATLAB="no (missing GSL)"
fi
AC_ARG_ENABLE([openmp], AS_HELP_STRING([--enable-openmp], [use OpenMP for parallelization of some MEX files]), [
if test "x$enable_openmp" = "xyes"; then
CPPFLAGS="$CPPFLAGS -DUSE_OMP"
CFLAGS="$CFLAGS -fopenmp"
CXXFLAGS="$CXXFLAGS -fopenmp"
fi
])
AC_MSG_NOTICE([
Dynare is now configured for building the following components...
......
......@@ -74,6 +74,13 @@ else
BUILD_SWZ_MEX_OCTAVE="no (missing GSL)"
fi
AC_ARG_ENABLE([openmp], AS_HELP_STRING([--enable-openmp], [use OpenMP for parallelization of some MEX files]), [
if test "x$enable_openmp" = "xyes"; then
CPPFLAGS="$CPPFLAGS -DUSE_OMP"
CFLAGS="$CFLAGS -fopenmp"
CXXFLAGS="$CXXFLAGS -fopenmp"
fi
])
AC_MSG_NOTICE([
......
SUBDIRS = estimation
EXTRA_DIST = \
build_matlab_multithread.m \
dynblas.h \
dynlapack.h \
dynmex.h \
mjdgges \
kronecker \
bytecode \
k_order_perturbation \
threads
k_order_perturbation
clean-local:
rm -rf `find mex/sources -name *.o`
......
% Build file for Dynare MEX Librairies under Matlab with multithreading
% Read http://www.dynare.org/DynareWiki/UsingMultithreadedDlls
% Copyright (C) 2007-2009 Dynare Team
%
% This file is part of Dynare.
%
% Dynare is free software: you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% Dynare 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 General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with Dynare. If not, see <http://www.gnu.org/licenses/>.
addpath '../../matlab'; % For matlab_ver_less_than
MATLAB_PATH = matlabroot;
COMPILE_OPTIONS = '';
if strcmpi('GLNX86', computer) || strcmpi('GLNXA64', computer) ...
|| strcmpi('MACI', computer) || strcmpi('MAC', computer)
% GNU/Linux (x86-32 or x86-64) or MacOS (Intel or PPC)
LAPACK_PATH = '-lmwlapack';
if matlab_ver_less_than('7.5')
BLAS_PATH = LAPACK_PATH; % On <= 7.4, BLAS in included in LAPACK
else
BLAS_PATH = '-lmwblas';
end
elseif strcmpi('PCWIN', computer) || strcmpi('PCWIN64', computer)
% Windows (x86-32 or x86-64) with Microsoft or gcc compiler
if strcmpi('PCWIN', computer)
LIBRARY_PATH = [MATLAB_PATH '/extern/lib/win32/microsoft/'];
else
LIBRARY_PATH = [MATLAB_PATH '/extern/lib/win64/microsoft/'];
end
LAPACK_PATH = ['"' LIBRARY_PATH 'libmwlapack.lib"'];
if matlab_ver_less_than('7.5')
BLAS_PATH = LAPACK_PATH; % On <= 7.4, BLAS in included in LAPACK
else
BLAS_PATH = ['"' LIBRARY_PATH 'libmwblas.lib"'];
end
else
error('Unsupported platform')
end
% Pass MATLAB_VERSION to C preprocessor in hexadecimal form
verstruct = ver('matlab');
matver = sscanf(verstruct.Version, '%d.%d.%d')';
COMPILE_OPTIONS = [ COMPILE_OPTIONS ' -DMATLAB_MEX_FILE -DMATLAB_VERSION=0x' sprintf('%02d%02d', matver(1), matver(2)) ];
% Large array dims for 64 bits platforms appeared in Matlab 7.3
if (strcmpi('GLNXA64', computer) || strcmpi('PCWIN64', computer)) ...
&& ~matlab_ver_less_than('7.3')
COMPILE_OPTIONS = [ COMPILE_OPTIONS ' -largeArrayDims' ];
end
OUTPUT_DIR = '../matlab';
disp(' ')
if exist(OUTPUT_DIR,'dir')
disp('Delete old mex files.')
delete([OUTPUT_DIR '/*.' mexext]);
else
whereami = pwd;
disp(['Create directory ' whereami(1:end-7) OUTPUT_DIR(4:end) '.'])
mkdir(OUTPUT_DIR);
end
disp(' ')
% Set Optimization and Debug flags
CXXOPTIMFLAGS = ' CXXOPTIMFLAGS=-O3 ';
COPTIMFLAGS = ' COPTIMFLAGS=-O3 ';
CXXDEBUGFLAGS = ' CXXDEBUGFLAGS= ';
CDEBUGFLAGS = ' CDEBUGFLAGS= ';
LDOPTIMFLAGS = ' LDOPTIMFLAGS=-O3 ';
LDDEBUGFLAGS = ' LDDEBUGFLAGS= ';
COMPILE_OPTIONS = [ COMPILE_OPTIONS CDEBUGFLAGS COPTIMFLAGS CXXDEBUGFLAGS CXXOPTIMFLAGS LDDEBUGFLAGS LDOPTIMFLAGS];
% Comment next line to suppress compilation debugging info
% COMPILE_OPTIONS = [ COMPILE_OPTIONS ' -v' ];
COMPILE_COMMAND = [ 'mex ' COMPILE_OPTIONS ' -outdir ' OUTPUT_DIR ];
CFLAGS = ' CFLAGS="\$CFLAGS -fopenmp" ';
CXXFLAGS = ' CXXFLAGS="\$CXXFLAGS -fopenmp" ';
LDFLAGS = ' LDFLAGS="\$LDFLAGS -fopenmp" ';
disp('Compiling isopenmp...')
try
eval([ 'mex ' COMPILE_OPTIONS ' -DUSE_OMP ' CFLAGS CXXFLAGS LDFLAGS ' -outdir ' OUTPUT_DIR ' threads/isopenmp.cc ' ]);
disp(' ')
disp('|------------------------------------------------|')
disp('| OpenMp is used (multithreaded mex files) for: |')
disp('| * sparse_hessian_times_B_kronecker_C.cc |')
disp('| * A_times_B_kronecker_C.cc |')
disp('|------------------------------------------------|')
disp(' ')
COMPILE_OPTIONS_OMP = [ COMPILE_OPTIONS ' -DUSE_OMP ' CFLAGS CXXFLAGS LDFLAGS ];
catch
disp(' ')
disp('|------------------------------------------------|')
disp('| OpenMp is not available on this platform! |')
disp('|------------------------------------------------|')
disp(' ')
CFLAGS = []; CXXFLAGS = []; LDFLAGS = [];
COMPILE_OPTIONS_OMP = COMPILE_OPTIONS;
end
COMPILE_COMMAND_OMP = [ 'mex ' COMPILE_OPTIONS_OMP ' -outdir ' OUTPUT_DIR ];
disp('Compiling mjdgges...')
eval([ COMPILE_COMMAND ' -I. mjdgges/mjdgges.c ' LAPACK_PATH ]);
disp('Compiling sparse_hessian_times_B_kronecker_C...')
eval([ COMPILE_COMMAND_OMP ' -I. kronecker/sparse_hessian_times_B_kronecker_C.cc' ]);
disp('Compiling A_times_B_kronecker_C...')
eval([ COMPILE_COMMAND_OMP ' -I. kronecker/A_times_B_kronecker_C.cc ']);
disp('Compiling gensylv...')
eval([ COMPILE_COMMAND ' -I. -I../../dynare++/sylv/cc ' ...
'../../dynare++/sylv/matlab/gensylv.cpp ' ...
'../../dynare++/sylv/cc/BlockDiagonal.cpp ' ...
'../../dynare++/sylv/cc/GeneralMatrix.cpp ' ...
'../../dynare++/sylv/cc/GeneralSylvester.cpp ' ...
'../../dynare++/sylv/cc/IterativeSylvester.cpp ' ...
'../../dynare++/sylv/cc/KronUtils.cpp ' ...
'../../dynare++/sylv/cc/KronVector.cpp ' ...
'../../dynare++/sylv/cc/QuasiTriangular.cpp ' ...
'../../dynare++/sylv/cc/QuasiTriangularZero.cpp ' ...
'../../dynare++/sylv/cc/SchurDecomp.cpp ' ...
'../../dynare++/sylv/cc/SchurDecompEig.cpp ' ...
'../../dynare++/sylv/cc/SimilarityDecomp.cpp ' ...
'../../dynare++/sylv/cc/SylvException.cpp ' ...
'../../dynare++/sylv/cc/SylvMatrix.cpp ' ...
'../../dynare++/sylv/cc/SylvMemory.cpp ' ...
'../../dynare++/sylv/cc/SylvParams.cpp ' ...
'../../dynare++/sylv/cc/TriangularSylvester.cpp ' ...
'../../dynare++/sylv/cc/Vector.cpp ' ...
BLAS_PATH ' ' LAPACK_PATH ]);
disp('Compiling bytecode...')
eval([ COMPILE_COMMAND_OMP ' -Ibytecode -I../../preprocessor bytecode/bytecode.cc bytecode/Interpreter.cc bytecode/Mem_Mngr.cc bytecode/SparseMatrix.cc']);
\ No newline at end of file
/*
* Copyright (C) 2009 Dynare Team
*
* This file is part of Dynare.
*
* Dynare is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Dynare 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Dynare. If not, see <http://www.gnu.org/licenses/>.
*/
#include "mex.h"
#ifdef _OPENMP
#define OpenMp 1
#else
#define OpenMp 0
#endif
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] )
{
// Check input and output:
if ( (nrhs > 0) )
{
mexErrMsgTxt("This function has no input arguments!");
}
if (nlhs>1)
{
mexErrMsgTxt("Too many output arguments.");
}
plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);
double *z ;
z = mxGetPr(plhs[0]);
if (OpenMp)
{
*z = 1.0;
}
else
{
*z = 0.0;
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment