1

I am trying to set up CMake such that boost-graph is properly linked. But I am running into an error when doing

find_package(Boost REQUIRED COMPONENTS graph mpi) # finding mpi is a problem
-- Found boost_mpi 1.77.0 at ~/miniconda3/envs/xyz/lib/cmake/boost_mpi-1.77.0
--   Library has no variants and is considered not found
CMake Error at /home/tom/miniconda3/envs/pokeai/lib/cmake/Boost-1.77.0/BoostConfig.cmake:141 (find_package):
  Found package configuration file:

    ~/miniconda3/envs/xyz/lib/cmake/boost_mpi-1.77.0/boost_mpi-config.cmake

  but it set boost_mpi_FOUND to FALSE so package "boost_mpi" is considered to
  be NOT FOUND.  Reason given by package:

  No suitable build variant has been found.

I have tried to find a doc from Boost-graph for this but it seems like the cmake part is not there for the setup. A line from boost_mpi-config.cmake looks suspicious to me and it is related to the error.

To produce the problem locally, you might find the files below useful.

CMakeLists.txt used:

cmake_minimum_required(VERSION 3.23)

set(Boost_VERBOSE ON)
message(CHECK_START "Looking for MPI")
find_package(MPI REQUIRED COMPONENTS CXX C)

#find_package(Boost REQUIRED COMPONENTS graph)
find_package(Boost REQUIRED COMPONENTS graph mpi) # finding mpi is a problem
add_executable(parallel_boost_graph parallel_boost_graph.cpp)

target_link_libraries(parallel_boost_graph
        PUBLIC
        MPI::MPI_CXX
        ${Boost_LIBRARIES}
        Boost::graph
        #        Boost::mpi
        )

A small example code to reproduce the problem:

// Enable PBGL interfaces to BGL algorithms
#include <boost/graph/use_mpi.hpp>

// Communication via MPI
#include <boost/graph/distributed/mpi_process_group.hpp>

// Dijkstra's single-source shortest paths algorithm
#include <boost/graph/dijkstra_shortest_paths.hpp>

// Distributed adjacency list
#include <boost/graph/distributed/adjacency_list.hpp>

// METIS Input
#include <boost/graph/metis.hpp>

// Graphviz Output
#include <boost/graph/distributed/graphviz.hpp>

// Standard Library includes
#include <fstream>
#include <string>

#ifdef BOOST_NO_EXCEPTIONS
void boost::throw_exception(std::exception const& ex) {
  std::cout << ex.what() << std::endl;
  abort();
}
#endif

using namespace boost;
using boost::graph::distributed::mpi_process_group;

/* An undirected, weighted graph with distance values stored on the
vertices. */
typedef adjacency_list<vecS, distributedS<mpi_process_group, vecS>, undirectedS,
                       /*Vertex properties=*/property<vertex_distance_t, float>,
                       /*Edge properties=*/property<edge_weight_t, float> >
    Graph;

using namespace boost;
using boost::graph::distributed::mpi_process_group;

int main(int argc, char* argv[]) {
  boost::mpi::environment env(argc, argv);

  typedef adjacency_list<listS, distributedS<mpi_process_group, vecS>,
                         directedS,
                         no_property,                  // Vertex properties
                         property<edge_weight_t, int>  // Edge properties
                         >
      graph_t;
  typedef graph_traits<graph_t>::vertex_descriptor vertex_descriptor;
  typedef graph_traits<graph_t>::edge_descriptor edge_descriptor;

  typedef std::pair<int, int> Edge;
  const int num_nodes = 5;
  enum nodes { A, B, C, D, E };
  char name[] = "ABCDE";
  Edge edge_array[] = {Edge(A, C), Edge(B, B), Edge(B, D),
                       Edge(B, E), Edge(C, B), Edge(C, D),
                       Edge(D, E), Edge(E, A), Edge(E, B)};
  int weights[] = {1, 2, 1, 2, 7, 3, 1, 1, 1};
  int num_arcs = sizeof(edge_array) / sizeof(Edge);

  graph_t g(edge_array, edge_array + num_arcs, weights, num_nodes);
  // Keeps track of the predecessor of each vertex
  std::vector<vertex_descriptor> p(num_vertices(g));
  // Keeps track of the distance to each vertex
  std::vector<int> d(num_vertices(g));

  vertex_descriptor s = vertex(A, g);
  dijkstra_shortest_paths(g, s,
                          predecessor_map(make_iterator_property_map(
                                              p.begin(), get(vertex_index, g)))
                              .distance_map(make_iterator_property_map(
                                  d.begin(), get(vertex_index, g))));

  std::cout << std::endl;

  return EXIT_SUCCESS;
}

For your convenience, you can also check out this repo to reproduce the problem: https://bitbucket.org/cpchung/debugging-only

sehe
  • 374,641
  • 47
  • 450
  • 633
cpchung
  • 774
  • 3
  • 8
  • 23
  • Do you actually need PBGL? Your question title only mentions Boost Graph (BGL) which is 99% header-only. You only need to link for reading certain file formats – sehe Oct 25 '22 at 02:57
  • 1
    The example c++ code shown above needs the parallel part. E.g. the #include – cpchung Oct 25 '22 at 02:59

1 Answers1

1

The parallel Boost.Graph library needs Boost.MPI. The CMake find process (or better: the Boost.MPI CMake config files) tell you

No suitable build variant has been found.

This happens when there are no libboost_mpi-variant-*.cmake files next to boost_mpi-config.cmake which is the case when there was an error in packaging (e.g. however copied the files to the final destination missed those) or the Boost.MPI library simply was not build. I suspect the latter.

So what you need to do is either get a Boost installation containing Boost.MPI via whatever package manager you use which could be as simple as installing a single additional package in case the Boost libraries were split into individual packages. Or you can build & install Boost from source yourself making sure the b2 command can find the MPI headers and hence Boost.MPI is build.

Note: Using the CMake variables Boost_DEBUG and Boost_VERBOSE (set them via cmake -DBoost_DEBUG=ON) can help in finding why a library was not found or rejected.

Flamefire
  • 5,313
  • 3
  • 35
  • 70
  • Much appreciated. These are the finicky edge cases I don't use often. Do you have a recommendation between OpenMPI/MPICH when building from source? – sehe Oct 25 '22 at 11:40
  • Not sure what do you mean by that. I tried not to use conda and install boost and its components: ` sudo apt install libboost-mpi-dev sudo apt install libboost-graph-dev sudo apt install libboost-graph-parallel-dev ` Still seeing the similar error. – cpchung Oct 25 '22 at 20:18
  • Check that the Boost.MPI is actually installed (in conda path or system path), i.e. that there is a `libboost_mpi.so` (or similar) and at least 1 `libboost_mpi-variant*.cmake` file (when Boost is installed with a `boost_mpi-config.cmake`) – Flamefire Oct 26 '22 at 09:49
  • checked. Still cannot build it – cpchung Oct 28 '22 at 02:46