Parameters

There are several reasons that one might want to set the value of a constant at compile time rather than when writing the spec. For example, the value may not be known ahead of time, or you might want to reuse the same spec with multiple different values e.g. assign different values for epsilon in a robustness specification.

Basics

Parameters can be declared using the @parameter annotation as follows:

@parameter
epsilon : Rat

Parameters can be of the following types: Bool, Index n, Nat, Int, Rat.

Similar to networks and datasets, parameters are passed in at compile time via the --parameter command line option. For example setting epsilon to the value 0.1 can be achieved using --parameter epsilon:0.1.

Inferable parameters

Sometimes the value of the parameter can be inferred from other parts of the specification, but is still inconvenient to pass in at compile time. For example, a common scenario is that the specification contains two datasets, one that contains the training or test inputs, and one that contains the corresponding outputs. It is important to guarantee that the two datasets have the same size in their first dimension, but you don’t want to specify the size upfront as you may add some more data later.

The solution in this case is to set the infer option on the parameter as follows:

@parameter(infer=True)
n : Nat

@dataset
trainingInputs : Tensor Rat [n, 10]

@dataset
trainingOutputs : Tensor Rat [n, 3]

Unlike normal parameters, inferable parameters cannot be passed in at the command line using the --parameter option. Instead the compiler will try to automatically infer their value.

For example, in the code above if the datasets passed in at compile time both have 20 training samples then the compiler will deduce that the value of n is 20. If the datasets are of different sizes then compilation will fail with a suitable error.