Can I call multiple algorithms?

You can call multiple algorithms on the same graph. However, it will require writing a custom property for your use case.

SGL provides example properties for all its algorithms. These are tailored for their corresponding algorithms. However, for using multiple algorithms on the same input graph, the properties need to be expanded to include a union of the individual property classes.

Create a new property class for your application. This should include the interfaces of all constituent properties for the algorithms you’d like to execute on the graph, as well as the data-members of the individual classes.

Write a proxy for the new class (see corresponding tutorial or FAQ).

Create your graph with the given property. This should now be able to work with multiple algorithms.

What are proxies?

Proxies provide an interface for accessing/modifying remote objects in a distributed system. Please see the blog post describing the rationale between proxies in STAPL.

In SGL, you’ll need to write proxies for any new vertex or edge property class that you create. This is required, since these properties may be accessed or modified by remote processes while executing algorithms, or even accessing elements globally (e.g. global-indexing into a graph to get a particular vertex’s property, since that vertex may be remote).

Writing a proxy

Proxies have the same interface as the classes which they proxy. They also derive from an Accessor class, and provide conversion operators. Proxy methods forward their calls to the class they proxy.

A typical proxy for a class my_property looks like this:

class my_property
{
  private:
  int value;

  public:
  typedef int value_type;

  value_type rank(void) const
  {  return value;  }

  void rank(value_type val)
  {  value = val;  }

 void define_type(typer& t)
 {
   t.member(value);
 }
};

template <typename Accessor>
class proxy<my_property, Accessor>
  : public Accessor
{
private:
  friend class proxy_core_access;
  typedef my_property target_t;
  typedef target_t::value_type value_type;

public:
  explicit proxy(Accessor const& acc)
    : Accessor(acc)
  { }

  operator target_t(void) const
  {  return Accessor::read();  }

  proxy const& operator=(proxy const& rhs)
  {
    Accessor::write(rhs);
    return *this;
  }

  proxy const& operator=(target_t const& rhs)
  {
    Accessor::write(rhs);
    return *this;
  }

  value_type rank(void) const
  {  return Accessor::const_invoke(&target_t::rank);  }

  void rank(value_type val)
  {  Accessor::invoke(&target_t::rank, val);  }
};

How and when do I serialize?

Anytime you have a data-member in an object or work-function, it needs to be serialized. This is done by writing a define_type(...) method for the class.

Assume a class has two data-members: int foo and string bar. The define-type method looks like:

void define_type(stapl::typer& t)
 {
   t.member(foo);
   t.member(bar);
  // … +other data-members of this class can be serialized/deserialized by calling t.member(...) for them.
 }

results matching ""

    No results matching ""