Building and using the library

The library needs a C++20 compiler, CMake 3.21 or GNU make, and ADS, whose headers CMake finds by find_package(ADS) (with ADS_ROOT as a hint) or else downloads at the commit PBEFS_ADS_COMMIT, and the makefiles take from ADSSDR. OpenMP, MPI and FastFlow are optional, and each of them is used if it is found. FastFlow is header-only: CMake looks for it in FASTFLOW_ROOT (/opt/fastflow by default) and on the include path, and if it is not there downloads the commit PBEFS_FASTFLOW_COMMIT (unless PBEFS_FETCH_FASTFLOW is OFF), while the makefiles take its headers from FF_ROOT (/opt/fastflow by default on Linux and macOS). With CMake one has

git clone https://github.com/dmeoli/PBeFS.git
cmake -S PBeFS -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build -j
ctest --test-dir build
cmake --install build --prefix <prefix>

where PBEFS_WITH_OPENMP, PBEFS_WITH_MPI and PBEFS_WITH_FASTFLOW (all ON by default) can exclude a runtime, PBEFS_STRUCTURES chooses the data structures of A* (ads, the default, std, or boost, which needs Boost 1.81 or later; the makefiles take it from PBeFSSTRUCT), and PBEFS_BUILD_TESTS, PBEFS_BUILD_EXAMPLES and PBEFS_BUILD_TOOLS (ON only when PBeFS is the top-level project) the tests, the examples and the benchmark. A CMake project then uses the library with

find_package(PBeFS REQUIRED)
target_link_libraries(myTarget PRIVATE PBeFS::PBeFS)

adding PBeFS::OpenMP, PBeFS::MPI or PBeFS::FastFlow for the corresponding runtime; these are the components of the package, each present if the library was built with its runtime and the runtime is found again by the project that uses it; hence, find_package(PBeFS REQUIRED COMPONENTS OpenMP) fails without OpenMP, while find_package(PBeFS) finds the package with no PBeFS::OpenMP. Without CMake, pkg-config --cflags --libs pbefs gives the flags of the library alone. The packages of vcpkg, conda-forge, Homebrew, Debian and Ubuntu (libpbefs-dev), Conan, Spack, Nix, the AUR, MSYS2, xmake and Meson WrapDB install the same files from the recipes of packaging, on the package of ADS of the same channel, with OpenMP where the compiler has it, MPI only where the channel lets one choose it, and without FastFlow, which no channel packages. Without installing anything, a CMake project can also take PBeFS at configure time, with FetchContent (CMake 3.24 or later),

include(FetchContent)
FetchContent_Declare(PBeFS
    URL https://github.com/dmeoli/PBeFS/releases/download/v0.1.0/PBeFS-0.1.0.tar.gz
    FIND_PACKAGE_ARGS 0.1)               # an installed PBeFS, if there is one
FetchContent_MakeAvailable(PBeFS)
target_link_libraries(<target> PRIVATE PBeFS::PBeFS)

or with CPM.cmake,

CPMAddPackage("gh:dmeoli/PBeFS@0.1.0")
target_link_libraries(<target> PRIVATE PBeFS::PBeFS)

and as a subproject PBeFS builds neither its tests nor its examples nor its tools. With Meson, meson wrap install pbefs and dependency('pbefs'), from WrapDB, in C++20. Since the searches are templates over the Domain, they are in the headers, and the library (src) holds only what does not depend on it, i.e., the grid maps and the measures of a search. Without CMake, the makefiles in the root give the library in three ways to the makefile of a program that uses it, which needs only to include one of them: makefile builds the objects and exports them together with the include directive and the list of the headers, makefile-c adds the external libraries of the runtimes (the threads, OpenMP and FastFlow), and makefile-inc gives instead the library already built, lib/libPBeFS.a, which make -f makefile-lib builds and make -f makefile-lib install PREFIX=<prefix> installs. makefile-OS adapts them to the operating system and to the compiler (CC=g++ or CC=clang++), and the places of the external libraries are those of extlib/makefile-default-paths-linux, -macos and -win (FastFlow in FF_ROOT, ADS in ADSSDR, Boost in BOOST_ROOT and, for Apple clang, the OpenMP runtime of LLVM in OMP_ROOT), unless they are given on the command line or in extlib/makefile-paths, which git ignores. In examples, test and tools a makefile builds the corresponding programs, in test the targets check and check_mpi also run the tests, and in the root make, make test, make test_mpi and make install do the same for the whole repository. Both CMake and the makefiles are tested on Linux, macOS and Windows (with MSYS2, and CMake also with MSVC), with g++ and with clang++; on Windows FastFlow, which relies on POSIX, and MPI are left out.

As an example, a minimal program that solves the instance 1 of Korf [7] sequentially, and then with HDA* and Abstract Zobrist hashing on 8 threads, reads

#include "PBeFS/PBeFS.h"
using namespace PBeFS_di_unipi_it;

int main( void )
{
 const FifteenPuzzle d( FifteenPuzzle::parse(
                         "14 13 15 7 11 12 9 5 6 0 2 1 4 8 10 3" ) );
 const auto s = astar( d );
 ParallelOptions o;
 o.threads = 8;
 const AbstractZobristDistribution< FifteenPuzzle > az( d );
 const auto p = HDAStar< FifteenPuzzle , decltype( az ) >( d , az , o )
                 .solve();
 return( ( s.cost == 57 ) && ( p.cost == 57 ) ? 0 : 1 );
 }

The documentation is at dmeoli.github.io/PBeFS: a site of Sphinx with the theme of Read the Docs (light or dark), made of the sections of this README, of the pages of the theory in docs/theory (A* with its invariants and the cost of its operations, the parallel A* searches, branch-and-bound and its parallel schemes, with what each one guarantees), and of the reference of the classes and of the functions that Breathe renders from the comments of the headers (through Doxygen), where the page of each search gives its pseudocode, arranged by layer, by group of headers (the searches, the domains, the runtimes, and so on), by header and by class. Locally, with Doxygen installed, pip install -r docs/requirements.txt, then python3 docs/pages.py && sphinx-build -b html docs build-docs/html.