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

[ENH] Augment coiteration algorithm to handle hashed level during conjunctive merge #19

Closed
wants to merge 32 commits into from
Closed
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
8714270
WIP example of compareVector
adam2392 Mar 23, 2023
652d8b0
Adding the unit test for coiteration that should work
adam2392 Apr 3, 2023
bcbcbe2
Clean diff
adam2392 Apr 3, 2023
462dbb0
Update test/source/coiteration_test.cpp
adam2392 Apr 8, 2023
7cc42f7
Update test/source/coiteration_test.cpp
adam2392 Apr 8, 2023
1969843
Fix unit test based on comments
adam2392 May 25, 2023
a9dc754
Merge branch 'comparevec' of github.com:adam2392/xsparse into comparevec
adam2392 May 25, 2023
0c91a0d
Fix unit test based on comments
adam2392 May 25, 2023
0a35239
Attempt at the right answer
adam2392 May 25, 2023
8d97006
Clean
adam2392 May 25, 2023
c0bc015
I think this enables us to store the ordered indices, but does not ye…
adam2392 May 26, 2023
fc08789
Fix docstring and clean up unit-test
adam2392 May 30, 2023
eb63b3c
Fix ci and doctest errors
adam2392 May 30, 2023
0420df3
Merge branch 'main' into comparevec
adam2392 May 30, 2023
828092a
Add levelproperty to all the levels
adam2392 May 31, 2023
b5ec7ef
Merge branch 'main' into levelprops
adam2392 May 31, 2023
aa56276
Try again
adam2392 May 31, 2023
29f4f7f
Adding unit tests for level property
adam2392 May 31, 2023
3e0afc4
Clean diff
adam2392 May 31, 2023
b63b67c
Only check strict property requirements
adam2392 May 31, 2023
2ac6d71
Fixed unit-tests for dense ordered
adam2392 May 31, 2023
5e72277
Level to lower-case
adam2392 Jun 1, 2023
25c5c2e
Merging level props
adam2392 Jun 1, 2023
ddaf8d2
Merge branch 'levelprops' into comparevec
adam2392 Jun 1, 2023
f77dd0d
Trying again
adam2392 Jun 1, 2023
6a73b73
Fix new design
adam2392 Jun 5, 2023
1a6d711
Merge branch 'levelprops' into comparevec
adam2392 Jun 5, 2023
8690b48
Fix co-iteration and just get initial design template for getting tup…
adam2392 Jun 5, 2023
a379e0b
Trying
adam2392 Jun 5, 2023
89ee47d
Merge branch 'main' into comparevec
adam2392 Jun 6, 2023
f7d0ed1
Merge main
adam2392 Jun 6, 2023
7730adb
Kind of wip
adam2392 Jun 7, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 21 additions & 1 deletion include/xsparse/level_capabilities/co_iteration.hpp
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This file contains my initial attempt at: adding a constexpr check at compile time to determine if the coiteration is valid (this assumes that the user converts non-ordered, non-locatable formats to a correct format).

What I'm not sure on now is how to best implement the locate logic. That is, we want to somehow given a tuple of levels, determine which of these have locate and instead of advancing the iterator on those levels, we locate into them given a index and pointer.

Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,27 @@
#include <stdexcept>

namespace xsparse::level_capabilities
{
{
/*
The class template for Coiteration of level formats.

Uses a generic function object F to compare elements
from different sequences at the same position and returns a tuple of the
minimum index and the corresponding elements from each sequence.

Parameters
----------
F : class
A function object that is used to compare two elements from different ranges.
IK : class
The type of the first element of each range.
PK : class
The type of the second element of each range.
Levels : Tuple of class
A tuple of level formats, where each level is itself a tuple of elements to be iterated.
Is : Tuple of class
A tuple of indices that is used to keep track of the current position in each level.
*/
template <class F, class IK, class PK, class Levels, class Is>
class Coiterate;

Expand Down
74 changes: 74 additions & 0 deletions test/source/coiteration_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,13 @@
#include <tuple>
#include <vector>
#include <functional>
#include <set>
adam2392 marked this conversation as resolved.
Show resolved Hide resolved
#include <unordered_map>

#include <xsparse/levels/compressed.hpp>
#include <xsparse/levels/dense.hpp>
#include <xsparse/levels/singleton.hpp>
#include <xsparse/levels/hashed.hpp>
#include <xsparse/version.h>

#include <xsparse/util/container_traits.hpp>
Expand Down Expand Up @@ -193,3 +196,74 @@ TEST_CASE("Coiteration-Singleton-Singleton-Dense-Dense")
}
CHECK(fn(std::tuple(it1 == end1, it2 == end2, it3 == end3, it4 == end4)) == true);
}

TEST_CASE("Coiteration-Dense-Hashed-ConjunctiveMerge")
{
constexpr uint8_t ZERO = 0;

std::unordered_map<uintptr_t, uintptr_t> const umap1{ { 0, 1 }, { 2, 0 }, { 1, 2 } };
std::vector<std::unordered_map<uintptr_t, uintptr_t>> const crd0{ umap1 };

// initialize the two levels to be coiterated
xsparse::levels::dense<std::tuple<>, uintptr_t, uintptr_t> s1{ 5 };
xsparse::levels::hashed<
std::tuple<>,
uintptr_t,
uintptr_t,
xsparse::util::container_traits<std::vector, std::set, std::unordered_map>,
adam2392 marked this conversation as resolved.
Show resolved Hide resolved
xsparse::level_properties<false, false, false, false, false>>
h { 5, crd0 };

// define a conjunctive function
auto fn = [](std::tuple<bool, bool> t) constexpr
{
return (std::get<0>(t) && std::get<1>(t));
};

xsparse::level_capabilities::Coiterate<std::function<bool(std::tuple<bool, bool>)>,
uintptr_t,
uintptr_t,
std::tuple<decltype(s1), decltype(h)>,
std::tuple<>>
coiter(fn, s1, h);

auto it_helper1 = s1.iter_helper(std::make_tuple(), ZERO);
auto it1 = it_helper1.begin();
auto it_helper2 = h.iter_helper(ZERO);
auto it2 = it_helper2.begin();

auto end1 = it_helper1.end();
auto end2 = it_helper2.end();

// when co-iterating over levels that are unordered (i.e. hashed), then we use locate to check
// if the index exists in the hashed level. If not, then we skip it.
for (auto const [ik, pk_tuple] : coiter.coiter_helper(std::make_tuple(), ZERO))
{
// get the index and pointer from the levels involved in co-iteration
auto [i1, p1] = *it1;
auto [i2, p2] = *it2;
adam2392 marked this conversation as resolved.
Show resolved Hide resolved

// should only iterate over the ordered level
uintptr_t l = i1;
CHECK(ik == l);

// check that neither level has reached the end
if (it1 != end1)
{
CHECK(ik == l);

if (i1 == l && h.locate(p1, i1) != std::nullopt)
{
CHECK(p1 == std::get<0>(pk_tuple).value());
CHECK(p2 == std::get<1>(pk_tuple).value());
}

// increment through the dense level always
++it1;
}
}

// check that the constexpr function representing the coiteration is conjunctive
CHECK(fn(std::tuple(it1 == end1, it2 == end2)) == true);
adam2392 marked this conversation as resolved.
Show resolved Hide resolved
CHECK(fn(std::tuple(it1 == end1, it2 != end2)) == false);
}