PBeFS
Parallel Best-First Search
Loading...
Searching...
No Matches
Distribution.h
Go to the documentation of this file.
1/*--------------------------------------------------------------------------*/
2/*-------------------------- File Distribution.h ---------------------------*/
3/*--------------------------------------------------------------------------*/
35/*--------------------------------------------------------------------------*/
36/*------------------------------ DEFINITIONS -------------------------------*/
37/*--------------------------------------------------------------------------*/
38
39#ifndef __PBeFS_Distribution
40 #define __PBeFS_Distribution
41 /* self-identification: #endif at the end of the file */
42
43/*--------------------------------------------------------------------------*/
44/*-------------------------------- INCLUDES --------------------------------*/
45/*--------------------------------------------------------------------------*/
46
47#include <concepts>
48
49#include <cstddef>
50
51#include <cstdint>
52
53#include <random>
54
55#include <string>
56
57#include <utility>
58
59#include <vector>
60
61#if defined( _MSC_VER )
62 #include <intrin.h>
63#endif
64
65#include "PBeFS/astar/Domain.h"
66
67#include "ADS/dictionary/RandomHashing.h"
68
69/*--------------------------------------------------------------------------*/
70/*------------------------------- NAMESPACE --------------------------------*/
71/*--------------------------------------------------------------------------*/
72
74namespace PBeFS_di_unipi_it
75{
76
77/*--------------------------------------------------------------------------*/
78/*------------------------------- FUNCTIONS --------------------------------*/
79/*--------------------------------------------------------------------------*/
81
84
85[[nodiscard]] inline unsigned reduce( std::uint64_t h , unsigned p ) noexcept
86{
87 #if defined( __SIZEOF_INT128__ )
88 __extension__ using u128 = unsigned __int128;
89 return( unsigned( ( u128( h ) * p ) >> 64 ) );
90 #elif defined( _MSC_VER )
91 return( unsigned( __umulh( h , p ) ) );
92 #else
93 return( unsigned( h % p ) );
94 #endif
95 }
96
97/*--------------------------------------------------------------------------*/
99
101
102[[nodiscard]] inline unsigned key_owner( std::uint32_t k , unsigned p )
103 noexcept
104{
105 return( reduce( std::uint64_t( k ) << 32 , p ) );
106 }
107
108/*--------------------------------------------------------------------------*/
109/*----------------------- CLASS ZobristDistribution ------------------------*/
110/*--------------------------------------------------------------------------*/
112
120
121template< FeatureDomain D >
123
124 public:
125
127
128 explicit ZobristDistribution( const D & domain , std::uint64_t seed = 1 )
129 : f_domain( domain ) , f_r( domain.num_features() , 1 , seed ) {}
130
132
133 [[nodiscard]] std::uint64_t hash( const state_t< D > & s ) const {
134 std::uint64_t z = 0;
135 f_domain.for_each_feature( s , [ & ]( std::size_t i ) {
136 z ^= f_r( i , 0 );
137 } );
138 return( z );
139 }
140
142
143 [[nodiscard]] std::uint32_t key( const state_t< D > & s ) const {
144 return( std::uint32_t( hash( s ) >> 32 ) );
145 }
146
148
149 [[nodiscard]] unsigned owner( const state_t< D > & s , unsigned p ) const {
150 return( key_owner( key( s ) , p ) );
151 }
152
154
156
157 [[nodiscard]] std::uint32_t key( std::uint32_t k , const state_t< D > & s ,
158 const state_t< D > & t ) const
160 f_domain.for_each_feature_change( s , t , [ & ]( std::size_t i ) {
161 k ^= std::uint32_t( f_r( i , 0 ) >> 32 );
162 } );
163 return( k );
164 }
165
167
168 [[nodiscard]] static std::string name( void ) { return( "Z" ); }
169
170 private:
171
172 const D & f_domain;
173 ADS::ZobristTable f_r;
174
175 }; // end( class( ZobristDistribution ) )
176
177/*--------------------------------------------------------------------------*/
178/*------------------- CLASS AbstractZobristDistribution --------------------*/
179/*--------------------------------------------------------------------------*/
181
189
190template< AbstractFeatureDomain D >
192
193 public:
194
196
197 explicit AbstractZobristDistribution( const D & domain ,
198 std::uint64_t seed = 1 )
199 : f_domain( domain ) , v_r( domain.num_features() ) {
200 const ADS::ZobristTable r0( domain.num_abstract_features() , 1 , seed );
201 for( std::size_t i = 0 ; i < v_r.size() ; ++i )
202 v_r[ i ] = r0( domain.abstract_feature( i ) , 0 );
203 }
204
206
207 [[nodiscard]] std::uint64_t hash( const state_t< D > & s ) const {
208 std::uint64_t z = 0;
209 f_domain.for_each_feature( s , [ & ]( std::size_t i ) { z ^= v_r[ i ]; } );
210 return( z );
211 }
212
214
215 [[nodiscard]] std::uint32_t key( const state_t< D > & s ) const {
216 return( std::uint32_t( hash( s ) >> 32 ) );
217 }
218
220
221 [[nodiscard]] unsigned owner( const state_t< D > & s , unsigned p ) const {
222 return( key_owner( key( s ) , p ) );
223 }
224
226
228
229 [[nodiscard]] std::uint32_t key( std::uint32_t k , const state_t< D > & s ,
230 const state_t< D > & t ) const
232 f_domain.for_each_feature_change( s , t , [ & ]( std::size_t i ) {
233 k ^= std::uint32_t( v_r[ i ] >> 32 );
234 } );
235 return( k );
236 }
237
239
240 [[nodiscard]] static std::string name( void ) { return( "AZ" ); }
241
242 private:
243
244 const D & f_domain;
245 std::vector< std::uint64_t > v_r;
246
247 }; // end( class( AbstractZobristDistribution ) )
248
249/*--------------------------------------------------------------------------*/
250/*-------------------- CLASS AbstractStateDistribution ---------------------*/
251/*--------------------------------------------------------------------------*/
253
256
257template< AbstractStateDomain D >
259
260 public:
261
262 explicit AbstractStateDistribution( const D & domain ,
263 std::uint64_t seed = 1 )
264 : f_domain( domain ) , f_seed( ADS::splitmix64( seed ) ) {}
265
267
268 [[nodiscard]] unsigned owner( const state_t< D > & s , unsigned p ) const {
269 return( reduce( ADS::splitmix64( f_domain.abstract_state( s ) ^
270 f_seed ) , p ) );
271 }
272
274
275 [[nodiscard]] static std::string name( void ) { return( "A" ); }
276
277 private:
278
279 const D & f_domain;
280 std::uint64_t f_seed;
281
282 }; // end( class( AbstractStateDistribution ) )
283
284/*--------------------------------------------------------------------------*/
285/*--------------------- CLASS PerfectHashDistribution ----------------------*/
286/*--------------------------------------------------------------------------*/
288
292
293template< PerfectHashDomain D >
295
296 public:
297
298 explicit PerfectHashDistribution( const D & domain , std::uint64_t = 1 )
299 : f_domain( domain ) {}
300
301 [[nodiscard]] unsigned owner( const state_t< D > & s , unsigned p ) const {
302 return( unsigned( f_domain.perfect_hash( s ) % p ) );
303 }
304
305 [[nodiscard]] static std::string name( void ) { return( "P" ); }
306
307 private:
308
309 const D & f_domain;
310
311 }; // end( class( PerfectHashDistribution ) )
312
313/*--------------------------------------------------------------------------*/
314/*---------------------- CLASS StateHashDistribution -----------------------*/
315/*--------------------------------------------------------------------------*/
317
320
321template< Domain D >
323
324 public:
325
326 explicit StateHashDistribution( const D & domain , std::uint64_t seed = 1 )
327 : f_domain( domain ) , f_seed( ADS::splitmix64( seed ) ) {}
328
329 [[nodiscard]] unsigned owner( const state_t< D > & s , unsigned p ) const {
330 return( reduce( ADS::splitmix64( f_domain.hash( s ) ^ f_seed ) , p ) );
331 }
332
333 [[nodiscard]] static std::string name( void ) { return( "H" ); }
334
335 private:
336
337 const D & f_domain;
338 std::uint64_t f_seed;
339
340 }; // end( class( StateHashDistribution ) )
341
342/*--------------------------------------------------------------------------*/
343/*------------------------ CLASS RandomDistribution ------------------------*/
344/*--------------------------------------------------------------------------*/
346
350
351template< Domain D >
353
354 public:
355
356 explicit RandomDistribution( const D & , std::uint64_t seed = 1 )
357 : f_gen( seed ) {}
358
359 [[nodiscard]] unsigned owner( const state_t< D > & , unsigned p ) const {
360 return( reduce( f_gen() , p ) );
361 }
362
363 [[nodiscard]] static std::string name( void ) { return( "R" ); }
364
366 static constexpr bool per_worker = true;
367
368 private:
369
370 mutable std::mt19937_64 f_gen;
371
372 }; // end( class( RandomDistribution ) )
373
374/*--------------------------------------------------------------------------*/
375/*-------------------------------- CONCEPTS --------------------------------*/
376/*--------------------------------------------------------------------------*/
378
383
384template< class X , class D >
386 requires( const X & x , const state_t< D > & s , std::uint32_t k ,
387 unsigned p ) {
388 { x.key( s ) } -> std::same_as< std::uint32_t >;
389 { x.key( k , s , s ) } -> std::same_as< std::uint32_t >;
390 { x.owner( s , p ) } -> std::convertible_to< unsigned >;
391 };
392
393/*--------------------------------------------------------------------------*/
394/*------------------------------- FUNCTIONS --------------------------------*/
395/*--------------------------------------------------------------------------*/
397
398template< Domain D , class X >
399[[nodiscard]] std::uint32_t distribution_key( const X & x ,
400 const state_t< D > & s ) {
402 return( x.key( s ) );
403 else
404 return( 0 );
405 }
406
407/*--------------------------------------------------------------------------*/
409
412
413template< Domain D , class X >
414[[nodiscard]] auto successor_owners( const X & x , const state_t< D > & s ,
415 std::uint32_t k , unsigned p ) {
417 return( [ & x , & s , k , p ]( const state_t< D > & t ) {
418 const std::uint32_t kt = x.key( k , s , t );
419 return( std::pair( key_owner( kt , p ) , kt ) );
420 } );
421 else
422 return( [ & x , p ]( const state_t< D > & t ) {
423 return( std::pair( unsigned( x.owner( t , p ) ) , std::uint32_t( 0 ) ) );
424 } );
425 }
426
427} // end( namespace PBeFS_di_unipi_it )
428
429/*--------------------------------------------------------------------------*/
430
431#endif /* __PBeFS_Distribution */
432
433/*--------------------------------------------------------------------------*/
434/*------------------------ End File Distribution.h -------------------------*/
435/*--------------------------------------------------------------------------*/
Header file for the concepts a search problem has to satisfy in order to be searched by the algorithm...
static std::string name(void)
the name in the notation of Jinnai and Fukunaga
Definition Distribution.h:275
unsigned owner(const state_t< D > &s, unsigned p) const
the owner of s among p workers
Definition Distribution.h:268
AbstractStateDistribution(const D &domain, std::uint64_t seed=1)
Definition Distribution.h:262
static std::string name(void)
the name in the notation of Jinnai and Fukunaga
Definition Distribution.h:240
AbstractZobristDistribution(const D &domain, std::uint64_t seed=1)
constructor, drawing the table of the abstract features from the seed
Definition Distribution.h:197
std::uint32_t key(const state_t< D > &s) const
the key of s, the high 32 bits of its hash
Definition Distribution.h:215
unsigned owner(const state_t< D > &s, unsigned p) const
the owner of s among p workers, that of its key
Definition Distribution.h:221
std::uint64_t hash(const state_t< D > &s) const
the abstract Zobrist hash of s
Definition Distribution.h:207
std::uint32_t key(std::uint32_t k, const state_t< D > &s, const state_t< D > &t) const
the key of t, a successor of s whose key is k
Definition Distribution.h:229
static std::string name(void)
Definition Distribution.h:305
PerfectHashDistribution(const D &domain, std::uint64_t=1)
Definition Distribution.h:298
unsigned owner(const state_t< D > &s, unsigned p) const
Definition Distribution.h:301
static std::string name(void)
Definition Distribution.h:363
static constexpr bool per_worker
true: each worker needs its own copy
Definition Distribution.h:366
unsigned owner(const state_t< D > &, unsigned p) const
Definition Distribution.h:359
RandomDistribution(const D &, std::uint64_t seed=1)
Definition Distribution.h:356
static std::string name(void)
Definition Distribution.h:333
StateHashDistribution(const D &domain, std::uint64_t seed=1)
Definition Distribution.h:326
unsigned owner(const state_t< D > &s, unsigned p) const
Definition Distribution.h:329
static std::string name(void)
the name in the notation of Jinnai and Fukunaga
Definition Distribution.h:168
std::uint32_t key(const state_t< D > &s) const
the key of s, the high 32 bits of its hash
Definition Distribution.h:143
unsigned owner(const state_t< D > &s, unsigned p) const
the owner of s among p workers, that of its key
Definition Distribution.h:149
std::uint64_t hash(const state_t< D > &s) const
the Zobrist hash of s
Definition Distribution.h:133
std::uint32_t key(std::uint32_t k, const state_t< D > &s, const state_t< D > &t) const
the key of t, a successor of s whose key is k
Definition Distribution.h:157
ZobristDistribution(const D &domain, std::uint64_t seed=1)
constructor, drawing the table of D from the seed
Definition Distribution.h:128
a distribution whose owners follow the moves
Definition Distribution.h:385
a FeatureDomain that also gives the features changed by a move
Definition Domain.h:143
namespace for the Parallel Best-First Search library
Definition AStar.h:83
std::uint32_t distribution_key(const X &x, const state_t< D > &s)
the key of s for x, 0 if X is not an IncrementalDistribution
Definition Distribution.h:399
typename D::state_type state_t
the state type of a Domain
Definition Domain.h:241
unsigned reduce(std::uint64_t h, unsigned p) noexcept
the worker in of a 64-bit hash value
Definition Distribution.h:85
auto successor_owners(const X &x, const state_t< D > &s, std::uint32_t k, unsigned p)
the owner among p workers and the key of each successor of s
Definition Distribution.h:414
unsigned key_owner(std::uint32_t k, unsigned p) noexcept
the worker in of a 32-bit key
Definition Distribution.h:102