Mentions légales du service

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

Fix a segfault in EigTJParallelSparse C++ test.

The bug was due to a buffer over-read in `choices' MATIO variable because of a wrong hard-coded value of J (used next as size of choices).
Now the dimensions are dynamically obtained from the .mat file.
Other change: use the proper function Mat_VarFree instead of system free() for freeing the variable.
parent 3d23639a
Branches
Tags
No related merge requests found
Pipeline #853469 passed
#include "faust_EigTJParallel.h" #include "faust_EigTJParallel.h"
#include "faust_MatDense.h" #include "faust_MatDense.h"
#include "faust_init_from_matio_params.h" #include "faust_init_from_matio_params.h"
#include "faust_init_from_matio_core.h" #include "faust_init_from_matio_core.h"
#include <complex> #include <complex>
using namespace Faust; using namespace Faust;
typedef @TEST_FPP@ FPP; typedef @TEST_FPP@ FPP;
typedef @TEST_FPP2@ FPP2; typedef @TEST_FPP2@ FPP2;
/*** /***
* This test results have to be compared with what misc/test/src/Matlab/test_GivensDiagPar.m outputs. * This test results have to be compared with what misc/test/src/Matlab/test_GivensDiagPar.m outputs.
* That's a way to validate the C++ impl. of Parallel EigTJ. * That's a way to validate the C++ impl. of Parallel EigTJ.
*/ */
int main() int main()
{ {
string configFilename = "@FAUST_DATA_MAT_DIR@/test_GivensDiagParallel_Lap_U_J_choices.mat"; string configFilename = "@FAUST_DATA_MAT_DIR@/test_GivensDiagParallel_Lap_U_J_choices.mat";
Faust::MatDense<FPP,Cpu> Lap; Faust::MatDense<FPP,Cpu> Lap;
Faust::MatSparse<FPP,Cpu> sLap; Faust::MatSparse<FPP,Cpu> sLap;
init_faust_mat_from_matio(Lap,configFilename.c_str(),"Lap"); init_faust_mat_from_matio(Lap,configFilename.c_str(),"Lap");
sLap = Lap; sLap = Lap;
int J = 5472; //TODO: should be retrieved from .mat file (not be a hard-coded value)
EigTJParallel<FPP,Cpu, FPP> algo(sLap,J,/*t=*/ Lap.getNbRow()/2,
/*verbosity */ 0, /* stoppingError */ 0.0, /* errIsRel */ true, /* enable_large_Faust */ true); mat_t *matfp;
algo.compute_facts(); matfp = Mat_Open(configFilename.c_str(),MAT_ACC_RDONLY);
if ( NULL == matfp ) {
vector<pair<int,int>> coord_choices = algo.get_coord_choices(); fprintf(stderr,"Error opening MAT file %s", configFilename.c_str());
return EXIT_FAILURE;
mat_t *matfp; }
auto mv_info = Mat_VarReadInfo(matfp, "choices");
matfp = Mat_Open(configFilename.c_str(),MAT_ACC_RDONLY); matvar_t* cell_choices = Mat_VarRead(matfp, "choices");
if ( NULL == matfp ) { // Mat_VarPrint(cell_choices, 0);
fprintf(stderr,"Error opening MAT file %s", configFilename.c_str()); int J = cell_choices->dims[1];
return EXIT_FAILURE; EigTJParallel<FPP,Cpu, FPP> algo(sLap,J,/*t=*/ Lap.getNbRow()/2,
} /*verbosity */ 0, /* stoppingError */ 0.0, /* errIsRel */ true, /* enable_large_Faust */ true);
matvar_t* cell_choices = Mat_VarRead(matfp, "choices");
int* p_choices = new int[J]; algo.compute_facts();
int* q_choices = new int[J];
cout << "=======================================" << endl; vector<pair<int,int>> coord_choices = algo.get_coord_choices();
if ( NULL != cell_choices) { int* p_choices = new int[J];
for (int i = 0; i < J*2; i+=2 ) int* q_choices = new int[J];
{ cout << "=======================================" << endl;
p_choices[i/2] = (int)((double*) (cell_choices->data))[i]; if ( NULL != cell_choices) {
q_choices[i/2] = (int)((double*) (cell_choices->data))[i+1]; for (int i = 0; i < J*2; i+=2 )
} {
free(cell_choices); p_choices[i/2] = (int)((double*) (cell_choices->data))[i];
} q_choices[i/2] = (int)((double*) (cell_choices->data))[i+1];
Mat_Close(matfp); }
Mat_VarFree(cell_choices);
for(int j=0;j<J;j++) }
printf("ite=%d (1-base index) ref. p=%d q=%d, algo. p=%d q=%d eq=%d\n", j, p_choices[j], q_choices[j], coord_choices[j].first+1, coord_choices[j].second+1, p_choices[j] == coord_choices[j].first+1 && q_choices[j] == coord_choices[j].second+1); Mat_Close(matfp);
for(int j=0;j<J;j++)
Faust::MatDense<FPP,Cpu> fourier_diag(Lap.getNbRow(), Lap.getNbCol()); printf("ite=%d (1-base index) ref. p=%d q=%d, algo. p=%d q=%d eq=%d\n", j, p_choices[j], q_choices[j], coord_choices[j].first+1, coord_choices[j].second+1, p_choices[j] == coord_choices[j].first+1 && q_choices[j] == coord_choices[j].second+1);
fourier_diag.setEyes();
const vector<Faust::MatSparse<FPP,Cpu>>& givens_facts = algo.get_facts();
for(int i=givens_facts.size()-1;i>=0;i--) Faust::MatDense<FPP,Cpu> fourier_diag(Lap.getNbRow(), Lap.getNbCol());
givens_facts[i].multiply(fourier_diag, 'N'); fourier_diag.setEyes();
const vector<Faust::MatSparse<FPP,Cpu>>& givens_facts = algo.get_facts();
cout << "fourier_diag fro norm: " << fourier_diag.norm() << endl; for(int i=givens_facts.size()-1;i>=0;i--)
givens_facts[i].multiply(fourier_diag, 'N');
const Faust::MatSparse<FPP,Cpu> D = algo.get_Dspm();
Faust::MatDense<FPP,Cpu> full_D = Faust::MatDense<FPP,Cpu>(D); cout << "fourier_diag fro norm: " << fourier_diag.norm() << endl;
cout << "D fro norm:" << D.norm() << endl;
const Faust::MatSparse<FPP,Cpu> D = algo.get_Dspm();
Faust::MatDense<FPP,Cpu> fourier_diag2 = algo.compute_fourier(); Faust::MatDense<FPP,Cpu> full_D = Faust::MatDense<FPP,Cpu>(D);
Faust::MatDense<FPP,Cpu> ordered_fourier_diag2 = algo.compute_fourier(true); cout << "D fro norm:" << D.norm() << endl;
Faust::MatDense<FPP,Cpu> * ordered_fourier_diag = fourier_diag.get_cols(algo.get_ord_indices()); Faust::MatDense<FPP,Cpu> fourier_diag2 = algo.compute_fourier();
Faust::MatDense<FPP,Cpu> ordered_fourier_diag2 = algo.compute_fourier(true);
fourier_diag2 -= fourier_diag;
ordered_fourier_diag2 -= *ordered_fourier_diag; Faust::MatDense<FPP,Cpu> * ordered_fourier_diag = fourier_diag.get_cols(algo.get_ord_indices());
cout << "norm(fourier_diag2-fourier_diag): " << fourier_diag2.norm() << endl;
cout << "norm(ordered_fourier_diag2-ordered_fourier_diag): " << ordered_fourier_diag2.norm() << endl; fourier_diag2 -= fourier_diag;
ordered_fourier_diag2 -= *ordered_fourier_diag;
//verify approx. fourier is properly computed (when ordered or not) cout << "norm(fourier_diag2-fourier_diag): " << fourier_diag2.norm() << endl;
assert(fourier_diag2.norm()==0); cout << "norm(ordered_fourier_diag2-ordered_fourier_diag): " << ordered_fourier_diag2.norm() << endl;
assert(ordered_fourier_diag2.norm()==0);
//verify approx. fourier is properly computed (when ordered or not)
Faust::MatDense<FPP,Cpu> ordered_D(algo.get_Dspm(true)); assert(fourier_diag2.norm()==0);
assert(ordered_fourier_diag2.norm()==0);
cout << "orderded D fro norm: " << ordered_D.norm() << endl;
cout << "ordered_D:" << endl; Faust::MatDense<FPP,Cpu> ordered_D(algo.get_Dspm(true));
ordered_D.Display();
cout << "orderded D fro norm: " << ordered_D.norm() << endl;
cout << "ordered D eles" << endl; cout << "ordered_D:" << endl;
for(int i=0;i<ordered_D.getNbRow();i++) ordered_D.Display();
{
cout << ordered_D.getData()[i*ordered_D.getNbRow()+i] << " " << full_D(i,i) << endl; cout << "ordered D eles" << endl;
} for(int i=0;i<ordered_D.getNbRow();i++)
{
cout << "ordered fourier_diag fro norm: " << ordered_fourier_diag->norm() << endl; cout << ordered_D.getData()[i*ordered_D.getNbRow()+i] << " " << full_D(i,i) << endl;
cout << "Lap fro norm: " << Lap.norm() << endl; }
Faust::MatDense<FPP,Cpu> tmp = *ordered_fourier_diag; cout << "ordered fourier_diag fro norm: " << ordered_fourier_diag->norm() << endl;
tmp.multiplyRight(ordered_D); cout << "Lap fro norm: " << Lap.norm() << endl;
ordered_fourier_diag->transpose();
tmp.multiplyRight(*ordered_fourier_diag); Faust::MatDense<FPP,Cpu> tmp = *ordered_fourier_diag;
ordered_fourier_diag->transpose(); tmp.multiplyRight(ordered_D);
tmp -= Lap; ordered_fourier_diag->transpose();
cout << tmp.norm()/Lap.norm() << endl; tmp.multiplyRight(*ordered_fourier_diag);
ordered_fourier_diag->transpose();
delete []p_choices; tmp -= Lap;
delete []q_choices; cout << tmp.norm()/Lap.norm() << endl;
return 0;
} delete []p_choices;
delete []q_choices;
return 0;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment