Skip to content

Commit 2ce06c3

Browse files
author
Benjamin Chrétien
committed
Sparse: re-use sparse structure
This removes some allocations at the cost of lookups in the sparse matrix. Tests on a very large problem hinted at some speedup, but further tests will confirm if this is indeed a good idea.
1 parent cb0aa67 commit 2ce06c3

4 files changed

Lines changed: 39 additions & 20 deletions

File tree

src/tnlp.cc

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -166,10 +166,12 @@ namespace roboptim
166166
else
167167
g = get<shared_ptr<nonLinearFunction_t> > (*it);
168168

169-
function_t::jacobian_t jacobian = g->jacobian (x);
170-
for (int k = 0; k < jacobian.outerSize (); ++k)
169+
constraintJacobians_.push_back (g->jacobian (x));
170+
function_t::jacobian_t& tmp_jac = constraintJacobians_.back ();
171+
tmp_jac.makeCompressed ();
172+
for (int k = 0; k < tmp_jac.outerSize (); ++k)
171173
for (function_t::jacobian_t::InnerIterator
172-
it (jacobian, k); it; ++it)
174+
it (tmp_jac, k); it; ++it)
173175
{
174176
const int row = static_cast<int> (idx + it.row ());
175177
const int col = static_cast<int> (it.col ());
@@ -211,7 +213,6 @@ namespace roboptim
211213
typedef solver_t::problem_t::constraints_t::const_iterator
212214
citer_t;
213215

214-
int idx = 0;
215216
int constraintId = 0;
216217
for (citer_t it = solver_.problem ().constraints ().begin ();
217218
it != solver_.problem ().constraints ().end (); ++it)
@@ -222,26 +223,34 @@ namespace roboptim
222223
else
223224
g = get<shared_ptr<nonLinearFunction_t> > (*it);
224225

225-
// TODO: use middleRows once Eigen is fixed
226-
// TODO: avoid allocation here (may be solved with
227-
// http://eigen.tuxfamily.org/bz/show_bug.cgi?id=910)
228-
copySparseBlock (*jacobian_, g->jacobian (x_), idx, 0);
229-
idx += g->outputSize ();
226+
typename function_t::matrix_t& jac = constraintJacobians_[constraintId];
227+
// Set the Jacobian to 0 while keeping its structure
228+
jac *= 0.;
229+
g->jacobian (jac, x_);
230230

231231
IpoptCheckGradient
232232
(*g, 0, x_,
233233
constraintId++, solver_);
234234
}
235235

236-
// Copy jacobian values from internal sparse matrix.
237-
idx = 0;
238-
for (int k = 0; k < jacobian_->outerSize (); ++k)
239-
for (function_t::jacobian_t::InnerIterator it (*jacobian_, k);
240-
it; ++it)
241-
{
242-
assert (idx < nele_jac);
243-
values[idx++] = it.value ();
244-
}
236+
// Copy jacobian values from internal sparse matrices.
237+
int idx = 0;
238+
for (int k = 0;
239+
k < ((StorageOrder == Eigen::ColMajor)?
240+
solver_.problem ().function ().inputSize ()
241+
: solver_.problem ().function ().outputSize ());
242+
++k)
243+
for (constraintJacobians_t::const_iterator
244+
g = constraintJacobians_.begin ();
245+
g != constraintJacobians_.end (); ++g)
246+
{
247+
for (function_t::jacobian_t::InnerIterator it (*g, k);
248+
it; ++it)
249+
{
250+
assert (idx < nele_jac);
251+
values[idx++] = it.value ();
252+
}
253+
}
245254

246255
return true;
247256
}

src/tnlp.hh

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@
1717

1818
#ifndef ROBOPTIM_CORE_IPOPT_TNLP_HH
1919
# define ROBOPTIM_CORE_IPOPT_TNLP_HH
20+
21+
# include <vector>
22+
2023
# include <boost/mpl/at.hpp>
2124
# include <boost/optional.hpp>
2225

@@ -177,6 +180,12 @@ namespace roboptim
177180

178181
/// \brief Constraints jacobian buffer.
179182
boost::optional<typename function_t::matrix_t> jacobian_;
183+
184+
/// \brief Constraint Jacobian matrices buffer for the sparse case.
185+
/// Since we cannot just rely on Eigen::Ref in the sparse case, temporary
186+
/// Jacobian matrices are used for each constraint.
187+
typedef std::vector<typename function_t::matrix_t> constraintJacobians_t;
188+
constraintJacobians_t constraintJacobians_;
180189
};
181190
} // end of namespace detail.
182191
} // end of namespace roboptim.

src/tnlp.hxx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,8 @@ namespace roboptim
135135
cost_ (),
136136
costGradient_ (),
137137
constraints_ (),
138-
jacobian_ ()
138+
jacobian_ (),
139+
constraintJacobians_ ()
139140
{
140141
BOOST_MPL_ASSERT_RELATION
141142
( (boost::mpl::size<

tests/shared-tests

Submodule shared-tests updated 71 files

0 commit comments

Comments
 (0)