Building GTSAM 4.0: MATLAB toolbox + TYPEDEF_POINTS_TO_VECTORS?

Issue #357 wontfix
Mike Sheffler created an issue

Hi, I've been using GTSAM 3.2.1 via the MATLAB interface and it has been great. Thank you very much. I'm exploring updating to GTSAM 4.0 and am running into a little trouble.

I am attempting to build GTSAM 4.0 with GTSAM_INSTALL_MATLAB_TOOLBOX. After getting everything configured / generated, etc, I build and get a series of errors similar to

6>gtsam\gtsam/geometry/Point2.h(56): error C2039: 'Vector2' : is not a member of 'Eigen::Matrix<double,2,1,0,2,1>' (gtsam\gtsam\geometry\Cal3DS2_Base.cpp)

Looking through the CMake options, I see GTSAM_TYPEDEF_POINTS_TO_VECTORS with the tooltip Typedef Point2 and Point3 to Eigen::Vector equivalents I reasoned that that could be the issue with my build, so I enabled that option. On configuring again, I get the CMake error:

CMake Error at CMakeLists.txt:96 (message):
  GTSAM_INSTALL_MATLAB_TOOLBOX and GTSAM_TYPEDEF_POINTS_TO_VECTORS are both
  enabled.  For now, the MATLAB toolbox cannot deal with this yet.  Please
  turn one of the two options off.

So, is there a workaround? Am I doing this completely wrong? Is anyone else using the MATLAB toolbox against GTSAM 4.0?

I'm building develop using Visual Studio 2013 on Windows 10 Professional, if that is relevant.

Thanks!

Comments (22)

  1. Frank Dellaert

    GTSAM_TYPEDEF_POINTS_TO_VECTORS needs to be false to build the MATLAB toolbox. Seems maybe there is a build issue in that case. Can you turn off the flag and try to diagnose the exact issue?

  2. Mike Sheffler reporter

    Okay. Just to be clear, the first time I built with GTSAM_INSTALL_MATLAB_TOOLBOX, the option GTSAM_TYPEDEF_POINTS_TO_VECTORS was not enabled, and that's when I saw errors of the variety

    6>gtsam\gtsam/geometry/Point2.h(56): error C2039: 'Vector2' : is not a member of 'Eigen::Matrix<double,2,1,0,2,1>' (gtsam\gtsam\geometry\Cal3DS2_Base.cpp)

    I will try to understand what is going on.

  3. Frank Dellaert

    Line 56 is the 'using Vector2::Vector2;' statement. Vector2 itself is a typedef to 'Eigen::Matrix<double,2,1,0,2,1>'. This compiles fine on Linux I think so maybe it's a Windows compilation issue.

  4. Mike Sheffler reporter

    I'm thinking you're correct. I thought it was going to be something a little more subtle, but, it looks like Visual Studio 2013 is just not 'cut-and-paste'-ing that typedef. Good to know Linux (g++?) isn't have any problem with that line; I'll try a newer version of Visual Studio.

    If you're zealous about resolving issues, this can probably be closed and we can say that Visual Studio 2013 is probably not sufficient for compiling. If you don't mind leaving it open, I can report back with another try with a newer compiler (probably within a week).

  5. Mike Sheffler reporter

    Just to report back: I tried

    • Visual Studio 2015 with included Eigen
    • Visual Studio 2015 with system Eigen (I used 3.3.4)
    • Visual Studio 2017 with included Eigen
    • Visual Studio 2017 with system Eigen (I used 3.3.4)

    I believe I used boost 1.60 for each of them.

    Similar to issue #358, I had compilation errors stemming from Eigen in each of the four cases. I compiled GTSAM 4.0 in Ubuntu 16.04 and had zero errors. If GCC can build it, but Visual Studio barfs, I'm guessing the Visual Studio compiler just isn't up to the task. Unlike issue #358, I only tried to build GTSAM 4.0.

    For my current GTSAM 3.2.1 setup, I compiled GTSAM 3.2.1 using Visual Studio 2013 with GTSAM_INSTALL_MATLAB_TOOLBOX' disabled and downloaded the MATLAB toolbox.

  6. Frank Dellaert

    Awesome experiments. The intent of that statement is that the constructor is available. What happens if you just create the "passthrough" constructors that are called? Just default and (x,y) might be only ones used... Or maybe also copy constructor... You might try just omitting the line before this more elaborate scheme.

  7. Mike Sheffler reporter

    I think what I said was confusing; I am getting build errors stemming from Eigen, but not the exact same ones as issue #358

    In my case (right this second, I have Visual Studio 2015 using system Eigen at my fingertips), I have (this is the first error I see):

    5>\gtsam\3rdparty\eigen\eigen\src/Core/DenseBase.h(424): error C2338: THIS_METHOD_IS_ONLY_FOR_1x1_EXPRESSIONS (compiling source file \gtsam\geometry\Cal3Bundler.cpp)
    5>  \gtsam\3rdparty\eigen\eigen\src/Core/DenseBase.h(423): note: while compiling class template member function 'const double &Eigen::DenseBase<Derived>::value(void) const'
    5>          with
    5>          [
    5>              Derived=gtsam::Vector3
    5>          ] (compiling source file C:\Users\msheffler\Desktop\gtsam\gtsam\geometry\Cal3Bundler.cpp)
    5>  \gtsam\3rdparty\eigen\eigen\src/Core/MatrixBase.h(50): note: see reference to class template instantiation 'Eigen::DenseBase<Derived>' being compiled
    5>          with
    5>          [
    5>              Derived=gtsam::Vector3
    5>          ] (compiling source file C:\Users\msheffler\Desktop\gtsam\gtsam\geometry\Cal3Bundler.cpp)
    5>  \gtsam/base/Vector.h(45): note: see reference to class template instantiation 'Eigen::MatrixBase<gtsam::Vector3>' being compiled (compiling source file gtsam\geometry\Cal3Bundler.cpp)
    

    Chasing THIS_METHOD_IS_ONLY_FOR_1x1_EXPRESSIONS, I see (this is Eigen Core/DenseBase.h) ...

    /** \returns the unique coefficient of a 1x1 expression */
        CoeffReturnType value() const
        {
          EIGEN_STATIC_ASSERT_SIZE_1x1(Derived)
          eigen_assert(this->rows() == 1 && this->cols() == 1);
          return derived().coeff(0,0);
        }
    

    and that static assert seems to be the bomb. If I am reading this correctly (big if), the line

    static const Eigen::MatrixBase<Vector3>::ConstantReturnType Z_3x1 = Vector3::Zero();

    in gtsam\base\Vector.h is being used for the value of Derived in Eigen, and Eigen is saying No, that doesn't work. Your thing is not 1x1. At first blush, I would tend to agree, since Vector3 is Eigen::Vector3d is Eigen::Matrix<double, 3, 1>, but I don't know

    • Why GCC compiles it
    • How '1x1' is defined. EIGEN_STATIC_ASSERT_SIZE_1x1 is a series of ORs:
    #define EIGEN_STATIC_ASSERT_SIZE_1x1(TYPE) \
          EIGEN_STATIC_ASSERT((TYPE::RowsAtCompileTime == 1 || TYPE::RowsAtCompileTime == Dynamic) && \
                              (TYPE::ColsAtCompileTime == 1 || TYPE::ColsAtCompileTime == Dynamic), \
                              THIS_METHOD_IS_ONLY_FOR_1x1_EXPRESSIONS)
    

    and I would have guessed TYPE::RowsAtCompileTime == 1 is being violated, but why don't I see this on GCC?

    Edit: For clarity, before doing this most recent compile, I did not change anything from the current HEAD of develop

    Edit 2: Initially, I wrote TYPE::ColsAtCompileTime == 1 and meant TYPE::RowsAtCompileTime == 1; now changed

  8. Anup

    I get the same error as @mikesheffler when using the eigen that is included in the gtsam repo. If I use an external eigen (3.3.4), I get the errors in #359

  9. Frank Dellaert

    Indeed, Vector3 is 3x1, not 1x1. Can you figure out exactly which code is triggering the compile error? (and confirm, again, this is just a problem on windows??)

  10. Mike Sheffler reporter

    I'm about to step away from my desk until tomorrow so I can't be positive, but I think I saw error C2338: OUT_OF_RANGE_ACCESS, as in issue #359, as well. With respect to the configuration of @anuppari , I'm also using Windows 10, x64, but I am using boost 1.60 (he uses 1.64), he uses the TBB allocator (I use STL), and I do not have TBB or MKL (he has both, I think).

  11. Mike Sheffler reporter

    Frank, I will look. I have to pop out for a few hours, but I will look later tonight or tomorrow.

    Edit Also, yes; I built the clone of develop on Ubuntu 16.04 and did not see any errors. I didn't try to run anything, but, just not seeing build errors was pretty convincing to me. I would check, but someone took that box away to use it for something. I'll be embarrassed if I just didn't notice the errors, but I would expect your CI runner to barf as well if my machine were barfing.

  12. Frank Dellaert

    Indeed, CI would barf :-) I think the solution will involve identifying the offending line and finding a Windows workaround. Not sure though.

  13. Anup

    The value function is never called in any of the erring files, presumably it is put in place by eigen magic during compile time. I don't know enough about eigen to know when it would be called. @mikesheffler what led you to believe that static const Eigen::MatrixBase<Vector3>::ConstantReturnType Z_3x1 = Vector3::Zero(); was the offending line? The typedef above that line typedef Eigen::Vector3d Vector3; would explain the derived type eigen is using.

  14. Mike Sheffler reporter

    @anuppari Honestly, I don't know. typedef is indeed processed by the compiler (and not the preprocessor), but I don't believe it is a statement, so I don't know if that would raise the issue of a static assertion. I don't know if my interpretation is correct, and I definitely don't know what goes on in the twisted mind of the Visual Studio compiler.

    My suspicion is that Visual Studio is getting tripped up with all of the replacements that are happening. I think Vector3::Zero() might be the real boogeyman. It is

    template<typename Derived>
    EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
    DenseBase<Derived>::Zero()
    {
      return Constant(Scalar(0));
    }
    

    I bet (and I have no reason to believe this other than that it fits my narrative) that

    template<typename Derived>
    EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
    DenseBase<Derived>::Constant(const Scalar& value)
    {
      EIGEN_STATIC_ASSERT_FIXED_SIZE(Derived)
      return DenseBase<Derived>::NullaryExpr(RowsAtCompileTime, ColsAtCompileTime, internal::scalar_constant_op<Scalar>(value));
    }
    

    is being interpreted in a funny way; somehow the magic of returning 3 values of 0.0 is not being seen one at a time, (where the static assert value() would pass), but instead as value() somehow being invoked on the triplet (which is more than 1x1).

    I'll be first to admit that that's grasping at straws, but this is deeper in template hell than I normally like to swim. In fact, I tried making the replacement

    //static const Eigen::MatrixBase<Vector2>::ConstantReturnType Z_2x1 = Vector2::Zero();
    //static const Eigen::MatrixBase<Vector3>::ConstantReturnType Z_3x1 = Vector3::Zero();
    static const Eigen::Vector2d Z_2x1 = (Eigen::Vector2d() << 0.0, 0.0).finished();
    static const Eigen::Vector3d Z_3x1 = (Eigen::Vector3d() << 0.0, 0.0, 0.0).finished();
    

    and saw

    6>\gtsam\3rdparty\eigen\eigen\src/Core/DenseBase.h(424): error C2338: THIS_METHOD_IS_ONLY_FOR_1x1_EXPRESSIONS (compiling source file C:\Users\msheffler\Desktop\gtsam\gtsam\geometry\Cal3_S2Stereo.cpp)
    6> \gtsam\3rdparty\eigen\eigen\src/Core/DenseBase.h(423): note: while compiling class template member function 'const double &Eigen::DenseBase<Derived>::value(void) const'
    6>          with
    6>          [
    6>              Derived=Eigen::Matrix<double,2,1,0,2,1>
    6>          ] (compiling source file \gtsam\geometry\Cal3_S2Stereo.cpp)
    6>  \gtsam\3rdparty\eigen\eigen\src/Core/MatrixBase.h(50): note: see reference to class template instantiation 'Eigen::DenseBase<Derived>' being compiled
    6>          with
    6>          [
    6>              Derived=Eigen::Matrix<double,2,1,0,2,1>
    6>          ] (compiling source file \gtsam\geometry\Cal3_S2Stereo.cpp)
    6>  \gtsam\3rdparty\eigen\eigen\src/Core/PlainObjectBase.h(90): note: see reference to class template instantiation 'Eigen::MatrixBase<Derived>' being compiled
    6>          with
    6>          [
    6>              Derived=Eigen::Matrix<double,2,1,0,2,1>
    6>          ] (compiling source file \gtsam\geometry\Cal3_S2Stereo.cpp)
    6>  \gtsam\3rdparty\eigen\eigen\src/Core/Matrix.h(129): note: see reference to class template instantiation 'Eigen::PlainObjectBase<Eigen::Matrix<double,2,1,0,2,1>>' being compiled (compiling source file \gtsam\geometry\Cal3_S2Stereo.cpp)
    6>  \gtsam/base/Vector.h(46): note: see reference to class template instantiation 'Eigen::Matrix<double,2,1,0,2,1>' being compiled (compiling source file \gtsam\geometry\Cal3_S2Stereo.cpp)
    

    which suggests that my hunch is incorrect, since I think Eigen::Matrix<double,2,1,0,2,1> is just the unpacked name for Eigen::Vector2d. So, in short, I don't know what is the problem here.

    I'll try reinstalling VS2017 (I had to uninstall it to get VS2015 working, because of Reasons) and see if I am getting the same error.

    Before I do that, though: Frank, how do you guys target your version of Eigen? If someone subbed in 3.3.4, would you expect that to work? Do you make local changes to the version you distribute or rely on deprecated behavior? I don't actually know anything about Eigen, I'm more curious if investigating 'use system Eigen' is worthwhile as another line of inquiry.

  15. Sebastian Friston

    Just tried this. The 3rd party dependency GKlib requires POSIX support (sys/resource.h), which mingw does not have. Cygwin is another possibility.

  16. Thomas Weichselbaumer

    Hi, is there any solution for this problem now?

    I think VS2017 (maybe other editions too) has a problem with the GTSAM_EXPORT in special cases. If I remove the macro or enable GTSAM_STATIC_LIBRARY (no real option, because I want to build the Matlab Toolbox) the THIS_METHOD_IS_ONLY_FOR_1x1_EXPRESSIONS error goes away.

    Nevertheless I get another one:

    e:\build\gtborg-gtsam-4.0-alpha2\gtsam\base\genericvalue.h(161): error C2280: 'gtsam::GenericValue<ValueType> &gtsam::G
    enericValue<ValueType>::operator =(const gtsam::GenericValue<ValueType> &)': attempting to reference a deleted function
     [E:\Build\gtborg-gtsam-4.0-alpha2\build\gtsam\gtsam.vcxproj]
              with
              [
                  ValueType=gtsam::Point3
              ] (compiling source file E:\Build\gtborg-gtsam-4.0-alpha2\gtsam\slam\dataset.cpp)
      e:\build\gtborg-gtsam-4.0-alpha2\gtsam\base\genericvalue.h(195): note: compiler has generated 'gtsam::GenericValue<Va
      lueType>::operator =' here
              with
              [
                  ValueType=gtsam::Point3
              ] (compiling source file E:\Build\gtborg-gtsam-4.0-alpha2\gtsam\slam\dataset.cpp)
      e:\build\gtborg-gtsam-4.0-alpha2\gtsam\base\genericvalue.h(156): note: while compiling class template member function
       'gtsam::Value &gtsam::GenericValue<ValueType>::operator =(const gtsam::Value &)'
              with
              [
                  ValueType=gtsam::Point3
              ] (compiling source file E:\Build\gtborg-gtsam-4.0-alpha2\gtsam\slam\dataset.cpp)
      e:\build\gtborg-gtsam-4.0-alpha2\gtsam\nonlinear\values-inl.h(68): note: see reference to class template instantiatio
      n 'gtsam::GenericValue<ValueType>' being compiled
              with
              [
                  ValueType=gtsam::Point3
              ] (compiling source file E:\Build\gtborg-gtsam-4.0-alpha2\gtsam\slam\dataset.cpp)
      e:\build\gtborg-gtsam-4.0-alpha2\gtsam\nonlinear\values-inl.h(64): note: while compiling class template member functi
      on 'gtsam::_ValuesConstKeyValuePair<ValueType> gtsam::ValuesCastHelper<const ValueType,gtsam::_ValuesConstKeyValuePai
      r<ValueType>,gtsam::Values::ConstKeyValuePair>::cast(KeyValuePairType)'
              with
              [
                  ValueType=gtsam::Point3,
                  KeyValuePairType=gtsam::Values::ConstKeyValuePair
              ] (compiling source file E:\Build\gtborg-gtsam-4.0-alpha2\gtsam\slam\dataset.cpp)
      e:\build\gtborg-gtsam-4.0-alpha2\gtsam\nonlinear\values-inl.h(144): note: see reference to function template instanti
      ation 'gtsam::_ValuesConstKeyValuePair<ValueType> gtsam::ValuesCastHelper<const ValueType,gtsam::_ValuesConstKeyValue
      Pair<ValueType>,gtsam::Values::ConstKeyValuePair>::cast(KeyValuePairType)' being compiled
              with
              [
                  ValueType=gtsam::Point3,
                  KeyValuePairType=gtsam::Values::ConstKeyValuePair
              ] (compiling source file E:\Build\gtborg-gtsam-4.0-alpha2\gtsam\slam\dataset.cpp)
      e:\build\gtborg-gtsam-4.0-alpha2\gtsam\nonlinear\values-inl.h(150): note: see reference to class template instantiati
      on 'gtsam::ValuesCastHelper<const ValueType,gtsam::_ValuesConstKeyValuePair<ValueType>,gtsam::Values::ConstKeyValuePa
      ir>' being compiled
              with
              [
                  ValueType=gtsam::Point3
              ] (compiling source file E:\Build\gtborg-gtsam-4.0-alpha2\gtsam\slam\dataset.cpp)
      e:\build\gtborg-gtsam-4.0-alpha2\gtsam\nonlinear\values-inl.h(135): note: while compiling class template member funct
      ion 'gtsam::Values::Filtered<gtsam::Point3>::Filtered(const boost::function<bool (const gtsam::Values::ConstKeyValueP
      air &)> &,gtsam::Values &)' (compiling source file E:\Build\gtborg-gtsam-4.0-alpha2\gtsam\slam\dataset.cpp)
      e:\build\gtborg-gtsam-4.0-alpha2\gtsam\nonlinear\values-inl.h(246): note: see reference to function template instanti
      ation 'gtsam::Values::Filtered<gtsam::Point3>::Filtered(const boost::function<bool (const gtsam::Values::ConstKeyValu
      ePair &)> &,gtsam::Values &)' being compiled (compiling source file E:\Build\gtborg-gtsam-4.0-alpha2\gtsam\slam\datas
      et.cpp)
    

    https://stackoverflow.com/questions/33517902/how-to-export-a-class-derived-from-an-explicitly-instantiated-template-in-visual

  17. Frank Dellaert

    Suspected Windows compilation issue: very little I can do, because I don't have a Windows machine. Nor do I have the experience with Windows compilers that I think is needed to resolve this. If any one of you wants to pick this up, please self-assign yourself to this issue. We would love to have some motivated windows contributors, and can also give write access to the repo so you don't have to fork :-) We're trying to actively run down the issue list in preparation for an official GTSAM 4 release. But If we can't find anyone to pick up these issues, I see no choice but to put these "on hold".

  18. Thomas Weichselbaumer

    At the moment i don't have enough time to try to fix the error. Nevertheless I did some additional research. Maybe it can be useful for someone.

    For the attempting to reference a deleted function I found this:

    https://stackoverflow.com/questions/31264984/c-compiler-error-c2280-attempting-to-reference-a-deleted-function-in-visual

    The other error (THIS_METHOD_IS_ONLY_FOR_1x1_EXPRESSIONS) is also described here:

    https://github.com/RainerKuemmerle/g2o/issues/144

    As I had written before, I think GTSAM_EXPORT on class level is not allowed if the class devides from a template class. Maybe it could be fixed by removing the GTSAM_EXPORT from class and add it to all methods where the export is needed.

  19. Mike Sheffler reporter

    I don't think I have the skillz needed to diagnose and remedy the idiosyncrasies of how Visual Studio treats templates. I would absolutely be willing to try out some builds, but, that's about all I can realistically offer. If I had the Intel compiler, I'd give that a whirl, since I'm more concerned about VS as a compiler / linker than I am about the fact that the code is being compiled for Windows. But I don't.

    Now that Google is building Chromium on Windows using Clang, I wonder if Clang support on Windows is good enough for a project like this. If there were a Clang build of GTSAM on Linux, that would at least be easy to test out on Windows, and it would be reasonable to expect that it might work. I'm not sure how involved getting to Clang on Linux would be, though. :/

  20. Frank Dellaert

    Duy and I will try to switch MATLAB to only work with typedef flag. It makes sense in GTSAM 4 to switch to native vector types in the wrappers.

  21. Log in to comment