Lattice Land Core Library
Loading...
Searching...
No Matches
abstract_deps.hpp
Go to the documentation of this file.
1// Copyright 2021 Pierre Talbot
2
3#ifndef LALA_CORE_ABSTRACT_DEPS_HPP
4#define LALA_CORE_ABSTRACT_DEPS_HPP
5
6#include "battery/utility.hpp"
7#include "battery/vector.hpp"
8#include "battery/string.hpp"
9#include "battery/string.hpp"
10#include "battery/tuple.hpp"
11#include "battery/variant.hpp"
12#include "logic/ast.hpp"
13
14namespace lala {
15
16template <class A>
17using abstract_ptr = battery::shared_ptr<A, typename A::allocator_type>;
18
19/** Abstract domains are organized in a directed-acyclic graph (DAG).
20 * Therefore, it is not straighforward to copy the whole hierarchy, because the child of a node may be shared by another node, and might have already been copied.
21 * This class is useful to copy hierarchy of abstract domains.
22 * Moreover, the allocators between the original and the copied hierarchy can be different.
23 *
24 * The first allocator of the list is used for the internal allocations of this class.
25 */
26template<class... Allocators>
28{
29public:
30 constexpr static size_t n = battery::tuple_size<battery::tuple<Allocators...>>{};
31 static_assert(n > 0, "AbstractDeps must have a non-empty list of allocators.");
32
33 using allocators_type = battery::tuple<Allocators...>;
34 using allocator_type = typename battery::tuple_element<0, battery::tuple<Allocators...>>::type;
35
36private:
37 struct dep_erasure {
38 CUDA virtual ~dep_erasure() {}
39 };
40
41 template <class A>
42 struct dep_holder : dep_erasure {
44 CUDA dep_holder(A* ptr): a(ptr, ptr->get_allocator()) {}
45 CUDA virtual ~dep_holder() {}
46 };
47
48 allocators_type allocators;
49 battery::vector<battery::unique_ptr<dep_erasure, allocator_type>, allocator_type> deps;
50
51 /** If the hierarchy to be copied is the root of the search tree, the children can share some elements with the root.
52 * For instance, this is the case of propagators in `PC`.
53 * This enables to share data among GPU blocks to avoid duplicating similar data, and to ease the contention on L2 cache. */
54 bool shared_copy;
55
56public:
57 CUDA AbstractDeps(bool shared_copy, const Allocators&... allocators)
58 : shared_copy(shared_copy)
59 , allocators(allocators...)
60 , deps(battery::get<0>(this->allocators))
61 {}
62
63 CUDA AbstractDeps(const Allocators&... allocators)
64 : AbstractDeps(false, allocators...) {}
65
66 CUDA size_t size() const {
67 return deps.size();
68 }
69
70 CUDA bool is_shared_copy() const {
71 return shared_copy;
72 }
73
74 template<class A>
76 assert(aty != UNTYPED);
77 assert(deps.size() > aty);
78 assert(deps[aty]);
79 return static_cast<dep_holder<A>*>(deps[aty].get())->a;
80 }
81
82 template<class A2, class A>
84 {
85 auto to_alloc = battery::get<typename A2::allocator_type>(allocators);
86 if(!a) {
87 return abstract_ptr<A2>{to_alloc};
88 }
89 assert(a->aty() != UNTYPED); // Abstract domain must all have a unique identifier to be copied.
90 // If the dependency is not in the list, we copy it and add it.
91 if(deps.size() <= a->aty() || !static_cast<bool>(deps[a->aty()])) {
92 deps.resize(battery::max((int)deps.size(), a->aty()+1));
93 allocator_type internal_alloc = battery::get<0>(allocators);
94 A2* a2 = static_cast<A2*>(to_alloc.allocate(sizeof(A2)));
95 new(a2) A2(*a, *this);
96 dep_holder<A2>* dep_hold = static_cast<dep_holder<A2>*>(internal_alloc.allocate(sizeof(dep_holder<A2>)));
97 new(dep_hold) dep_holder<A2>(a2);
98 deps[a->aty()] = battery::unique_ptr<dep_erasure, allocator_type>(
99 dep_hold, internal_alloc);
100 // NOTE: Since we are copying a DAG, `A(*a, *this)` or one of its dependency cannot create `deps[a->aty()]`.
101 }
102 return extract<A2>(a->aty());
103 }
104
105 template <class Alloc>
106 CUDA Alloc get_allocator() const {
107 return battery::get<Alloc>(allocators);
108 }
109};
110
111}
112
113#endif
Definition abstract_deps.hpp:28
CUDA Alloc get_allocator() const
Definition abstract_deps.hpp:106
CUDA AbstractDeps(bool shared_copy, const Allocators &... allocators)
Definition abstract_deps.hpp:57
CUDA abstract_ptr< A > extract(AType aty)
Definition abstract_deps.hpp:75
typename battery::tuple_element< 0, battery::tuple< Allocators... > >::type allocator_type
Definition abstract_deps.hpp:34
CUDA NI abstract_ptr< A2 > clone(const abstract_ptr< A > &a)
Definition abstract_deps.hpp:83
CUDA size_t size() const
Definition abstract_deps.hpp:66
CUDA bool is_shared_copy() const
Definition abstract_deps.hpp:70
CUDA AbstractDeps(const Allocators &... allocators)
Definition abstract_deps.hpp:63
battery::tuple< Allocators... > allocators_type
Definition abstract_deps.hpp:33
static constexpr size_t n
Definition abstract_deps.hpp:30
Definition ast.hpp:210
Definition abstract_deps.hpp:14
int AType
Definition sort.hpp:18
battery::shared_ptr< A, typename A::allocator_type > abstract_ptr
Definition abstract_deps.hpp:17
#define UNTYPED
Definition sort.hpp:21