Mentions légales du service

Skip to content
Snippets Groups Projects
Commit 96a44290 authored by hhakim's avatar hhakim
Browse files

Add matfaust wrapper for hieararchical factorization (2020 backend, tested on a CBP's GPU).

parent 6a3fef3b
Branches
Tags
No related merge requests found
......@@ -140,18 +140,29 @@ function varargout = hierarchical(M, p, varargin)
backend = 2016;
nargin = length(varargin);
if(nargin > 0)
backend = varargin{1};
if(strcmp('backend', backend))
if(nargin < 2)
error('keyword argument ''backend'' must be followed by 2016 or 2020')
else
backend = varargin{2};
for i=1:nargin
switch(varargin{i})
case 'backend'
if(nargin < i+1)
error('keyword argument ''backend'' must be followed by 2016 or 2020')
else
backend = varargin{i+1};
end
case 'gpu'
if(nargin == i || ~ islogical(varargin{i+1}))
error('gpu keyword argument is not followed by a logical')
else
gpu = varargin{i+1};
end
end
end
if(~ (isscalar(backend) && floor(backend) == backend) || backend ~= 2016 && backend ~= 2020)
backend
error('backend must be a int equal to 2016 or 2020')
end
if(backend ~= 2020 && gpu == true)
error('GPU implementation is only available for 2020 backend.')
end
end
if(backend == 2016)
if(isreal(M))
......@@ -162,7 +173,11 @@ function varargout = hierarchical(M, p, varargin)
F = Faust(core_obj, isreal(M));
elseif(backend == 2020)
if(isreal(M))
[lambda, core_obj] = mexHierarchical2020Real(M, mex_params);
if(gpu)
[lambda, core_obj] = mexHierarchical2020_gpu2Real(M, mex_params);
else
[lambda, core_obj] = mexHierarchical2020Real(M, mex_params);
end
else
error('backend 2020 doesn''t handle yet the complex matrices')
end
......
......@@ -124,8 +124,11 @@ foreach(SCALAR_AND_FSUFFIX double:Real std::complex<double>:Cplx) # TODO: float
if(USE_GPU_MOD)
configure_file(${FAUST_MATLAB_MEX_SRC_DIR}/mexPALM4MSA2020_gpu2.cpp.in ${FAUST_MATLAB_MEX_SRC_DIR}/mexPALM4MSA2020_gpu2${FSUFFIX}.cpp @ONLY)
configure_file(${FAUST_MATLAB_DOC_SRC_DIR}/mexPALM4MSA2020_gpu2.m.in ${FAUST_MATLAB_DOC_SRC_DIR}/mexPALM4MSA2020_gpu2${FSUFFIX}.m @ONLY)
configure_file(${FAUST_MATLAB_DOC_SRC_DIR}/mexHierarchical2020_gpu2.m.in ${FAUST_MATLAB_DOC_SRC_DIR}/mexHierarchical2020_gpu2${FSUFFIX}.m @ONLY)
configure_file(${FAUST_MATLAB_MEX_SRC_DIR}/mexHierarchical2020_gpu2.cpp.in ${FAUST_MATLAB_MEX_SRC_DIR}/mexHierarchical2020_gpu2${FSUFFIX}.cpp @ONLY)
else()
file(REMOVE ${FAUST_MATLAB_MEX_SRC_DIR}/mexPALM4MSA2020_gpu2${FSUFFIX}.cpp) # delete a possible previous file generated with USE_GPU_MOD = ON (because otherwise it fails the building)
file(REMOVE ${FAUST_MATLAB_MEX_SRC_DIR}/mexHierarchical2020_gpu2${FSUFFIX}.cpp) # delete a possible previous file generated with USE_GPU_MOD = ON (because otherwise it fails the building)
endif()
endif()
# copy the *.m for factorization now, because we have the FSUFFIX in hands
......
% TODO
%
/****************************************************************************/
/* Description: */
/* For more information on the FAuST Project, please visit the website */
/* of the project : <http://faust.inria.fr> */
/* of the project : <http://faust.inria.fr> */
/* */
/* License: */
/* Copyright (2020): Nicolas Bellot, Adrien Leman, Thomas Gautrais, */
/* Copyright (2021): Nicolas Bellot, Adrien Leman, Thomas Gautrais, */
/* Hakim HADJ-DJILANI */
/* Luc Le Magoarou, Remi Gribonval */
/* INRIA Rennes, FRANCE */
/* http://www.inria.fr/ */
......
/****************************************************************************/
/* Description: */
/* For more information on the FAuST Project, please visit the website */
/* of the project : <http://faust.inria.fr> */
/* */
/* License: */
/* Copyright (2021): Nicolas Bellot, Adrien Leman, Thomas Gautrais, */
/* Hakim HADJ-DJILANI */
/* 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: */
/* Hakim Hadj-Djilani : hakim.hadj-djilani@inria.fr */
/* 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 */
/* */
/* References: */
/* [1] Le Magoarou L. and Gribonval R., "Flexible multi-layer sparse */
/* approximations of matrices and applications", Journal of Selected */
/* Topics in Signal Processing, 2016. */
/* <https://hal.archives-ouvertes.fr/hal-01167948v1> */
#include "mex.h"
#include "faust_hierarchical.h"
#include "faust_TransformHelper.h"
#include "class_handle.hpp"
#include <vector>
#include <string>
#include <algorithm>
#include "mx2Faust.h"
#include "faust2Mx.h"
#include <stdexcept>
typedef @FAUST_SCALAR@ SCALAR;
typedef @FACT_FPP@ FPP2;
using namespace std;
void convert_cons_vec_cpu2gpu(vector<const Faust::ConstraintGeneric*>& cpu_cons,
vector<const Faust::ConstraintGeneric*>& gpu_cons)
{
for(auto cons: cpu_cons)
{
if(cons->is_constraint_parameter_int<SCALAR,GPU2>())
{
auto c = dynamic_cast<const Faust::ConstraintInt<SCALAR,Cpu>*>(cons);
gpu_cons.push_back(new Faust::ConstraintInt<SCALAR, GPU2>(c->get_constraint_type(), c->get_parameter(), c->get_rows(), c->get_cols()));
}
else if(cons->is_constraint_parameter_real<SCALAR,GPU2>())
{
auto c = dynamic_cast<const Faust::ConstraintFPP<SCALAR,Cpu>*>(cons);
gpu_cons.push_back(new Faust::ConstraintFPP<SCALAR, GPU2>(c->get_constraint_type(), c->get_parameter(), c->get_rows(), c->get_cols()));
}
else if(cons->is_constraint_parameter_mat<SCALAR,GPU2>())
{
auto c = dynamic_cast<const Faust::ConstraintMat<SCALAR,Cpu>*>(cons);
gpu_cons.push_back(new Faust::ConstraintMat<SCALAR, GPU2>(c->get_constraint_type(), c->get_parameter(), c->get_rows(), c->get_cols()));
}
else
{
mexErrMsgTxt("Unknown constraint type: only integer, real or matrix constraints are available.");
}
// (*(gpu_cons.end()-1))->Display();
}
// cout << "gpu cons size:" << gpu_cons.size() << endl;
}
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
Faust::enable_gpu_mod();
#ifdef FAUST_VERBOSE
if (typeid(SCALAR) == typeid(float))
{
std::cout<<"SCALAR == float"<<std::endl;
}
if (typeid(SCALAR) == typeid(double))
{
std::cout<<"SCALAR == double"<<std::endl;
}
system("sleep 7");
#endif
if(nrhs < 2) // matrix + params + (optional use_csr and packing_RL)
mexErrMsgTxt("The number of arguments of hierarchical2020 must be 2 at least");
const mxArray* matlab_matrix = prhs[0];
const mxArray* matlab_params = prhs[1];
if(!mxIsStruct(matlab_params))
{
mexErrMsgTxt("Input must be a structure.");
}
// initialization of the matrix that will be factorized
Faust::MatDense<SCALAR,Cpu> matrix;
mxArray2FaustMat(matlab_matrix,matrix);
Faust::MatDense<SCALAR,Cpu> gpu_matrix(matrix);
auto *params = mxArray2FaustParams<SCALAR,FPP2>(matlab_params);
FPP2 lambda = params->init_lambda;
try{
auto cpu_fac_cons = params->cons[0];
auto cpu_res_cons = params->cons[1];
vector<const Faust::ConstraintGeneric*> gpu_fac_cons;
vector<const Faust::ConstraintGeneric*> gpu_res_cons;
convert_cons_vec_cpu2gpu(cpu_fac_cons, gpu_fac_cons);
convert_cons_vec_cpu2gpu(cpu_res_cons, gpu_res_cons);
bool compute_2norm_on_arrays = false;
// gpu_matrix.Display();
std::vector<Faust::StoppingCriterion<Real<SCALAR>>> sc = {params->stop_crit_2facts.get_crit(), params->stop_crit_global.get_crit()};
// cout << "gpu_fac_cons.size():" << gpu_fac_cons.size() << endl;
auto th = Faust::hierarchical<FPP2, GPU2>(gpu_matrix, sc, gpu_fac_cons, gpu_res_cons, lambda, params->isUpdateWayR2L, params->isFactSideLeft, params->use_csr, params->packing_RL, compute_2norm_on_arrays, params->norm2_threshold, params->norm2_max_iter, params->isVerbose, params->isConstantStepSize, params->step_size);
auto th_times_lambda = th->multiply(lambda);
delete th;
th = th_times_lambda;
auto cpuF = th->tocpu();
Faust::MatDense<FPP2,Cpu> mat1x1Lambda = Faust::MatDense<FPP2, Cpu>(&lambda, 1, 1);
plhs[0] = FaustMat2mxArray(mat1x1Lambda);
plhs[1] = convertPtr2Mat<Faust::TransformHelper<SCALAR, Cpu>>(cpuF);
}
catch (const std::exception& e)
{
// most likely error: compute_lambda : Xhatt_Xhat_tr is too small or Xt_Xhat.trace is too big so lambda is infinite
plhs[1] = nullptr;
mexErrMsgTxt(e.what());
}
delete params;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment