# Tutorial

This section will introduce the basic concepts to use the STAPL Graph Library.

We are going to implement a simple program that will read a graph from disk, compute the betweenness centrality metric for each vertex, and print out the vertex that has highest centrality value.

## Includes

First, we will include the appropriate files for the graph container, helpers for graph I/O and the algorithms we want to run.

``````#include <stapl/containers/graph/graph.hpp>
#include <stapl/containers/graph/algorithms/graph_io.hpp>
#include <stapl/containers/graph/algorithms/properties.hpp>
#include <stapl/containers/graph/algorithms/betweenness_centrality.hpp>
#include <stapl/algorithms/algorithm.hpp>
``````

We are going to use the betweenness centrality algorithm, so we need to include it. Note that we also include the general `algorithm.hpp` because want to use the STL-style algorithm `max_element`.

## Main

Every STAPL program begins with the `stapl_main` function, which is the entry point for the program. It receives the command-line arguments in `argc` and `argv` like a traditional C++ `main`. At the end of the function, we'll return 0 for success, or an error code if something went wrong.

``````stapl::exit_code stapl_main(int argc, char* argv[])
{
// ...
return 0;
}
``````

## Graph I/O

Next, we will read in a graph from the disk:

``````auto graph = stapl::load_edge_list<stapl::properties::bc_property>(argv[1]);
``````

The function `load_edge_list` will read a graph from the disk that is formatted using the traditional edge list format, which is something like:

``````num_verts num_edges
0 1
2 3
...
``````

After it reads the graph, it will populate a container and return a `graph_view` to it. Note that we are using the `bc_property` for the vertices, which will allow us to store information on the vertex to run the betweenness computation and retrieve the result.

## Algorithms

For the main computation, we will run a parallel graph algorithm and a parallel STL algorithm:

``````stapl::betweenness_centrality(graph);

auto v = stapl::max_element(graph, [](auto x, auto y) {
return x.property().BC() < y.property().BC();
});
``````

After invoking `betweenness_centrality` on the graph, all vertices will have their centrality values stored in their properties. That is, for each vertex v, `v.property().BC()` will contain the centrality value for v.

We can then use `max_element` to find the largest vertex with respect to this value. We use a custom comparison lambda to specify how we are to compare vertices. In the end, we have a reference to the vertex with highest centrality value as `v`.

## Output

Finally, we want to print out the vertex we found. We use the `stapl::do_once` construct to ensure that only a single location prints, as we do not want overlapping output.

``````stapl::do_once([&]() {
std::cout << v << " is the most important vertex!" << std::endl;
});
``````

## Running

Using a C++14 compiler with MPI, we can compile and run the code as follows:

``````\$ make most_central
\$ mpirun -np 16 ./most_central my_graph.el
189 is the most important vertex!
``````

## Full Code

The full code is below.

``````#include <stapl/containers/graph/graph.hpp>
#include <stapl/containers/graph/algorithms/graph_io.hpp>
#include <stapl/containers/graph/algorithms/properties.hpp>
#include <stapl/containers/graph/algorithms/betweenness_centrality.hpp>
#include <stapl/algorithms/algorithm.hpp>

stapl::exit_code stapl_main(int argc, char* argv[])
{
auto graph = stapl::load_edge_list<stapl::properties::bc_property>(argv[1]);

stapl::betweenness_centrality(graph);

auto v = stapl::max_element(graph, [](auto x, auto y) {
return x.property().BC() < y.property().BC();
});

stapl::do_once([&]() {
std::cout << v << " is the most important vertex!" << std::endl;
});

return 0;
}
``````