Mentions légales du service

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

Add to MatSparse<FPP, GPU2> the member functions: operator=, operator==,...

Add to MatSparse<FPP, GPU2> the member functions: operator=, operator==, operator/=, operator==, operator!=, operator*= (scalar mul.), setIdentity, move and related unit tests (update to gpu_mod@3f55a2f8).
parent 90ce47e2
No related branches found
No related tags found
No related merge requests found
Subproject commit aff4369adf4a328d9346610697ec449c3c97313c
Subproject commit 3f55a2f8b0b67b716e5dbad488ad22be75415afc
......@@ -136,6 +136,26 @@ void test_gpu_ctor_and_tocpu2()
delete cpu_sp_mat;
}
void test_eq_operator_rhs_cpu()
{
cout << "test MatSparse<FPP,GPU2>::operator=(MatSparse<FPP,Cpu>" << endl;
auto nrows = 5;
auto ncols = 8;
auto cpu_sp_mat = Faust::MatSparse<double, Cpu>::randMat(nrows, ncols, .2);
auto cpu_sp_mat2 = Faust::MatSparse<double, Cpu>::randMat(nrows+1, ncols+4, .2);
Faust::MatSparse<double, Cpu> cpu_sp_mat3;
Faust::MatSparse<double, GPU2> gpu_sp_mat(*cpu_sp_mat);
gpu_sp_mat = *cpu_sp_mat2;
gpu_sp_mat.tocpu(cpu_sp_mat3);
assert(gpu_sp_mat.norm() == cpu_sp_mat2->norm());
MatDense<double, Cpu> diff_mat = *cpu_sp_mat2;
diff_mat -= MatDense<double, Cpu>(cpu_sp_mat3);
assert(diff_mat.norm() < 1e-3);
cout << "OK" << endl;
delete cpu_sp_mat;
delete cpu_sp_mat2;
}
void test_copy()
{
cout << "test MatSparse<FPP,GPU2>::copy" << endl;
......@@ -148,6 +168,7 @@ void test_copy()
Faust::MatSparse<double, GPU2> gpu_sp_mat(*cpu_sp_mat);
Faust::MatSparse<double, GPU2> gpu_sp_mat2(*cpu_sp_mat2);
gpu_sp_mat = gpu_sp_mat2;
assert(std::abs(gpu_sp_mat.norm() - cpu_sp_mat2->norm()) < 1e-3);
cout << "OK" << endl;
}
......@@ -169,6 +190,24 @@ void test_clone()
cout << "OK" << endl;
}
void test_move()
{
// TODO: really test on several devices if available with a specially created stream
cout << "test MatSparse<FPP,GPU2>::move" << endl;
auto nrows = 5;
auto ncols = 8;
auto cpu_sp_mat = Faust::MatSparse<double, Cpu>::randMat(nrows, ncols, .2);
Faust::MatSparse<double, GPU2> gpu_sp_mat(*cpu_sp_mat);
Faust::MatSparse<double, Cpu> cpu_sp_mat2;
gpu_sp_mat.move(/*dev_id*/-1, /*stream*/ nullptr);
gpu_sp_mat.tocpu(cpu_sp_mat2);
MatDense<double, Cpu> diff_mat = *cpu_sp_mat;
diff_mat -= MatDense<double, Cpu>(cpu_sp_mat2);
assert(diff_mat.norm() < 1e-3);
delete cpu_sp_mat;
cout << "OK" << endl;
}
void test_set_eyes()
{
cout << "test MatSparse<FPP,GPU2>::setEyes" << endl;
......@@ -188,6 +227,26 @@ void test_set_eyes()
cout << "OK" << endl;
}
void test_set_id()
{
cout << "test MatSparse<FPP,GPU2>::setIdentity" << endl;
auto nrows = 5;
auto ncols = 8;
auto cpu_sp_mat = Faust::MatSparse<double, Cpu>::randMat(nrows, ncols, .2);
Faust::MatSparse<double, GPU2> gpu_sp_mat(*cpu_sp_mat);
cpu_sp_mat->resize(55,55);
cpu_sp_mat->setEyes(); // setIdentity not implemented in MatSparse<FPP,Cpu>
Faust::MatSparse<double, Cpu> cpu_sp_mat2;
gpu_sp_mat.setIdentity(55);
gpu_sp_mat.tocpu(cpu_sp_mat2);
assert(gpu_sp_mat.norm() == gpu_sp_mat.norm());
MatDense<double, Cpu> diff_mat = *cpu_sp_mat;
diff_mat -= MatDense<double, Cpu>(cpu_sp_mat2);
assert(diff_mat.norm() < 1e-3);
delete cpu_sp_mat;
cout << "OK" << endl;
}
void test_set_zeros()
{
cout << "test MatSparse<FPP,GPU2>::setZeros" << endl;
......@@ -235,12 +294,45 @@ void test_resize()
delete cpu_sp_mat;
}
void test_scal_mul()
{
cout << "test MatSparse<FPP,GPU2>::operator*=(const FPP &scal)" << endl;
auto nrows = 5;
auto ncols = 8;
double scalar = 55.;
auto cpu_sp_mat = Faust::MatSparse<double, Cpu>::randMat(nrows, ncols, .2);
MatDense<double, Cpu> cpu_ds_mat(*cpu_sp_mat);
Faust::MatSparse<double, GPU2> gpu_sp_mat(*cpu_sp_mat);
cpu_ds_mat *= scalar;
gpu_sp_mat *= scalar;
assert(std::abs(gpu_sp_mat.norm() - cpu_ds_mat.norm()) < 1e-3);
cout << "OK" << endl;
delete cpu_sp_mat;
}
void test_is_equal()
{
cout << "test MatSparse<FPP,GPU2>::operator==(const MatSparse<FPP,GPU2>& mat)" << endl;
auto nrows = 5;
auto ncols = 8;
auto cpu_sp_mat = Faust::MatSparse<double, Cpu>::randMat(nrows, ncols, .2);
auto cpu_sp_mat2 = Faust::MatSparse<double, Cpu>::randMat(nrows+1, ncols+4, .2);
Faust::MatSparse<double, GPU2> gpu_sp_mat(*cpu_sp_mat);
Faust::MatSparse<double, GPU2> gpu_sp_mat2(*cpu_sp_mat2);
Faust::MatSparse<double, GPU2> gpu_sp_mat3(*cpu_sp_mat2);
assert(gpu_sp_mat == gpu_sp_mat);
assert(gpu_sp_mat2 == gpu_sp_mat2);
assert(gpu_sp_mat3 != gpu_sp_mat2);
cout << "OK" << endl;
}
int main()
{
Faust::enable_gpu_mod();
test_gpu_norm();
test_gpu_ctor_and_tocpu();
test_gpu_ctor_and_tocpu2();
test_eq_operator_rhs_cpu();
test_transpose();
test_adjoint();
test_conjugate();
......@@ -249,4 +341,8 @@ int main()
test_set_eyes();
test_clone();
test_copy();
test_scal_mul();
test_set_id();
test_move();
test_is_equal();
}
......@@ -41,6 +41,11 @@ namespace Faust
const void* stream=nullptr);
void operator=(const MatSparse<FPP, GPU2>& mat);
void operator=(const MatSparse<FPP, Cpu>& mat);
void operator*=(const FPP& alpha);
void operator/=(const FPP& alpha);
bool operator==(const MatSparse<FPP, GPU2>& mat) const;
bool operator!=(const MatSparse<FPP, GPU2>& mat) const;
void tocpu(MatSparse<FPP,Cpu> &sp_mat);
Real<FPP> norm();
......@@ -50,8 +55,10 @@ namespace Faust
void resize(int32_t nnz, int32_t nrows, int32_t ncols);
void setEyes();
void setIdentity(int32_t dim);
void setZeros();
MatSparse<FPP, GPU2>* clone(const int32_t dev_id=-1, const void* stream=nullptr);
void move(const int32_t dev_id=-1, const void* stream=nullptr);
int32_t getNbRow();
int32_t getNbCol();
int32_t getNonZeros();
......
......@@ -21,9 +21,9 @@ namespace Faust
this->spm_funcs = FaustGPU<@FAUST_SCALAR_FOR_GM@>::spm_funcs;
if(this->gp_funcs == nullptr)
this->gp_funcs = FaustGPU<@FAUST_SCALAR_FOR_GM@>::gp_funcs;
auto spm_funcs = (gm_SparseMatFunc_@FAUST_SCALAR_FOR_GM@*) this->spm_funcs;
if(values != nullptr)
{
auto spm_funcs = (gm_SparseMatFunc_@FAUST_SCALAR_FOR_GM@*) this->spm_funcs;
auto gp_funcs = ((gm_GenPurposeFunc_@GM_SCALAR@*)this->gp_funcs);
if(rowptr == nullptr || colinds == nullptr)
throw std::runtime_error("All GPU buffers or none must be defined to instantiate a MatSparse<FPP,GPU2>.");
......@@ -31,7 +31,7 @@ namespace Faust
gp_funcs->set_dev(dev_id);
gpu_mat = spm_funcs->togpu_stream(nbRow, nbCol, nnz, rowptr, colinds, values, stream);
gp_funcs->set_dev(cur_dev_id);
spm_funcs->info(gpu_mat, &this->nbRow, &this->nbCol, /*nnz*/ nullptr); //normally useless, but just in case
spm_funcs->info(gpu_mat, &this->nbRow, &this->nbCol, /*nnz*/ nullptr); //normally useless (bcause dims are already initialized), but init from GPU again just in case of inconsistency that would show up in tests
}
else gpu_mat = nullptr;
}
......@@ -39,16 +39,19 @@ namespace Faust
template<>
Faust::MatSparse<@FAUST_SCALAR_FOR_GM@,GPU2>::~MatSparse()
{
auto spm_funcs = ((gm_SparseMatFunc_@GM_SCALAR@*) this->spm_funcs);
spm_funcs->free(gpu_mat);
if(gpu_mat != nullptr)
{
auto spm_funcs = ((gm_SparseMatFunc_@GM_SCALAR@*) this->spm_funcs);
spm_funcs->free(gpu_mat);
}
}
// must be after the called ctor and the dtor to avoid an error "specialization after instantiation"
template<>
MatSparse<@FAUST_SCALAR_FOR_GM@,GPU2>::MatSparse(
const MatSparse<@FAUST_SCALAR_FOR_GM@, Cpu>& M,
const int32_t dev_id,
const void* stream) : MatSparse<@FAUST_SCALAR_FOR_GM@,GPU2>(M.getNbRow(),
const int32_t dev_id/*=-1*/,
const void* stream/*=nullptr*/) : MatSparse<@FAUST_SCALAR_FOR_GM@,GPU2>(M.getNbRow(),
M.getNbCol(), M.getNonZeros(), M.getValuePtr(), M.getRowPtr(), M.getColInd(), dev_id, stream)
{
}
......@@ -70,6 +73,45 @@ namespace Faust
nbCol = mat.nbCol;
}
template<>
bool MatSparse<@FAUST_SCALAR_FOR_GM@,GPU2>::operator==(const MatSparse<@FAUST_SCALAR_FOR_GM@, GPU2>& mat) const
{
auto spm_funcs = ((gm_SparseMatFunc_@GM_SCALAR@*) this->spm_funcs);
return spm_funcs->is_equal(gpu_mat, mat.gpu_mat);
}
template<>
bool MatSparse<@FAUST_SCALAR_FOR_GM@,GPU2>::operator!=(const MatSparse<@FAUST_SCALAR_FOR_GM@, GPU2>& mat) const
{
return ! ((*this) == mat);
}
template<>
void MatSparse<@FAUST_SCALAR_FOR_GM@,GPU2>::operator*=(const @FAUST_SCALAR_FOR_GM@& scalar)
{
auto spm_funcs = ((gm_SparseMatFunc_@GM_SCALAR@*) this->spm_funcs);
spm_funcs->mul_scalar(gpu_mat, reinterpret_cast<const @GM_REINTERPRET_CAST_SCALAR@*>(&scalar));
}
template<>
void MatSparse<@FAUST_SCALAR_FOR_GM@,GPU2>::operator/=(const @FAUST_SCALAR_FOR_GM@& scalar)
{
*this *= ((@FAUST_SCALAR_FOR_GM@)1)/scalar;
}
template<>
void MatSparse<@FAUST_SCALAR_FOR_GM@,GPU2>::operator=(const MatSparse<@FAUST_SCALAR_FOR_GM@, Cpu>& mat)
{
// copy on current device
MatSparse<@FAUST_SCALAR_FOR_GM@, GPU2> gmat(mat);
auto spm_funcs = (gm_SparseMatFunc_@FAUST_SCALAR_FOR_GM@*) this->spm_funcs;
spm_funcs->free(this->gpu_mat);
this->gpu_mat = gmat.gpu_mat;
this->nbRow = gmat.nbRow;
this->nbCol = gmat.nbCol;
gmat.gpu_mat = nullptr; // to avoid freeing the new gpu_mat when leaving this scope
}
template<>
void MatSparse<@FAUST_SCALAR_FOR_GM@,GPU2>::tocpu(MatSparse<@FAUST_SCALAR_FOR_GM@, Cpu> & sp_mat)
{
......@@ -118,6 +160,25 @@ namespace Faust
spm_funcs->set_eyes(gpu_mat);
}
template<>
void Faust::MatSparse<@FAUST_SCALAR_FOR_GM@, GPU2>::resize(int32_t nnz, int32_t nrows, int32_t ncols)
{
nbRow = nrows;
nbCol = ncols;
auto spm_funcs = ((gm_SparseMatFunc_@GM_SCALAR@*) this->spm_funcs);
spm_funcs->resize(gpu_mat, nnz, nrows, ncols);
}
template<>
void Faust::MatSparse<@FAUST_SCALAR_FOR_GM@,GPU2>::setIdentity(int32_t dim)
{
auto spm_funcs = ((gm_SparseMatFunc_@GM_SCALAR@*) this->spm_funcs);
resize(dim, dim, dim);
setEyes();
}
template<>
void Faust::MatSparse<@FAUST_SCALAR_FOR_GM@,GPU2>::setZeros()
{
......@@ -146,12 +207,13 @@ namespace Faust
}
template<>
void Faust::MatSparse<@FAUST_SCALAR_FOR_GM@, GPU2>::resize(int32_t nnz, int32_t nrows, int32_t ncols)
void Faust::MatSparse<@FAUST_SCALAR_FOR_GM@,GPU2>::move(const int32_t dev_id/*=-1*/, const void* stream/*=nullptr*/)
{
nbRow = nrows;
nbCol = ncols;
auto spm_funcs = ((gm_SparseMatFunc_@GM_SCALAR@*) this->spm_funcs);
spm_funcs->resize(gpu_mat, nnz, nrows, ncols);
auto spm_funcs = ((gm_SparseMatFunc_@GM_SCALAR@*)this->spm_funcs);
//TODO: backup possible pre-existing stream to restore it afterward
spm_funcs->set_stream(gpu_mat, stream);
spm_funcs->mv_to_gpu(gpu_mat, dev_id);
spm_funcs->set_stream(gpu_mat, nullptr);
}
template<>
......@@ -159,6 +221,7 @@ namespace Faust
{
return nbRow;
}
template<>
int32_t Faust::MatSparse<@FAUST_SCALAR_FOR_GM@, GPU2>::getNbCol()
{
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment