55#ifndef __PBeFS_FarmAStar
56 #define __PBeFS_FarmAStar
75#include "ADS/parallel/Farm.h"
109template<
Domain D , ADS::WorkerExecutor Executor = ADS::ThreadPool ,
110 class Open = std::conditional_t<
111 std::is_integral_v< cost_t< D > > ,
133 : f_domain( domain ) , f_options( options ) {
150 const unsigned w = f_options.threads;
151 Master master( *
this );
152 std::vector< char > pinned( w , 0 );
153 const auto start = [ & ](
auto && emit , std::size_t ) {
154 if( ! ADS::isRunCaller() )
156 master.start( emit );
158 const auto back = [ & ]( Task * t ,
auto && emit ) {
159 return( master.back( t , emit ) );
161 const auto work = [ & ]( Task * t , std::size_t i ) {
162 if( ! pinned[ i ] ) {
164 if( ! ADS::isRunCaller() )
171 ADS::feedbackFarm< Task * , Task * >( *f_ex , w , start , back , work );
173 Executor ex( w + 1 );
174 ADS::feedbackFarm< Task * , Task * >( ex , w , start , back , work );
178 sol.
stats = master.f_st;
182 if( master.f_limit_hit )
185 if( master.f_goal ) {
187 sol.
cost = master.f_goal->
g;
200 std::vector< NodeT * > nodes;
201 std::vector< std::uint8_t > ops;
203 std::uint8_t > > succ;
212 explicit Master(
const FarmAStar & a ) : f_a( a ) {}
214 Master(
const Master & ) =
delete;
215 Master & operator=(
const Master & ) =
delete;
218 for( Task * t : v_free )
224 void start( E && emit ) {
225 const State s0 = f_a.f_domain.initial_state();
226 insert( s0 ,
Cost( 0 ) ,
Cost( f_a.f_domain.heuristic( s0 ) ) ,
227 nullptr ,
no_op , f_a.f_domain.hash( s0 ) );
234 bool back( Task * t , E && emit ) {
236 v_hash.resize( t->succ.size() );
237 for( std::size_t i = 0 ; i < t->succ.size() ; ++i ) {
238 v_hash[ i ] = f_a.f_domain.hash( std::get< 1 >( t->succ[ i ] ) );
239 f_table.prefetch( v_hash[ i ] );
241 for( std::size_t i = 0 ; i < t->succ.size() ; ++i ) {
242 const auto & [ k , s , c , h , o ] = t->succ[ i ];
244 NodeT * parent = t->nodes[ k ];
245 const Cost g = parent->g + c;
246 if( g + h < f_incumbent )
247 insert( s , g , h , parent , o , v_hash[ i ] );
249 if( f_a.f_options.node_limit &&
250 ( f_pool.size() >= f_a.f_options.node_limit ) )
252 v_free.push_back( t );
254 return( ( f_out > 0 ) || ( ! f_limit_hit && has_work() ) );
259 void dispatch( E && emit ) {
260 while( ! f_limit_hit && ( f_out < f_a.f_options.threads ) ) {
262 while(
NodeT * n = next() ) {
268 if( f_a.f_domain.is_goal( n->state ) ) {
269 if( n->g < f_incumbent ) {
286 t->nodes.push_back( n );
287 t->ops.push_back( n->op );
288 if( t->nodes.size() >= f_a.f_options.batch )
299 bool has_work(
void ) {
300 while( ! f_open.empty() && f_open.top().stale() )
302 return( ! f_open.empty() && ( f_open.top_f() < f_incumbent ) );
306 NodeT * next(
void ) {
307 return( has_work() ? f_open.pop().node :
nullptr );
312 std::uint8_t op , std::uint64_t hash ) {
313 auto [ x , fresh ] = f_table.find_or_insert( s , hash , [ & ] {
314 NodeT * y = f_pool.allocate();
315 *y =
NodeT{ s , g , h , parent , false , false , op };
333 NodePool< NodeT > f_pool;
334 NodeTable< NodeT > f_table;
336 std::vector< Task * > v_free;
337 std::vector< std::uint64_t > v_hash;
340 NodeT * f_goal =
nullptr;
341 bool f_limit_hit =
false;
348 void expand( Task * t )
const {
349 for( std::size_t k = 0 ; k < t->nodes.size() ; ++k ) {
350 const NodeT * n = t->nodes[ k ];
354 t->succ.emplace_back( k , s , c , h , o );
362 ParallelOptions f_options;
363 Executor * f_ex =
nullptr;
Header file for the class template HDAStar, Hash Distributed A* on a shared-memory machine,...
the OPEN list on the BucketQueue of ADS, for integer costs
Definition OpenList.h:122
state_t< D > State
the state type
Definition FarmAStar.h:122
Solution< State, Cost > SolutionT
the solution type
Definition FarmAStar.h:125
Node< State, Cost > NodeT
the node type
Definition FarmAStar.h:124
cost_t< D > Cost
the cost type
Definition FarmAStar.h:123
SolutionT solve(void) const
searches the Domain, returning the Solution
Definition FarmAStar.h:147
void set_executor(Executor &ex) noexcept
sets the Executor that runs the master and the workers, which must outlive the searches and have at l...
Definition FarmAStar.h:142
FarmAStar(const D &domain, const ParallelOptions &options={})
constructor, taking the Domain (which must outlive the FarmAStar); threads is the number of workers,...
Definition FarmAStar.h:132
the OPEN list on the DaryHeap of ADS
Definition OpenList.h:52
a wall-clock stopwatch, started at construction
Definition SearchUtils.h:175
double seconds(void) const
the seconds elapsed since the construction
Definition SearchUtils.h:182
a search domain
Definition Domain.h:103
namespace for the Parallel Best-First Search library
Definition AStar.h:83
void for_each_child(const D &d, const state_t< D > &s, cost_t< D > h, std::uint8_t op, F &&f)
the successors of s but its parent, when D knows the operators
Definition Domain.h:276
typename D::cost_type cost_t
the cost type of a Domain
Definition Domain.h:245
@ solved
an optimal path has been found
Definition Solution.h:47
@ node_limit
the limit on the stored nodes was reached first
Definition Solution.h:49
constexpr Cost infinite_cost(void) noexcept
the largest value of a cost type, used as "no incumbent yet"
Definition Node.h:100
typename D::state_type state_t
the state type of a Domain
Definition Domain.h:241
void pin_worker(unsigned i) noexcept
pins the calling thread to the i-th CPU it may run on, if PBEFS_PIN is set
Definition SearchUtils.h:77
constexpr std::uint8_t no_op
the operator of the root, which no state was generated by
Definition Domain.h:205
auto trace_path(const NodeT *goal)
the states from the root to goal, following the parent pointers
Definition Node.h:126
a node of the search graph
Definition Node.h:74
Cost g
the cost of the best path found from the root
Definition Node.h:77
the options of the parallel searches: those of the sequential search, and the parameters of the paral...
Definition HDAStar.h:114
void normalize(void) noexcept
sets to 1 any parameter that is 0
Definition SearchUtils.h:102
std::vector< std::uint64_t > expanded_by
expansions of each worker
Definition Solution.h:75
std::uint64_t stored
distinct nodes stored at the end
Definition Solution.h:73
double seconds
wall-clock time of the search
Definition Solution.h:74
std::vector< std::uint64_t > stored_by
nodes stored by each worker
Definition Solution.h:76
std::uint64_t expanded
expansions, re-expansions included
Definition Solution.h:66
a path from the initial state to a goal, and its cost
Definition Solution.h:100
std::vector< State > path
the states along the path
Definition Solution.h:104
Cost cost
the cost of the path
Definition Solution.h:103
SearchStats stats
the counters of the search
Definition Solution.h:105
Status status
how the search ended
Definition Solution.h:102