Config clause

In SPL, a configuration option gives a directive or a hint to the compiler.

A config clause can be specified on an operator invocation. The config clause of a composite operator definition configures all operator invocations in its graph at once. For example:

type T = int32 i;
composite Comp(output Out; input In) {
  graph  stream<T> S2  = Functor(In)  { /*...*/ }
         stream<T> S3  = Functor(S2) { /*...*/ }
         stream<T> Out = Functor(S3) { /*...*/ }
  config wrapper : gdb;
}
composite Main {
  graph  stream<T> S1 = Beacon() { }
         stream<T> S4 = Comp(S1) { }
         stream<T> S5 = Functor(S4) { /*...*/ }
}

The config wrapper: gdb directs the run time to invoke all operators that are used in the graph Comp using the GNU debugger (gdb) as a wrapper program. In general, the config at the composite level applies to each operator in the graph clause individually.

When there is configuration options both on the definition and the invocation of a composite operator, the invocation config overrides the definition config. Consider this example:

composite MyOp(output V; input U) {
  graph
    stream<int32 i> V = Functor(U) { // spl.relational.Functor
      config
        wrapper: sdb; // instance config, rank 1
    }
  config
    wrapper: gdb; // definition config, rank 3
}
composite Main {
  graph
    stream<int32 i> X = Beacon() {}
    stream<int32 i> Y = MyOp(X) {
      config
        wrapper: console; // instance config, rank 2
    }
  config
    wrapper: valgrind; // definition config, rank 4
}

The operator instance Y.V has the config wrapper: sdb. In general, a config for a primitive operator instance is resolved by first going up in the operator instance hierarchy and checking for configs that are attached to operator instances, then going up in the operator instance hierarchy and checking for configs that are attached to composite operator definitions.