Missing Parameter in the NDL macros

Oct 31, 2014 at 7:26 AM
Sometimes I miss a parameter in the parameter list of a macro (i.e. a variable is used inside the macro but not declared in the input parameter set), and CNTK keep looping forever in this function.
// GetScalar - Get a scalar value from a node, may loop through some variables before arriving
    // returns: scalar value
    ConfigValue GetScalar()
    {
        NDLNode<ElemType>* node = this;
        while (node && (node->GetType() == ndlTypeVariable || node->GetType() == ndlTypeParameter))
        {
            node = node->FindNode(node->GetValue(), true /*searchForDotNames*/);
        }
        if (!node || node->GetType() != ndlTypeConstant)
        {
            std::string name = node->GetName();
            RuntimeError("Scalar expected, '%s' must be a constant or variable that resolves to a constant\n", name.c_str());
        }
        return node->GetValue();
    }
a simple case that can lead to that situation: OutputDimension is missing
ErrorNetwork(Input, InputDimension)
{
    W = Parameter(OutputDimension. InputDimension);
    ErrorNetwork = Times(W, Input);
}
It would be very nice if there is a way to detect that case and throw an exception and showing an error message in the log file (or console output).
Coordinator
Nov 7, 2014 at 8:48 AM
Edited Nov 7, 2014 at 8:49 AM
A missing parameter detector is now added to catch the error in the main branch. If you would like to add it directly to your own fork, replace the original GetScalar function with the following one.
    // GetScalar - Get a scalar value from a node, may loop through some variables before arriving
    // returns: scalar value
    ConfigValue GetScalar()
    {
        NDLNode<ElemType>* node = this;
        while (node && (node->GetType() == ndlTypeVariable || node->GetType() == ndlTypeParameter))
        {
            NDLNode<ElemType>* nodeLast = node;
            node = node->FindNode(node->GetValue(), true /*searchForDotNames*/);
 
            // if we are still on the same node, that means it was never resolved to anything, an undefined variable
            if (nodeLast == node)
            {
                RuntimeError("undefined Variable, '%s' found, must be declared before first use\n", node->GetName().c_str());
            }
        }
        if (!node || node->GetType() != ndlTypeConstant)
        {
            std::string name = node?node->GetName():GetName();
            RuntimeError("Scalar expected, '%s' must be a constant or variable that resolves to a constant\n", name.c_str());
        }
        return node->GetValue();
    }