PBeFS
Parallel Best-First Search
Loading...
Searching...
No Matches
ConcurrentClosed.h
Go to the documentation of this file.
1/*--------------------------------------------------------------------------*/
2/*------------------------ File ConcurrentClosed.h -------------------------*/
3/*--------------------------------------------------------------------------*/
28/*--------------------------------------------------------------------------*/
29/*------------------------------ DEFINITIONS -------------------------------*/
30/*--------------------------------------------------------------------------*/
31
32#ifndef __PBeFS_ads_ConcurrentClosed
33 #define __PBeFS_ads_ConcurrentClosed
34 /* self-identification: #endif at the end of the file */
35
36/*--------------------------------------------------------------------------*/
37/*-------------------------------- INCLUDES --------------------------------*/
38/*--------------------------------------------------------------------------*/
39
40#include <atomic>
41
42#include <cstddef>
43
44#include <cstdint>
45
46#include <memory>
47
48#include <mutex>
49
50#include <variant>
51
52#include "ADS/concurrent/ConcurrentFlatTable.h"
53
54#include "PBeFS/astar/Domain.h"
55
56#include "PBeFS/astar/Node.h"
57
59
60
61/*--------------------------------------------------------------------------*/
62/*------------------------------- NAMESPACE --------------------------------*/
63/*--------------------------------------------------------------------------*/
64
66namespace PBeFS_di_unipi_it
67{
68
69/*--------------------------------------------------------------------------*/
70/*------------------------- CLASS ConcurrentClosed -------------------------*/
71/*--------------------------------------------------------------------------*/
73
74
75template< Domain D , class Lock >
77
78 public:
79
81 using Cost = cost_t< D >;
83
84 static_assert( alignof( Cost ) >=
85 std::atomic_ref< Cost >::required_alignment );
86
88 struct Local {
90 NodeT * spare = nullptr;
91
93 [[nodiscard]] std::size_t stored( void ) const {
94 return( pool.size() - ( spare ? 1 : 0 ) );
95 }
96 };
97
99 struct Successor {
103 std::uint64_t hash;
104 std::uint8_t op = no_op;
105 };
106
108
109 explicit ConcurrentClosed( const D & domain )
110 : f_domain( domain ) , f_table( 0 , ByState{ &domain } ) {}
111
113
114 Lock & lock( const NodeT * n ) {
115 const auto a = std::uint64_t( reinterpret_cast< std::uintptr_t >( n ) );
116 return( f_stripes[ ( ( a >> 4 ) * 0x9E3779B97F4A7C15ULL ) >> 56 ].lock );
117 }
118
121
122 void prefetch( std::uint64_t hash ) const { f_table.prefetch( hash ); }
123
126
127 NodeT * update( const State & t , std::uint64_t hash , Cost g , Cost h ,
128 NodeT * parent , std::uint8_t op , Local & local ,
129 std::uint64_t & duplicates ) {
130 if( ! local.spare )
131 local.spare = local.pool.allocate();
132 *local.spare = NodeT{ t , g , h , parent , false , false , op };
133 const auto [ x , fresh ] = f_table.findOrInsertKey( local.spare , hash );
134 if( fresh ) {
135 local.spare = nullptr;
136 return( x );
137 }
138 if( g < std::atomic_ref< Cost >( x->g ).load(
139 std::memory_order_relaxed ) ) {
140 std::lock_guard< Lock > guard( lock( x ) );
141 if( g < x->g ) {
142 std::atomic_ref< Cost >( x->g ).store( g , std::memory_order_relaxed );
143 x->parent = parent;
144 x->op = op;
145 x->closed = false;
146 return( x );
147 }
148 }
149 ++duplicates;
150 return( nullptr );
151 }
152
153 private:
154
155 // the hash of the state of a node, well spread by the Domain
156 struct ByState {
157 using is_avalanching = void;
158 const D * d;
159 std::uint64_t operator()( const NodeT * n ) const {
160 return( d->hash( n->state ) );
161 }
162 };
163
164 // the equality of the states of two nodes
165 struct SameState {
166 bool operator()( const NodeT * a , const NodeT * b ) const {
167 return( a->state == b->state );
168 }
169 };
170
171 static constexpr unsigned c_stripes = 256;
172
173 // a lock on a line of its own
174 struct alignas( cache_line ) Stripe {
175 Lock lock;
176 };
177
178 using Table = ADS::ConcurrentFlatTable< NodeT * , std::monostate , ByState ,
179 SameState >;
180 static_assert( Table::packed );
181
182 const D & f_domain;
183 Table f_table;
184 std::unique_ptr< Stripe[] > f_stripes{ new Stripe[ c_stripes ] };
185
186 }; // end( class( ConcurrentClosed ) )
187
188/*--------------------------------------------------------------------------*/
189
190} // end( namespace PBeFS_di_unipi_it )
191
192/*--------------------------------------------------------------------------*/
193
194#endif /* __PBeFS_ads_ConcurrentClosed */
195
196/*--------------------------------------------------------------------------*/
197/*---------------------- End File ConcurrentClosed.h -----------------------*/
198/*--------------------------------------------------------------------------*/
Header file for the concepts a search problem has to satisfy in order to be searched by the algorithm...
Header file for the class template Node, a node of the search graph, for the class template NodePool,...
Header file for the small helpers shared by the searches: a stopwatch, the placement of the workers o...
void prefetch(std::uint64_t hash) const
the tags and the word that the lookup of the hash reads first, fetched with no wait
Definition ConcurrentClosed.h:122
state_t< D > State
the state type
Definition ConcurrentClosed.h:80
ConcurrentClosed(const D &domain)
constructor, taking the Domain (which must outlive the table)
Definition ConcurrentClosed.h:109
Node< State, Cost > NodeT
the node type
Definition ConcurrentClosed.h:82
cost_t< D > Cost
the cost type
Definition ConcurrentClosed.h:81
Lock & lock(const NodeT *n)
the lock of the node n, chosen by its address
Definition ConcurrentClosed.h:114
NodeT * update(const State &t, std::uint64_t hash, Cost g, Cost h, NodeT *parent, std::uint8_t op, Local &local, std::uint64_t &duplicates)
records the path to t of cost g through parent and op [see ConcurrentClosed.h]
Definition ConcurrentClosed.h:127
the arena of the nodes, on the Arena of ADS, on huge pages
Definition NodePool.h:48
namespace for the Parallel Best-First Search library
Definition AStar.h:83
typename D::cost_type cost_t
the cost type of a Domain
Definition Domain.h:245
typename D::state_type state_t
the state type of a Domain
Definition Domain.h:241
constexpr std::uint8_t no_op
the operator of the root, which no state was generated by
Definition Domain.h:205
the nodes that a worker allocates, and its spare node
Definition ConcurrentClosed.h:88
NodeT * spare
not in the table
Definition ConcurrentClosed.h:90
std::size_t stored(void) const
the number of the nodes in the table
Definition ConcurrentClosed.h:93
NodePool< NodeT > pool
the nodes
Definition ConcurrentClosed.h:89
a state generated, with its g, its h and its hash
Definition ConcurrentClosed.h:99
std::uint8_t op
the operator of t
Definition ConcurrentClosed.h:104
State state
the state
Definition ConcurrentClosed.h:100
Cost g
its g
Definition ConcurrentClosed.h:101
Cost h
its h
Definition ConcurrentClosed.h:102
std::uint64_t hash
its hash
Definition ConcurrentClosed.h:103
a node of the search graph
Definition Node.h:74
std::uint8_t op
the operator that generated the state
Definition Node.h:82