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.