returning sparse matrix in compressed format

issue#70
Michel Juillard 2013-10-13 17:49:10 +02:00
parent 6e0ef026ac
commit 17d0177276
2 changed files with 98 additions and 163 deletions

View File

@ -4511,10 +4511,8 @@ DynamicModel::writeSecondDerivativesCC_csr(const string &basename, bool cuda) co
deriv_node_temp_terms_t tef_terms; deriv_node_temp_terms_t tef_terms;
// Indexing derivatives in column order // Indexing derivatives in column order
vector<int> d_order(NNZDerivatives[1]); vector<derivative> D;
OrderByLinearAddress obla(NNZDerivatives[1]); int hessianColsNbr = dynJacobianColsNbr*dynJacobianColsNbr;
int counter = 0;
int dynHessianColsNbr = dynJacobianColsNbr*dynJacobianColsNbr;
for (second_derivatives_t::const_iterator it = second_derivatives.begin(); for (second_derivatives_t::const_iterator it = second_derivatives.begin();
it != second_derivatives.end(); it++) it != second_derivatives.end(); it++)
{ {
@ -4526,61 +4524,32 @@ DynamicModel::writeSecondDerivativesCC_csr(const string &basename, bool cuda) co
int id2 = getDynJacobianCol(var2); int id2 = getDynJacobianCol(var2);
int col_nb = id1 * dynJacobianColsNbr + id2; int col_nb = id1 * dynJacobianColsNbr + id2;
int col_nb_sym = id2 * dynJacobianColsNbr + id1;
obla.linear_address[counter] = col_nb + eq*dynHessianColsNbr; derivative deriv(col_nb + eq*hessianColsNbr,col_nb,eq,it->second);
d_order[counter] = counter; D.push_back(deriv);
++counter;
if (id1 != id2) if (id1 != id2)
{ {
obla.linear_address[counter] = col_nb_sym + eq*dynHessianColsNbr; col_nb = id2 * dynJacobianColsNbr + id1;
d_order[counter] = counter; derivative deriv(col_nb + eq*hessianColsNbr,col_nb,eq,it->second);
++counter; D.push_back(deriv);
} }
} }
sort(d_order.begin(), d_order.end(), obla); sort(D.begin(), D.end(), derivative_less_than() );
// Writing Hessian // Writing Hessian
vector<int> row_ptr(equations.size()); vector<int> row_ptr(equations.size());
fill(row_ptr.begin(),row_ptr.end(),0.0); fill(row_ptr.begin(),row_ptr.end(),0.0);
int k = 0; // Keep the order of a 2nd derivative int k = 0;
for (second_derivatives_t::const_iterator it = second_derivatives.begin(); for(vector<derivative>::const_iterator it = D.begin(); it != D.end(); ++it)
it != second_derivatives.end(); it++)
{ {
int eq = it->first.first; row_ptr[it->row_nbr]++;
int var1 = it->first.second.first; mDynamicModelFile << "col_ptr[" << k << "] "
int var2 = it->first.second.second; << "=" << it->col_nbr << ";" << endl;
expr_t d2 = it->second; mDynamicModelFile << "value[" << k << "] = ";
int id1 = getDynJacobianCol(var1);
int id2 = getDynJacobianCol(var2);
int col_nb = id1 * dynJacobianColsNbr + id2;
int col_nb_sym = id2 * dynJacobianColsNbr + id1;
row_ptr[eq]++;
mDynamicModelFile << "col_ptr[" << d_order[k] << "] "
<< "=" << col_nb << ";" << endl;
mDynamicModelFile << "value[" << d_order[k] << "] = ";
// oCstaticModel makes reference to the static variables // oCstaticModel makes reference to the static variables
d2->writeOutput(mDynamicModelFile, oCStaticModel, temporary_terms, tef_terms); it->value->writeOutput(mDynamicModelFile, oCStaticModel, temporary_terms, tef_terms);
mDynamicModelFile << ";" << endl; mDynamicModelFile << ";" << endl;
k++; k++;
// Treating symetric elements
if (id1 != id2)
{
row_ptr[eq]++;
mDynamicModelFile << "col_ptr[" << d_order[k] << "] "
<< "=" << col_nb_sym << ";" << endl;
mDynamicModelFile << "value[" << d_order[k] << "] = ";
// oCstaticModel makes reference to the static variables
d2->writeOutput(mDynamicModelFile, oCStaticModel, temporary_terms, tef_terms);
mDynamicModelFile << ";" << endl;
k++;
}
} }
// row_ptr must point to the relative address of the first element of the row // row_ptr must point to the relative address of the first element of the row
@ -4634,11 +4603,9 @@ DynamicModel::writeThirdDerivativesCC_csr(const string &basename, bool cuda) con
// this is always empty here, but needed by d1->writeOutput // this is always empty here, but needed by d1->writeOutput
deriv_node_temp_terms_t tef_terms; deriv_node_temp_terms_t tef_terms;
// Indexing derivatives in column order vector<derivative> D;
vector<int> d_order(NNZDerivatives[1]); int hessianColsNbr = dynJacobianColsNbr*dynJacobianColsNbr;
OrderByLinearAddress obla(NNZDerivatives[1]); int thirdDerivativesColsNbr = hessianColsNbr*dynJacobianColsNbr;
int counter = 0;
int dynHessianColsNbr = dynJacobianColsNbr*dynJacobianColsNbr;
for (third_derivatives_t::const_iterator it = third_derivatives.begin(); for (third_derivatives_t::const_iterator it = third_derivatives.begin();
it != third_derivatives.end(); it++) it != third_derivatives.end(); it++)
{ {
@ -4646,114 +4613,81 @@ DynamicModel::writeThirdDerivativesCC_csr(const string &basename, bool cuda) con
int var1 = it->first.second.first; int var1 = it->first.second.first;
int var2 = it->first.second.second.first; int var2 = it->first.second.second.first;
int var3 = it->first.second.second.second; int var3 = it->first.second.second.second;
expr_t d3 = it->second;
int id1 = getDynJacobianCol(var1); int id1 = getDynJacobianCol(var1);
int id2 = getDynJacobianCol(var2); int id2 = getDynJacobianCol(var2);
int id3 = getDynJacobianCol(var3); int id3 = getDynJacobianCol(var3);
// Reference column number for the g3 matrix // Reference column number for the g3 matrix (with symmetrical derivatives)
int ref_col = id1 * hessianColsNbr + id2 * dynJacobianColsNbr + id3; vector<long unsigned int> cols;
long unsigned int col_nb = id1 * hessianColsNbr + id2 * dynJacobianColsNbr + id3;
sparseHelper(3, mDynamicModelFile, k, 0, oCDynamicModel); int thirdDColsNbr = hessianColsNbr*dynJacobianColsNbr;
mDynamicModelFile << "=" << eq + 1 << ";" << endl; derivative deriv(col_nb + eq*thirdDColsNbr,col_nb,eq,it->second);
D.push_back(deriv);
sparseHelper(3, mDynamicModelFile, k, 1, oCDynamicModel); cols.push_back(col_nb);
mDynamicModelFile << "=" << ref_col + 1 << ";" << endl; col_nb = id1 * hessianColsNbr + id3 * dynJacobianColsNbr + id2;
if (find(cols.begin(),cols.end(),col_nb) == cols.end())
sparseHelper(3, mDynamicModelFile, k, 2, oCDynamicModel); {
mDynamicModelFile << "="; derivative deriv(col_nb + eq*thirdDerivativesColsNbr,col_nb,eq,it->second);
// oCstaticModel makes reference to the static variables D.push_back(deriv);
d3->writeOutput(mDynamicModelFile, oCStaticModel, temporary_terms, tef_terms); cols.push_back(col_nb);
mDynamicModelFile << ";" << endl; }
col_nb = id2 * hessianColsNbr + id1 * dynJacobianColsNbr + id3;
// Compute the column numbers for the 5 other permutations of (id1,id2,id3) and store them in a set (to avoid duplicates if two indexes are equal) if (find(cols.begin(),cols.end(),col_nb) == cols.end())
set<int> cols; {
cols.insert(id1 * hessianColsNbr + id3 * dynJacobianColsNbr + id2); derivative deriv(col_nb + eq*thirdDerivativesColsNbr,col_nb,eq,it->second);
cols.insert(id2 * hessianColsNbr + id1 * dynJacobianColsNbr + id3); D.push_back(deriv);
cols.insert(id2 * hessianColsNbr + id3 * dynJacobianColsNbr + id1); cols.push_back(col_nb);
cols.insert(id3 * hessianColsNbr + id1 * dynJacobianColsNbr + id2); }
cols.insert(id3 * hessianColsNbr + id2 * dynJacobianColsNbr + id1); col_nb = id2 * hessianColsNbr + id3 * dynJacobianColsNbr + id1;
if (find(cols.begin(),cols.end(),col_nb) == cols.end())
int k2 = 1; // Keeps the offset of the permutation relative to k {
for (set<int>::iterator it2 = cols.begin(); it2 != cols.end(); it2++) derivative deriv(col_nb + eq*thirdDerivativesColsNbr,col_nb,eq,it->second);
if (*it2 != ref_col) D.push_back(deriv);
{ cols.push_back(col_nb);
sparseHelper(3, mDynamicModelFile, k+k2, 0, oCDynamicModel); }
mDynamicModelFile << "=" << eq + 1 << ";" << endl; col_nb = id3 * hessianColsNbr + id1 * dynJacobianColsNbr + id2;
if (find(cols.begin(),cols.end(),col_nb) == cols.end())
sparseHelper(3, mDynamicModelFile, k+k2, 1, oCDynamicModel); {
mDynamicModelFile << "=" << *it2 + 1 << ";" << endl; derivative deriv(col_nb + eq*thirdDerivativesColsNbr,col_nb,eq,it->second);
D.push_back(deriv);
sparseHelper(3, mDynamicModelFile, k+k2, 2, oCDynamicModel); cols.push_back(col_nb);
mDynamicModelFile << "="; }
sparseHelper(3, mDynamicModelFile, k, 2, oCDynamicModel); col_nb = id3 * hessianColsNbr + id2 * dynJacobianColsNbr + id1;
mDynamicModelFile << ";" << endl; if (find(cols.begin(),cols.end(),col_nb) == cols.end())
{
k2++; derivative deriv(col_nb + eq*thirdDerivativesColsNbr,col_nb,eq,it->second);
} D.push_back(deriv);
k += k2; }
} }
// Writing third derivatives sort(D.begin(), D.end(), derivative_less_than() );
int hessianColsNbr = dynJacobianColsNbr * dynJacobianColsNbr;
int k = 0; // Keep the line of a 3rd derivative in v3 vector<int> row_ptr(equations.size());
for (third_derivatives_t::const_iterator it = third_derivatives.begin(); fill(row_ptr.begin(),row_ptr.end(),0.0);
it != third_derivatives.end(); it++) int k = 0;
for(vector<derivative>::const_iterator it = D.begin(); it != D.end(); ++it)
{ {
int eq = it->first.first; row_ptr[it->row_nbr]++;
int var1 = it->first.second.first; mDynamicModelFile << "col_ptr[" << k << "] "
int var2 = it->first.second.second.first; << "=" << it->col_nbr << ";" << endl;
int var3 = it->first.second.second.second; mDynamicModelFile << "value[" << k << "] = ";
expr_t d3 = it->second;
int id1 = getDynJacobianCol(var1);
int id2 = getDynJacobianCol(var2);
int id3 = getDynJacobianCol(var3);
// Reference column number for the g3 matrix
int ref_col = id1 * hessianColsNbr + id2 * dynJacobianColsNbr + id3;
sparseHelper(3, mDynamicModelFile, k, 0, oCDynamicModel);
mDynamicModelFile << "=" << eq + 1 << ";" << endl;
sparseHelper(3, mDynamicModelFile, k, 1, oCDynamicModel);
mDynamicModelFile << "=" << ref_col + 1 << ";" << endl;
sparseHelper(3, mDynamicModelFile, k, 2, oCDynamicModel);
mDynamicModelFile << "=";
// oCstaticModel makes reference to the static variables // oCstaticModel makes reference to the static variables
d3->writeOutput(mDynamicModelFile, oCStaticModel, temporary_terms, tef_terms); it->value->writeOutput(mDynamicModelFile, oCStaticModel, temporary_terms, tef_terms);
mDynamicModelFile << ";" << endl; mDynamicModelFile << ";" << endl;
k++;
// Compute the column numbers for the 5 other permutations of (id1,id2,id3) and store them in a set (to avoid duplicates if two indexes are equal)
set<int> cols;
cols.insert(id1 * hessianColsNbr + id3 * dynJacobianColsNbr + id2);
cols.insert(id2 * hessianColsNbr + id1 * dynJacobianColsNbr + id3);
cols.insert(id2 * hessianColsNbr + id3 * dynJacobianColsNbr + id1);
cols.insert(id3 * hessianColsNbr + id1 * dynJacobianColsNbr + id2);
cols.insert(id3 * hessianColsNbr + id2 * dynJacobianColsNbr + id1);
int k2 = 1; // Keeps the offset of the permutation relative to k
for (set<int>::iterator it2 = cols.begin(); it2 != cols.end(); it2++)
if (*it2 != ref_col)
{
sparseHelper(3, mDynamicModelFile, k+k2, 0, oCDynamicModel);
mDynamicModelFile << "=" << eq + 1 << ";" << endl;
sparseHelper(3, mDynamicModelFile, k+k2, 1, oCDynamicModel);
mDynamicModelFile << "=" << *it2 + 1 << ";" << endl;
sparseHelper(3, mDynamicModelFile, k+k2, 2, oCDynamicModel);
mDynamicModelFile << "=";
sparseHelper(3, mDynamicModelFile, k, 2, oCDynamicModel);
mDynamicModelFile << ";" << endl;
k2++;
}
k += k2;
} }
// row_ptr must point to the relative address of the first element of the row
int cumsum = 0;
mDynamicModelFile << "row_ptr = [ 0";
for (vector<int>::iterator it=row_ptr.begin(); it != row_ptr.end(); ++it)
{
cumsum += *it;
mDynamicModelFile << ", " << cumsum;
}
mDynamicModelFile << "];" << endl;
mDynamicModelFile << "}" << endl; mDynamicModelFile << "}" << endl;
writePowerDeriv(mDynamicModelFile, true); writePowerDeriv(mDynamicModelFile, true);
@ -4761,13 +4695,4 @@ DynamicModel::writeThirdDerivativesCC_csr(const string &basename, bool cuda) con
} }
OrderByLinearAddress::OrderByLinearAddress(int size)
{
linear_address.resize(size);
}
bool OrderByLinearAddress::operator()(const int i1, const int i2) const
{
return linear_address[i1] < linear_address[i2];
}

View File

@ -473,14 +473,24 @@ public:
bool isModelLocalVariableUsed() const; bool isModelLocalVariableUsed() const;
}; };
//! Class to re-order derivatives for various sparse storage formats //! Classes to re-order derivatives for various sparse storage formats
class OrderByLinearAddress class derivative
{ {
public: public:
//! vector of linear addresses in derivatives matrices long unsigned int linear_address;
vector<long unsigned int> linear_address; long unsigned int col_nbr;
OrderByLinearAddress(int size); unsigned int row_nbr;
//! Order by linear address in a matrix expr_t value;
bool operator()(const int i1, const int i2) const; derivative(long unsigned int arg1, long unsigned int arg2, int arg3, expr_t arg4):
linear_address(arg1), col_nbr(arg2), row_nbr(arg3), value(arg4) {};
};
class derivative_less_than
{
public:
bool operator()(const derivative & d1, const derivative & d2) const
{
return d1.linear_address < d2.linear_address;
}
}; };
#endif #endif