Make a stateful computation

In this section, we show how to make a stateful computation from nGraph’s stateless operations. The basic idea is that any computation with side-effects can be factored into a stateless function that transforms the old state into the new state.

An example from C++

Let’s start with a simple C++ example, a function count that returns how many times it has already been called:

update.cpp
int count()
{
    static int counter = 0;
    return counter++;
}

The static variable counter provides state for this function. The state is initialized to 0. Every time count is called, the current value of counter is returned and counter is incremented. To convert this to use a stateless function, define a function that takes the current value of counter as an argument and returns the updated value.

std::tuple<int, int> stateless_count(int counter)
{
    return std::tuple<int, int>(counter, counter + 1);
}

To use this version of counting,

    int counter = 0;
    {
        auto r(stateless_count(counter));
        counter = std::get<1>(r);
        std::cout << std::get<0>(r);
    }
    std::cout << ", ";
    {
        auto r(stateless_count(counter));
        counter = std::get<1>(r);
        std::cout << std::get<0>(r);
    }
    std::cout << std::endl;

Update in nGraph

In working with nGraph-based construction of graphs, updating takes the same approach. During training, we include all the weights as arguments to the training function and return the updated weights along with any other results. For more complex forms of training, such as those using momentum, we would add the momentum tensors as additional arguments and include their updated values as additional results. A simple case is illustrated in the documentation for how to Derive a trainable model.