sdsl-lite icon indicating copy to clipboard operation
sdsl-lite copied to clipboard

make wt_int and wm_int thread safe

Open ekg opened this issue 9 years ago • 12 comments

This is accomplished by moving m_path_off and m_path_rank_off to the local context of select (see #263).

Now, grep mutable include/sdsl/*hpp yields only wt_pc.hpp, bp_support_sada, and csa_sada, all of which have shared caches that will not be thread safe without changes to the API.

ekg avatar Aug 31 '15 10:08 ekg

Can one of the admins verify this patch?

tb-robot avatar Aug 31 '15 10:08 tb-robot

I think it might make sense to revert my last push. Trying to understand what I'm seeing here once I try to integrate the changes into another application: https://travis-ci.org/ekg/xg/builds/78046876#L5603-L5645. This wasn't an issue with int_vector<64>.

Here's the text of the error in case it vanishes into travis history:

In file included from sdsl-lite/build/include/sdsl/wavelet_trees.hpp:37:0,
                 from xg.hpp:12,
                 from xg.cpp:1:
sdsl-lite/build/include/sdsl/wt_int.hpp: In instantiation of ‘sdsl::wt_int<t_bitvector, t_rank, t_select, t_select_zero>::size_type sdsl::wt_int<t_bitvector, t_rank, t_select, t_select_zero>::select(sdsl::wt_int<t_bitvector, t_rank, t_select, t_select_zero>::size_type, sdsl::wt_int<t_bitvector, t_rank, t_select, t_select_zero>::value_type) const [with t_bitvector = sdsl::int_vector<1u>; t_rank = sdsl::rank_support_v<1u, 1u>; t_select = sdsl::select_support_mcl<1u, 1u>; t_select_zero = sdsl::select_support_mcl<0u, 1u>; sdsl::wt_int<t_bitvector, t_rank, t_select, t_select_zero>::size_type = long unsigned int; sdsl::wt_int<t_bitvector, t_rank, t_select, t_select_zero>::value_type = long unsigned int]’:
xg.cpp:355:64:   required from here
sdsl-lite/build/include/sdsl/wt_int.hpp:431:60: error: no matching function for call to ‘std::array<long unsigned int, 65ul>::array(unsigned int)’
             std::array<uint64_t, 65> m_path_off(max_level+1);
                                                            ^
sdsl-lite/build/include/sdsl/wt_int.hpp:431:60: note: candidates are:
In file included from /usr/include/c++/4.9/tuple:39:0,
                 from /usr/include/c++/4.9/bits/stl_map.h:63,
                 from /usr/include/c++/4.9/map:61,
                 from xg.hpp:6,
                 from xg.cpp:1:
/usr/include/c++/4.9/array:81:12: note: std::array<long unsigned int, 65ul>::array()
     struct array
            ^
/usr/include/c++/4.9/array:81:12: note:   candidate expects 0 arguments, 1 provided
/usr/include/c++/4.9/array:81:12: note: constexpr std::array<long unsigned int, 65ul>::array(const std::array<long unsigned int, 65ul>&)
/usr/include/c++/4.9/array:81:12: note:   no known conversion for argument 1 from ‘unsigned int’ to ‘const std::array<long unsigned int, 65ul>&’
/usr/include/c++/4.9/array:81:12: note: constexpr std::array<long unsigned int, 65ul>::array(std::array<long unsigned int, 65ul>&&)
/usr/include/c++/4.9/array:81:12: note:   no known conversion for argument 1 from ‘unsigned int’ to ‘std::array<long unsigned int, 65ul>&&’
In file included from sdsl-lite/build/include/sdsl/wavelet_trees.hpp:37:0,
                 from xg.hpp:12,
                 from xg.cpp:1:
sdsl-lite/build/include/sdsl/wt_int.hpp:432:65: error: no matching function for call to ‘std::array<long unsigned int, 65ul>::array(unsigned int)’
             std::array<uint64_t, 65> m_path_rank_off(max_level+1);
                                                                 ^
sdsl-lite/build/include/sdsl/wt_int.hpp:432:65: note: candidates are:
In file included from /usr/include/c++/4.9/tuple:39:0,
                 from /usr/include/c++/4.9/bits/stl_map.h:63,
                 from /usr/include/c++/4.9/map:61,
                 from xg.hpp:6,
                 from xg.cpp:1:
/usr/include/c++/4.9/array:81:12: note: std::array<long unsigned int, 65ul>::array()
     struct array
            ^
/usr/include/c++/4.9/array:81:12: note:   candidate expects 0 arguments, 1 provided
/usr/include/c++/4.9/array:81:12: note: constexpr std::array<long unsigned int, 65ul>::array(const std::array<long unsigned int, 65ul>&)
/usr/include/c++/4.9/array:81:12: note:   no known conversion for argument 1 from ‘unsigned int’ to ‘const std::array<long unsigned int, 65ul>&’
/usr/include/c++/4.9/array:81:12: note: constexpr std::array<long unsigned int, 65ul>::array(std::array<long unsigned int, 65ul>&&)
/usr/include/c++/4.9/array:81:12: note:   no known conversion for argument 1 from ‘unsigned int’ to ‘std::array<long unsigned int, 65ul>&&’

ekg avatar Aug 31 '15 14:08 ekg

why are you passing an argument to the constructor of std::array? The 65 as second template argument is enough I guess ;)

2015-08-31 16:22 GMT+02:00 Erik Garrison [email protected]:

I think it might make sense to revert my last push. Trying to understand what I'm seeing here once I try to integrate the changes into another application: https://travis-ci.org/ekg/xg/builds/78046876#L5603-L5645. This wasn't an issue with int_vector<64>.

Here's the text of the error in case it vanishes into travis history:

In file included from sdsl-lite/build/include/sdsl/wavelet_trees.hpp:37:0, from xg.hpp:12, from xg.cpp:1: sdsl-lite/build/include/sdsl/wt_int.hpp: In instantiation of ‘sdsl::wt_int<t_bitvector, t_rank, t_select, t_select_zero>::size_type sdsl::wt_int<t_bitvector, t_rank, t_select, t_select_zero>::select(sdsl::wt_int<t_bitvector, t_rank, t_select, t_select_zero>::size_type, sdsl::wt_int<t_bitvector, t_rank, t_select, t_select_zero>::value_type) const [with t_bitvector = sdsl::int_vector<1u>; t_rank = sdsl::rank_support_v<1u, 1u>; t_select = sdsl::select_support_mcl<1u, 1u>; t_select_zero = sdsl::select_support_mcl<0u, 1u>; sdsl::wt_int<t_bitvector, t_rank, t_select, t_select_zero>::size_type = long unsigned int; sdsl::wt_int<t_bitvector, t_rank, t_select, t_select_zero>::value_type = long unsigned int]’: xg.cpp:355:64: required from here sdsl-lite/build/include/sdsl/wt_int.hpp:431:60: error: no matching function for call to ‘std::array<long unsigned int, 65ul>::array(unsigned int)’ std::array<uint64_t, 65> m_path_off(max_level+1); ^ sdsl-lite/build/include/sdsl/wt_int.hpp:431:60: note: candidates are: In file included from /usr/include/c++/4.9/tuple:39:0, from /usr/include/c++/4.9/bits/stl_map.h:63, from /usr/include/c++/4.9/map:61, from xg.hpp:6, from xg.cpp:1: /usr/include/c++/4.9/array:81:12: note: std::array<long unsigned int, 65ul>::array() struct array ^ /usr/include/c++/4.9/array:81:12: note: candidate expects 0 arguments, 1 provided /usr/include/c++/4.9/array:81:12: note: constexpr std::array<long unsigned int, 65ul>::array(const std::array<long unsigned int, 65ul>&) /usr/include/c++/4.9/array:81:12: note: no known conversion for argument 1 from ‘unsigned int’ to ‘const std::array<long unsigned int, 65ul>&’ /usr/include/c++/4.9/array:81:12: note: constexpr std::array<long unsigned int, 65ul>::array(std::array<long unsigned int, 65ul>&&) /usr/include/c++/4.9/array:81:12: note: no known conversion for argument 1 from ‘unsigned int’ to ‘std::array<long unsigned int, 65ul>&&’ In file included from sdsl-lite/build/include/sdsl/wavelet_trees.hpp:37:0, from xg.hpp:12, from xg.cpp:1: sdsl-lite/build/include/sdsl/wt_int.hpp:432:65: error: no matching function for call to ‘std::array<long unsigned int, 65ul>::array(unsigned int)’ std::array<uint64_t, 65> m_path_rank_off(max_level+1); ^ sdsl-lite/build/include/sdsl/wt_int.hpp:432:65: note: candidates are: In file included from /usr/include/c++/4.9/tuple:39:0, from /usr/include/c++/4.9/bits/stl_map.h:63, from /usr/include/c++/4.9/map:61, from xg.hpp:6, from xg.cpp:1: /usr/include/c++/4.9/array:81:12: note: std::array<long unsigned int, 65ul>::array() struct array ^ /usr/include/c++/4.9/array:81:12: note: candidate expects 0 arguments, 1 provided /usr/include/c++/4.9/array:81:12: note: constexpr std::array<long unsigned int, 65ul>::array(const std::array<long unsigned int, 65ul>&) /usr/include/c++/4.9/array:81:12: note: no known conversion for argument 1 from ‘unsigned int’ to ‘const std::array<long unsigned int, 65ul>&’ /usr/include/c++/4.9/array:81:12: note: constexpr std::array<long unsigned int, 65ul>::array(std::array<long unsigned int, 65ul>&&) /usr/include/c++/4.9/array:81:12: note: no known conversion for argument 1 from ‘unsigned int’ to ‘std::array<long unsigned int, 65ul>&&’

— Reply to this email directly or view it on GitHub https://github.com/simongog/sdsl-lite/pull/264#issuecomment-136385034.

simongog avatar Aug 31 '15 14:08 simongog

I'd like to pick this back up as it's continuing to cause issues for me.

Relative to the patch that I proposed, what changes would you require to make this acceptable?

I'm also interested in doing something similar for csa_sada.

ekg avatar Oct 06 '15 12:10 ekg

just making the buffer in csa_sada local would probably cause lots of allocations which will degrade performance? Have not benchmarked this though.

mpetri avatar Oct 06 '15 12:10 mpetri

It seems it might hurt performance. That said, mutex locking isn't a great solution.

What might be sensible is to pass a thread-local buffer into the select.

ekg avatar Oct 06 '15 12:10 ekg

Yes, a third argument which is a pointer to a thread-local buffer seems to be the good solution, since it is backward-compatible. If a nullptr is passed we could then just use the old mutable array to still get the same performance for single-threaded program ;)

simongog avatar Oct 06 '15 13:10 simongog

the buffer is also used in rank_bwt which is called from the suffix_array_helper classes which are called from count() and extract() etc. so it will be quite difficult to adjust all of these and remain backward-compatible.

mpetri avatar Oct 06 '15 23:10 mpetri

Yes, it is used in those places, but since it is only called with the two arguments it will still work as expected in the single-threaded case. You are certainly right that more adjustments have to be made to make some methods of the CSA (like rank_bwt,count, and extract) work in a multithreaded environment, but I think this is not the point of Erik's request.

simongog avatar Oct 07 '15 00:10 simongog

well csa_sada::select_bwt() doesn't use the buffer at all so not sure what the problem is here?

mpetri avatar Oct 07 '15 00:10 mpetri

also, there is a assert(cc != 255); in there which probably has to removed as we now deal with integer alphabets.

mpetri avatar Oct 07 '15 00:10 mpetri

How much does the caching help? Could I simply add an option to turn it off to all of the classes that use this kind of non-threadsafe feature?

ekg avatar Mar 14 '16 14:03 ekg