Mentions légales du service

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

Optimize faust_torch module to avoid cloning data (by default) when possible.

It's still possible to clone data using the new argument 'clone' set to the value true.

Unfortunately it's mandatory to clone indices for a sparse matrix to sparse tensor conversion because torch imposes to use the same size types for both values and indices (even if values are floats and indices integers) but Faust/eigen uses 32 bits for indices and 64 bits for data (when double is used as FPP template parameter)

[skip ci]
parent f42fb075
Branches
Tags
No related merge requests found
...@@ -9,31 +9,35 @@ namespace Faust ...@@ -9,31 +9,35 @@ namespace Faust
/** /**
* Converts a Faust::MatDense to a torch::Tensor. * Converts a Faust::MatDense to a torch::Tensor.
* *
* Unfortunately this is not a view but a copy which is not a problem when dev == at::kCUDA. * \param dev the device at::kCPU or at::kCUDA.
* \param clone true to copy the Faust matrix data to create the tensor, false to use the same data without copying (false by default).
*/ */
template<typename FPP, FDevice D> template<typename FPP, FDevice D>
void faust_MatDense_to_torch_Tensor(const Faust::MatDense<FPP,D> & dm, torch::Tensor & t, at::DeviceType dev = at::kCPU); void faust_MatDense_to_torch_Tensor(const Faust::MatDense<FPP,D> & dm, torch::Tensor & t, at::DeviceType dev = at::kCPU, const bool clone = false);
/** /**
* Converts a Faust::MatSparse to a torch::Tensor. * Converts a Faust::MatSparse to a torch::Tensor.
* *
* Unfortunately this is not a view but a copy which is not a problem when dev == at::kCUDA. *\param dev the device at::kCPU or at::kCUDA.
*\param clone true to copy the Faust matrix data to create the tensor, false to use the same data without copying (false by default).
*/ */
template<typename FPP, FDevice D> template<typename FPP, FDevice D>
void faust_MatSparse_to_torch_Tensor(Faust::MatSparse<FPP,D> & spm, torch::Tensor & t, at::DeviceType dev = at::kCPU); void faust_MatSparse_to_torch_Tensor(Faust::MatSparse<FPP,D> & spm, torch::Tensor & t, at::DeviceType dev = at::kCPU, const bool clone = false);
/** /**
* Converts a Faust::MatGeneric vector to a torch::TensorList (vector alias). * Converts a Faust::MatGeneric vector to a torch::TensorList (vector alias).
* *
* Unfortunately this is not a view but a copy which is not a problem when dev == at::kCUDA. *\param dev the device at::kCPU or at::kCUDA.
* \param clone true to copy the Faust matrices data to create the tensors, false to use the same data without copying (false by default).
*/ */
template<typename FPP, FDevice D> template<typename FPP, FDevice D>
void faust_matvec_to_torch_TensorList(const std::vector<Faust::MatGeneric<FPP,D>*> & ml, std::vector<torch::Tensor> &tl, at::DeviceType dev = at::kCPU); void faust_matvec_to_torch_TensorList(const std::vector<Faust::MatGeneric<FPP,D>*> & ml, std::vector<torch::Tensor> &tl, at::DeviceType dev = at::kCPU, const bool clone = false);
/** /**
* Computes the tensor chain product of ml and applies it optionally to the tensor op. * Computes the tensor chain product of ml and applies it optionally to the tensor op.
* *
*\param dev the device at::kCPU or at::kCUDA.
* Returns the result as a Tensor. * Returns the result as a Tensor.
*/ */
torch::Tensor tensor_chain_mul(const std::vector<torch::Tensor>& ml, const torch::Tensor* op= nullptr, at::DeviceType dev = at::kCPU); torch::Tensor tensor_chain_mul(const std::vector<torch::Tensor>& ml, const torch::Tensor* op= nullptr, at::DeviceType dev = at::kCPU);
...@@ -43,10 +47,12 @@ namespace Faust ...@@ -43,10 +47,12 @@ namespace Faust
* *
* This function converts all the matrices to Tensors before and then computes the tensor product. * This function converts all the matrices to Tensors before and then computes the tensor product.
* *
* \param on_gpu true ot use the GPU backend, false for the CPU backend (false by default).
* \param clone true to copy the Faust matrices data to create the tensors, false to use the same data without copying (false by default).
* Returns the result as a Faust::MatDense. * Returns the result as a Faust::MatDense.
*/ */
template<typename FPP, FDevice D> template<typename FPP, FDevice D>
void tensor_chain_mul(const std::vector<Faust::MatGeneric<FPP,D>*>& ml, Faust::MatDense<FPP,Cpu> & out, const Faust::MatGeneric<FPP,D>* op = nullptr, const bool on_gpu = false); void tensor_chain_mul(const std::vector<Faust::MatGeneric<FPP,D>*>& ml, Faust::MatDense<FPP,Cpu> & out, const Faust::MatGeneric<FPP,D>* op = nullptr, const bool on_gpu = false, const bool clone = false);
} }
#include "faust_torch.hpp" #include "faust_torch.hpp"
#endif #endif
...@@ -2,13 +2,13 @@ namespace Faust ...@@ -2,13 +2,13 @@ namespace Faust
{ {
template<typename FPP, FDevice D> template<typename FPP, FDevice D>
void faust_MatSparse_to_torch_Tensor(const Faust::MatSparse<FPP,D> & spm, torch::Tensor & t, at::DeviceType dev) void faust_MatSparse_to_torch_Tensor(const Faust::MatSparse<FPP,D> & spm, torch::Tensor & t, at::DeviceType dev, const bool clone)
{ {
torch::Tensor values = torch::from_blob(const_cast<FPP*>(spm.getValuePtr()), {spm.getNonZeros()}, torch::TensorOptions().dtype(torch::kFloat64).device(dev)).clone(); torch::Tensor values = torch::from_blob(const_cast<FPP*>(spm.getValuePtr()), {spm.getNonZeros()}, torch::TensorOptions().dtype(torch::kFloat64).device(dev));//.clone();
// cout << "tensor values:" << values << endl; // cout << "tensor values:" << values << endl;
torch::Tensor col = torch::from_blob(const_cast<int*>(spm.getInnerIndexPtr()), {spm.getNonZeros()}, torch::TensorOptions().dtype(torch::kI32).device(dev)).clone(); torch::Tensor col = torch::from_blob(const_cast<int*>(spm.getInnerIndexPtr()), {spm.getNonZeros()}, torch::TensorOptions().dtype(torch::kI32).device(dev));//.clone();
// cout << "tensor col:" << col << endl; // cout << "tensor col:" << col << endl;
int* rows = new int[spm.getNonZeros()]; faust_unsigned_int* rows = new faust_unsigned_int[spm.getNonZeros()];
for(int i = 0; i < spm.getNbRow(); i++) for(int i = 0; i < spm.getNbRow(); i++)
{ {
for(int j=spm.getOuterIndexPtr()[i];j < spm.getOuterIndexPtr()[i+1]; j++) for(int j=spm.getOuterIndexPtr()[i];j < spm.getOuterIndexPtr()[i+1]; j++)
...@@ -17,9 +17,15 @@ namespace Faust ...@@ -17,9 +17,15 @@ namespace Faust
// cout << " " << rows[j]; // cout << " " << rows[j];
} }
} }
torch::Tensor row = torch::from_blob(rows, {spm.getNonZeros()}, torch::TensorOptions().dtype(torch::kI32).device(dev)).clone(); torch::Tensor row = torch::from_blob(rows, {spm.getNonZeros()}, torch::TensorOptions().dtype(torch::kI64).device(dev)).clone(); // clone is mandatory for rows
row = row.to(torch::kI64); if(clone)
col = col.to(torch::kI64); {
// row = row.clone();
// col = col.clone();
values = values.clone();
}
// row = row.to(torch::kI64);
col = col.to(torch::kI64); // mandatory conversion because torch forces to use same size types for indices and values (even if indices are integers and values floats)
// cout << "tensor row:" << row << endl; // cout << "tensor row:" << row << endl;
delete [] rows; delete [] rows;
torch::Tensor indices = at::stack({row, col}, /* dim */ 0); torch::Tensor indices = at::stack({row, col}, /* dim */ 0);
...@@ -28,13 +34,15 @@ namespace Faust ...@@ -28,13 +34,15 @@ namespace Faust
} }
template<typename FPP, FDevice D> template<typename FPP, FDevice D>
void faust_MatDense_to_torch_Tensor(const Faust::MatDense<FPP,D> & dm, torch::Tensor & t, at::DeviceType dev) void faust_MatDense_to_torch_Tensor(const Faust::MatDense<FPP,D> & dm, torch::Tensor & t, at::DeviceType dev, const bool clone)
{ {
t = torch::from_blob(const_cast<FPP*>(dm.getData()), {dm.getNbRow(), dm.getNbCol()},torch::TensorOptions().dtype(torch::kFloat64).device(dev)).clone(); t = torch::from_blob(const_cast<FPP*>(dm.getData()), {dm.getNbRow(), dm.getNbCol()},torch::TensorOptions().dtype(torch::kFloat64).device(dev));//.clone();
if(clone)
t = t.clone();
} }
template<typename FPP, FDevice D> template<typename FPP, FDevice D>
void faust_matvec_to_torch_TensorList(const std::vector<Faust::MatGeneric<FPP,D>*> & ml, std::vector<torch::Tensor> &tl, at::DeviceType dev) void faust_matvec_to_torch_TensorList(const std::vector<Faust::MatGeneric<FPP,D>*> & ml, std::vector<torch::Tensor> &tl, at::DeviceType dev, const bool clone)
{ {
const Faust::MatSparse<FPP,D> *spm; const Faust::MatSparse<FPP,D> *spm;
const Faust::MatDense<FPP,D> *dm; const Faust::MatDense<FPP,D> *dm;
...@@ -42,12 +50,12 @@ namespace Faust ...@@ -42,12 +50,12 @@ namespace Faust
for(auto m : ml) for(auto m : ml)
{ {
if(spm = dynamic_cast<Faust::MatSparse<FPP,D>*>(m)) if(spm = dynamic_cast<Faust::MatSparse<FPP,D>*>(m))
faust_MatSparse_to_torch_Tensor(*spm, t, dev); faust_MatSparse_to_torch_Tensor(*spm, t, dev, clone);
else if(dm = dynamic_cast<Faust::MatDense<FPP,D>*>(m)) else if(dm = dynamic_cast<Faust::MatDense<FPP,D>*>(m))
faust_MatDense_to_torch_Tensor(*dm, t, dev); faust_MatDense_to_torch_Tensor(*dm, t, dev, clone);
tl.push_back(t); tl.push_back(t);
} }
} }
torch::Tensor tensor_chain_mul(const std::vector<torch::Tensor>& ml, const torch::Tensor* op, at::DeviceType dev) torch::Tensor tensor_chain_mul(const std::vector<torch::Tensor>& ml, const torch::Tensor* op, at::DeviceType dev)
{ {
...@@ -83,7 +91,7 @@ namespace Faust ...@@ -83,7 +91,7 @@ namespace Faust
} }
template<typename FPP, FDevice D> template<typename FPP, FDevice D>
void tensor_chain_mul(const std::vector<Faust::MatGeneric<FPP,D>*>& ml, Faust::MatDense<FPP,Cpu> & out, const Faust::MatGeneric<FPP,D>* op, const bool on_gpu) void tensor_chain_mul(const std::vector<Faust::MatGeneric<FPP,D>*>& ml, Faust::MatDense<FPP,Cpu> & out, const Faust::MatGeneric<FPP,D>* op, const bool on_gpu, const bool clone)
{ {
std::vector<torch::Tensor> tl; std::vector<torch::Tensor> tl;
faust_matvec_to_torch_TensorList(ml, tl); faust_matvec_to_torch_TensorList(ml, tl);
...@@ -93,9 +101,9 @@ namespace Faust ...@@ -93,9 +101,9 @@ namespace Faust
if(op) if(op)
{ {
if(spm = dynamic_cast<const Faust::MatSparse<FPP,D>*>(op)) if(spm = dynamic_cast<const Faust::MatSparse<FPP,D>*>(op))
faust_MatSparse_to_torch_Tensor(*spm, top, on_gpu?at::kCUDA:at::kCPU); faust_MatSparse_to_torch_Tensor(*spm, top, on_gpu?at::kCUDA:at::kCPU, clone);
else if(dm = dynamic_cast<const Faust::MatDense<FPP,D>*>(op)) else if(dm = dynamic_cast<const Faust::MatDense<FPP,D>*>(op))
faust_MatDense_to_torch_Tensor(*dm, top, on_gpu?at::kCUDA:at::kCPU); faust_MatDense_to_torch_Tensor(*dm, top, on_gpu?at::kCUDA:at::kCPU, clone);
tres = tensor_chain_mul(tl, &top, on_gpu?at::kCUDA:at::kCPU); tres = tensor_chain_mul(tl, &top, on_gpu?at::kCUDA:at::kCPU);
} }
else else
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment