Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Eigen <-> StridedArrayView integration #74

Closed
wants to merge 6 commits into from
Closed

Conversation

Janos95
Copy link
Contributor

@Janos95 Janos95 commented Jul 28, 2020

This patch provides an arrayCast method converting between Eigen expressions and Corrade's StridedArrayView class. Not the most beautiful code in the world but should mostly work ;).

@codecov-commenter
Copy link

codecov-commenter commented Jul 28, 2020

Codecov Report

Merging #74 into master will increase coverage by 14.33%.
The diff coverage is 100.00%.

Impacted file tree graph

@@             Coverage Diff             @@
##           master      #74       +/-   ##
===========================================
+ Coverage   75.13%   89.47%   +14.33%     
===========================================
  Files          21       16        -5     
  Lines         905      570      -335     
===========================================
- Hits          680      510      -170     
+ Misses        225       60      -165     
Impacted Files Coverage Δ
src/Magnum/EigenIntegration/Integration.h 100.00% <100.00%> (ø)
src/Magnum/GlmIntegration/Integration.cpp 92.85% <0.00%> (-3.58%) ⬇️
src/Magnum/BulletIntegration/DebugDraw.cpp 13.88% <0.00%> (-2.78%) ⬇️
src/Magnum/BulletIntegration/MotionState.cpp 84.21% <0.00%> (-1.51%) ⬇️
src/Magnum/DartIntegration/Object.cpp
src/Magnum/DartIntegration/ConvertShapeNode.cpp
src/Magnum/DartIntegration/Object.h
src/Magnum/DartIntegration/World.cpp
src/Magnum/DartIntegration/ConvertShapeNode.h
src/Magnum/ImGuiIntegration/Context.cpp 90.90% <0.00%> (+3.40%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update e5562e1...f686010. Read the comment docs.

Copy link
Owner

@mosra mosra left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you! This is much appreciated.

src/Magnum/EigenIntegration/Integration.h Outdated Show resolved Hide resolved
src/Magnum/EigenIntegration/Integration.h Outdated Show resolved Hide resolved
src/Magnum/EigenIntegration/Integration.h Outdated Show resolved Hide resolved
src/Magnum/EigenIntegration/Integration.h Outdated Show resolved Hide resolved
CORRADE_COMPARE(view1[i][j], view2[i][j]);
}
}
}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could use an additional test case that

  1. uses a flipped(), broadcasted() and transposed() array on input to test all cases of a positive, zero and negative stride
  2. converts to Eigen, verifies a few random picks (a[2][3] == b[2][3])
  3. converts back

and then verifies that data(), size() and stride() are the same as on input. In particular I'm not sure if Eigen even supports zero strides (I hope it supports negative strides at least).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So I researched this a bit, and it is possible to incorporate negative strides by mapping those to Eigen::Reverse expressions I think.
Unfortunately I dont think it is possible to cast broadcasted ArrayViews, since Eigen handels braodcasting differently. E.g. to add a vector to a matrix one turns the matrix into a special kind of broadcast expression but the vector is not changed in any way

Eigen::MatrixXf m; 
Eigen::VectorXf v;
m.rowwise() += v;

So if you agree I would just assert on zero strides.

Copy link
Contributor Author

@Janos95 Janos95 Jul 29, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok actually the Reverse expression are not well suited since everything needs to be known at compile time. I found that negative strides are actually supported out of the box since relatively recently : https://eigen.tuxfamily.org/bz/show_bug.cgi?id=747 so that should still work and maybe zero strides will also just work, I will look into that.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at the commit log, this seems to be done and fully supported, right? :)

src/Magnum/EigenIntegration/Test/IntegrationTest.cpp Outdated Show resolved Hide resolved
src/Magnum/EigenIntegration/Test/IntegrationTest.cpp Outdated Show resolved Hide resolved
@brief Convert Corrades StridedArrayView2D to Eigens Dynamic Matrix Type.
*/
template<class T> inline Eigen::Map<Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>, Eigen::Unaligned, Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic>> arrayCast(const Containers::StridedArrayView2D<T>& from) {
using MatrixT = Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could be the RowMajor / ColMajor configurable via an optional second template parameter, maybe? Not sure what should be the default tho.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think having it RowMajor is consistent with how it is used in Magnum (i.e.. view2D[0] is usually used as a row, on the other hand the default in Eigen is ColumnMajor) and one can always transpose the resulting Eigen expression to get a ColumnMajor view on the data if I am not mistaken?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I investigated and tried to support both RowMajor / ColMajor via a template parameter only to realize it doesn't really have any effect on a Map if you explicitly specify Stride as well: https://eigen.tuxfamily.org/dox/group__TutorialMapClass.html#TutorialMapTypes A Map can be then copied to both row- and col-major Matrix so unless I'm missing something it doesn't matter at all what Matrix type is used inside the Map.

So I removed the RowMajor, flipped order of Stride arguments and it resulted in various types being significantly shorter: 9379c64

doc/snippets/EigenIntegration.cpp Show resolved Hide resolved
doc/snippets/EigenIntegration.cpp Outdated Show resolved Hide resolved
@mosra mosra added this to the 2020.0b milestone Jul 28, 2020
@mosra mosra added this to TODO in Math via automation Jul 28, 2020
Janos95 and others added 4 commits July 29, 2020 12:00
Co-authored-by: Vladimír Vondruš <mosra@centrum.cz>
avoid auto and add const

Co-authored-by: Vladimír Vondruš <mosra@centrum.cz>
use CORRADE_COMPARE_AS for StridedArrayView1D

Co-authored-by: Vladimír Vondruš <mosra@centrum.cz>
@Janos95 Janos95 changed the title Eigen <-> StrideArrayView integration Eigen <-> StridedArrayView integration Jul 31, 2020
@mosra
Copy link
Owner

mosra commented Oct 6, 2020

Finally merged as e8eceb3, thank you! 🙏 (and sorry for the several month delay)

As I mentioned in the comment above, 9379c64 removes the RowMajor from the Map typedef -- can you quickly verify it makes sense? I'm not "Eigen native" so I'm not 100% sure this doesn't break anything. Thanks again!

@mosra mosra closed this Oct 6, 2020
Math automation moved this from TODO to Done Oct 6, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Math
  
Done
Development

Successfully merging this pull request may close these issues.

None yet

3 participants