symforce-org / symforce

Fast symbolic computation, code generation, and nonlinear optimization for robotics

Home Page:https://symforce.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Upgrade instruction for 0.8 to 0.9? I get many new errors related to types and templating

arbor-arthur opened this issue · comments

I have some cpp code that built correctly against an install with 0.8 that no longer builds. I get the following errors:

/usr/include/symforce/opt/linearization.h: In instantiation of 'struct sym::Linearization<double>':
/usr/include/c++/9/type_traits:1228:12:   required from 'struct std::is_trivially_destructible<sym::Linearization<double> >'
/usr/include/tl/optional.hpp:531:24:   required from 'class tl::optional<sym::Linearization<double> >'
/usr/include/symforce/opt/optimization_stats.h:37:39:   required from 'struct sym::OptimizationStats<double>'
/usr/include/c++/9/type_traits:1150:12:   required from 'struct std::__is_trivially_copy_constructible_impl<sym::OptimizationStats<double>, true>'
/usr/include/c++/9/type_traits:1157:12:   required from 'struct std::is_trivially_copy_constructible<sym::OptimizationStats<double> >'
/usr/include/c++/9/type_traits:2938:25:   required from 'constexpr const bool std::is_trivially_copy_constructible_v<sym::OptimizationStats<double> >'
/usr/include/c++/9/optional:656:11:   required from 'class std::optional<sym::OptimizationStats<double> >'
rust_symforce.cc:148:50:   required from here
/usr/include/symforce/opt/linearization.h:27:9: error: 'double' is not a class, struct, or union type
   27 |   using Scalar = typename MatrixType::Scalar;
      |         ^~~~~~
/usr/include/symforce/opt/linearization.h:28:9: error: 'double' is not a class, struct, or union type
   28 |   using Vector = VectorX<Scalar>;
      |         ^~~~~~
/usr/include/symforce/opt/optimizer.tcc:80:1: note: declared here
   80 | Optimizer<ScalarType, NonlinearSolverType>::Optimize(Values<Scalar>* values, int num_iterations,
      | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
rust_symforce.cc:364:63: error: no match for 'operator=' (operand types are 'std::optional<sym::OptimizationStats<double> >' and 'sym::Optimizer<double>::Stats' {aka 'sym::OptimizationStats<Eigen::SparseMatrix<double> >'})
  364 |         g->stats = g->optimizer->Optimize(&g->values, -1, true);
      |                                                               ^
In file included from rust_symforce.cc:1:
/usr/include/c++/9/optional:773:7: note: candidate: 'std::optional<_Tp>& std::optional<_Tp>::operator=(std::nullopt_t) [with _Tp = sym::OptimizationStats<double>]'
  773 |       operator=(nullopt_t) noexcept
      |       ^~~~~~~~
/usr/include/c++/9/optional:773:17: note:   no known conversion for argument 1 from 'sym::Optimizer<double>::Stats' {aka 'sym::OptimizationStats<Eigen::SparseMatrix<double> >'} to 'std::nullopt_t'
  773 |       operator=(nullopt_t) noexcept
      |                 ^~~~~~~~~
/usr/include/c++/9/optional:786:2: note: candidate: 'template<class _Up> std::enable_if_t<__and_v<std::__not_<std::is_same<std::optional<_Tp>, typename std::remove_cv<typename std::remove_reference<_Up>::type>::type> >, std::__not_<std::__and_<std::is_scalar<_Tp>, std::is_same<_Tp, typename std::decay<_Up>::type> > >, std::is_constructible<_Tp, _Up>, std::is_assignable<_Tp&, _Up> >, std::optional<_Tp>&> std::optional<_Tp>::operator=(_Up&&) [with _Up = _Up; _Tp = sym::OptimizationStats<double>]'
  786 |  operator=(_Up&& __u)
      |  ^~~~~~~~
/usr/include/c++/9/optional:786:2: note:   template argument deduction/substitution failed:
/usr/include/c++/9/type_traits: In substitution of 'template<bool _Cond, class _Tp> using enable_if_t = typename std::enable_if::type [with bool _Cond = std::__and_v<std::__not_<std::is_same<std::optional<sym::OptimizationStats<double> >, sym::OptimizationStats<Eigen::SparseMatrix<double, 0, int> > > >, std::__not_<std::__and_<std::is_scalar<sym::OptimizationStats<double> >, std::is_same<sym::OptimizationStats<double>, sym::OptimizationStats<Eigen::SparseMatrix<double, 0, int> > > > >, std::is_constructible<sym::OptimizationStats<double>, sym::OptimizationStats<Eigen::SparseMatrix<double, 0, int> > >, std::is_assignable<sym::OptimizationStats<double>&, sym::OptimizationStats<Eigen::SparseMatrix<double, 0, int> > > >; _Tp = std::optional<sym::OptimizationStats<double> >&]':
/usr/include/c++/9/optional:786:2:   required by substitution of 'template<class _Up> std::enable_if_t<__and_v<std::__not_<std::is_same<std::optional<sym::OptimizationStats<double> >, typename std::remove_cv<typename std::remove_reference<_Tp>::type>::type> >, std::__not_<std::__and_<std::is_scalar<sym::OptimizationStats<double> >, std::is_same<sym::OptimizationStats<double>, typename std::decay<_Tp>::type> > >, std::is_constructible<sym::OptimizationStats<double>, _Up>, std::is_assignable<sym::OptimizationStats<double>&, _Up> >, std::optional<sym::OptimizationStats<double> >&> std::optional<sym::OptimizationStats<double> >::operator=<_Up>(_Up&&) [with _Up = sym::OptimizationStats<Eigen::SparseMatrix<double> >]'
rust_symforce.cc:364:63:   required from here
/usr/include/c++/9/type_traits:2378:11: error: no type named 'type' in 'struct std::enable_if<false, std::optional<sym::OptimizationStats<double> >&>'
 2378 |     using enable_if_t = typename enable_if<_Cond, _Tp>::type;
      |           ^~~~~~~~~~~

To Reproduce
Many of these errors stem from the following code:

#define Float double

struct FactorGraph_t {
    sym::Values<Float> values;

    std::optional<sym::Optimizer<Float>> optimizer;
    std::optional<sym::OptimizationStats<Float>> stats;

   ...
};

g->stats = g->optimizer->Optimize(&g->values, -1, true);

Expected behavior
My 0.8 code should build or at least be obvious how to fix.

Environment (please complete the following information):

  • OS and version: Ubuntu Linux 20.04
  • Python version: 3.8.10
  • SymForce Version 0.9.0

Hey Arthur. Sorry about the inconvenience. To get your code working with SymForce 0.9 you can either change

std::optional<sym::OptimizationStats<Float>> stats;

to

std::optional<sym::SparseOptimizationStats<Float>> stats;

or

std::optional<sym::Optimizer<Float>::Stats> stats;

The problem was that the OptimizationStats template was changed to expect a matrix type instead of a float or double. The SparseOptimizationStats<Scalar> is an alias for an OptimizationStats<Eigen::SparseMatrix<Scalar>> (and is exactly the same as what OptimizationStats<Scalar> used to be).

If you have a sym::Optimizer<...> type, then the type of OptimizationStats that can be used with it will always be sym::Optimizer<...>::Stats.