-
Notifications
You must be signed in to change notification settings - Fork 498
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
Several fixes for IndexType which are not of integral types #154
Conversation
…es that are stored in KDTreeBaseClass::vind with the type of the indices with which the values therein are accessed. In many places this worked fine, as the values stored in vind are of integral types well, since they are used to quantified indices in an array or a similar data structure. However, With these fixes nanoflann can be used with data structures that provide access to its elements using other types of accessors (such as pointers for example). - Metrics adaptors (L1_Adaptor, L2_Adaptor, ...) did not have a template parameter for IndexType. They expected b_idx to be of size_t, and by doing so always casted implicitly to size_t, if possible. - In several places, IndexType was used to store the location in vind in which the IndexType is stored, whereas the type for the argument of std::vector<IndexType>::operator[] has nothing to do with IndexType itself. E.g. KDTreeBaseClass::Node::node_type, KDTreeBaseClass::divideTree. - Since the argument of std::vector<IndexType>::operator[] is not a template parameter, uint64_t was used
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool! Apart of my comments, please, add the changes to the Changelog file (even with a link to this PR URL?)
@@ -486,17 +492,18 @@ struct SO2_Adaptor { | |||
* \tparam _DistanceType Type of distance variables (must be signed) (e.g. | |||
* float, double) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please, add doxygen docs for the new AccessorType here too?
include/nanoflann.hpp
Outdated
} | ||
|
||
void computeMinMax(const Derived &obj, IndexType *ind, IndexType count, | ||
void computeMinMax(const Derived &obj, uint64_t ind, uint64_t count, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this uint64_t be AccessorType too? Or if it's not, another new symbolic name?
(I'm doing a quick review, sorry if the answer is obvious)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To my understanding, what was done here is that a pointer to IndexType
was used in order to be able to use the element to which ind
points to, which is located in vInd
(or now vAcc
) as the element 0 of an array. However as pointer arithmetic is quite unsafe, I thought it would be somewhat safer and more understandable to explicitly access vAcc
with ind
as an offset, as we do have access to the array here. By using the std::vector::operator[]
explicitly, range checks are at least performed in debug mode.
include/nanoflann.hpp
Outdated
} | ||
} | ||
} else { | ||
IndexType idx; | ||
uint64_t idx; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same comment here, and basically, everywhere where uint64_t shows up... it lights a red light for me seen a hard-wired type instead of a typename parameter, a "using A=B;", etc. ;-)
return m_data_matrix.get().rows(); | ||
else | ||
return m_data_matrix.get().cols(); | ||
} | ||
|
||
// Returns the dim'th component of the idx'th point in the class: | ||
inline num_t kdtree_get_pt(const IndexType idx, size_t dim) const { | ||
if(row_major) | ||
if (row_major) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should add a .clangformat
at some point... but that's for another PR!
- Created type alias for Dimension, Size, Offset - Use 32bit types for these aliases, as well as default template arguments for AccessorType - Added doxygen comments for template arguments for metrics adaptors
@jlblancoc Thank you for reviewing my changes! I have addressed your comments, I hope this is roughly what you had in mind. Once these changes are accepted I am more than happy to create a PR with a |
Also, I am not sure if this is of interest to you as it is a modification of the API, but for our code I prefer to have a unified signature for both, |
Hi @jlblancoc , did you have a chance to look at my changes with respect to your review comments? |
Awesome, great contribution, thanks @dav1d-wright ! I'm just curious: in what context would you find useful using e.g. |
Thank you very much for merging my pull request @jlblancoc! Very glad you like my proposed changes. Actually the main motivation for providing |
std::vector<size_t> ret_index(num_results); | ||
std::vector<uint32_t> ret_index(num_results); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm puzzled by this change (or rather the change that makes this change necessary). For us it breaks backwards compatibility libMesh/libmesh#3122
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Aditionally to that, for msvc there are warnings due to conversion loss with size_t when using the default AccessorType = uint32_t value.
1>C:\dev\GSI\Vstars\packages\nanoflann.1.4.2.14\lib\native\include\nanoflann.hpp(1497,1): warning C4267: '=': conversion from 'size_t' to '_Ty', possible loss of data 1> with 1> [ 1> _Ty=std::_Vbase 1> ]
For KDTreeSingleIndexAdaptor settings the typename AccessorType = uint32_t to size_t leads to some different conversion errors which seem to imply that internally a uint32_t is being used somewhere.
1>C:\dev\GSI\Vstars\packages\nanoflann.1.4.2.14\lib\native\include\nanoflann.hpp(1561,1): warning C4267: 'argument': conversion from 'size_t' to 'const AccessorType', possible loss of data 1> with 1> [ 1> AccessorType=uint32_t 1> ]
Hi,
I have attempted to use
nanoflann
for data structures where the access to the elements is not provided using indexes of integral types, or more efficiently provided by other accessors. While doing so I have found certain issues, most of which arose due to mixing up the type of the values stored inKDTreeBaseClass::vind
and the type with whichvind
is accessed.In many places this worked fine, as the values stored in
vind
were typically of integral types well, since they are used to quantify indices in an array or a similar data structure. However, with these fixesnanoflann
can be used with data structures that provide access to its elements using other types of accessors (such as pointers for example).Here is a quick summary of the changes:
L1_Adaptor
,L2_Adaptor
, ...) did not have a template parameter forIndexType
. They expectedb_idx
to be ofsize_t
, and by doing so casted implicitly tosize_t
, if possible.IndexType
was used to store the location invind
in which theIndexType
is stored, whereas the type for the argument ofstd::vector<IndexType>::operator[]
has nothing to do withIndexType
itself. E.g.KDTreeBaseClass::Node::node_type
,KDTreeBaseClass::divideTree
.std::vector<IndexType>::operator[]
is not a template parameter,uint64_t
was usedIndexType
is not necessarily an index, I renamed it toAccessorType
.I built and ran all tests as well as the examples (all build targets), each of which passed.
I hope you find these changes useful and will merge them into your repository. If there is anything that I should change, don't hesitate to let me know.