Skip to content

Commit

Permalink
[NF] Handle function derivative annotations.
Browse files Browse the repository at this point in the history
  • Loading branch information
perost authored and OpenModelica-Hudson committed Jun 11, 2018
1 parent 82c686d commit 6533bcd
Show file tree
Hide file tree
Showing 10 changed files with 422 additions and 52 deletions.
54 changes: 54 additions & 0 deletions Compiler/FrontEnd/SCode.mo
Expand Up @@ -3921,6 +3921,60 @@ algorithm
end match;
end hasNamedAnnotation;

public function lookupNamedAnnotation
"Returns the modifier with the given name if it can be found in the
annotation, otherwise an empty modifier."
input Annotation ann;
input String name;
output Mod mod;
protected
list<SubMod> submods;
String id;
algorithm
mod := match ann
case Annotation.ANNOTATION(modification = Mod.MOD(subModLst = submods))
algorithm
for sm in submods loop
SubMod.NAMEMOD(id, mod) := sm;

if id == name then
return;
end if;
end for;
then
Mod.NOMOD();

else Mod.NOMOD();
end match;
end lookupNamedAnnotation;

public function lookupNamedAnnotations
"Returns a list of modifiers with the given name found in the annotation."
input Annotation ann;
input String name;
output list<Mod> mods = {};
protected
list<SubMod> submods;
String id;
Mod mod;
algorithm
mods := match ann
case Annotation.ANNOTATION(modification = Mod.MOD(subModLst = submods))
algorithm
for sm in submods loop
SubMod.NAMEMOD(id, mod) := sm;

if id == name then
mods := mod :: mods;
end if;
end for;
then
mods;

else {};
end match;
end lookupNamedAnnotations;

public function hasBooleanNamedAnnotationInClass
input Element inClass;
input String namedAnnotation;
Expand Down
38 changes: 19 additions & 19 deletions Compiler/NFFrontEnd/NFBuiltinFuncs.mo
Expand Up @@ -128,7 +128,7 @@ constant InstNode INTEGER_DUMMY_NODE = NFInstNode.CLASS_NODE("Integer",
constant Function INTEGER_FUNCTION = Function.FUNCTION(Path.IDENT("Integer"),
INTEGER_DUMMY_NODE, {ENUM_PARAM}, {}, {}, {
Slot.SLOT("e", SlotType.POSITIONAL, NONE(), NONE())
}, Type.INTEGER(), DAE.FUNCTION_ATTRIBUTES_BUILTIN, Pointer.createImmutable(true), Pointer.createImmutable(0));
}, Type.INTEGER(), DAE.FUNCTION_ATTRIBUTES_BUILTIN, {}, Pointer.createImmutable(true), Pointer.createImmutable(0));

constant InstNode INTEGER_NODE = InstNode.CLASS_NODE("IntegerFunc",
DUMMY_ELEMENT, Visibility.PUBLIC,
Expand All @@ -153,15 +153,15 @@ constant Function STRING_REAL = Function.FUNCTION(Path.IDENT("String"),
Slot.SLOT("significantDigits", SlotType.NAMED, SOME(Expression.INTEGER(6)), NONE()),
Slot.SLOT("minimumLength", SlotType.NAMED, SOME(Expression.INTEGER(0)), NONE()),
Slot.SLOT("leftJustified", SlotType.NAMED, SOME(Expression.BOOLEAN(true)), NONE())
}, Type.STRING(), DAE.FUNCTION_ATTRIBUTES_BUILTIN,
}, Type.STRING(), DAE.FUNCTION_ATTRIBUTES_BUILTIN, {},
Pointer.createImmutable(true), Pointer.createImmutable(0));

// String(r, format="-0.6g")
constant Function STRING_REAL_FORMAT = Function.FUNCTION(Path.IDENT("String"),
STRING_DUMMY_NODE, {REAL_PARAM, STRING_PARAM}, {STRING_PARAM}, {}, {
Slot.SLOT("r", SlotType.POSITIONAL, NONE(), NONE()),
Slot.SLOT("format", SlotType.NAMED, NONE(), NONE())
}, Type.STRING(), DAE.FUNCTION_ATTRIBUTES_BUILTIN,
}, Type.STRING(), DAE.FUNCTION_ATTRIBUTES_BUILTIN, {},
Pointer.createImmutable(true), Pointer.createImmutable(0));

// String(i, minimumLength=0, leftJustified=true)
Expand All @@ -170,7 +170,7 @@ constant Function STRING_INT = Function.FUNCTION(Path.IDENT("String"),
Slot.SLOT("i", SlotType.POSITIONAL, NONE(), NONE()),
Slot.SLOT("minimumLength", SlotType.NAMED, SOME(Expression.INTEGER(0)), NONE()),
Slot.SLOT("leftJustified", SlotType.NAMED, SOME(Expression.BOOLEAN(true)), NONE())
}, Type.STRING(), DAE.FUNCTION_ATTRIBUTES_BUILTIN,
}, Type.STRING(), DAE.FUNCTION_ATTRIBUTES_BUILTIN, {},
Pointer.createImmutable(true), Pointer.createImmutable(0));

// String(b, minimumLength=0, leftJustified=true)
Expand All @@ -179,7 +179,7 @@ constant Function STRING_BOOL = Function.FUNCTION(Path.IDENT("String"),
Slot.SLOT("b", SlotType.POSITIONAL, NONE(), NONE()),
Slot.SLOT("minimumLength", SlotType.NAMED, SOME(Expression.INTEGER(0)), NONE()),
Slot.SLOT("leftJustified", SlotType.NAMED, SOME(Expression.BOOLEAN(true)), NONE())
}, Type.STRING(), DAE.FUNCTION_ATTRIBUTES_BUILTIN,
}, Type.STRING(), DAE.FUNCTION_ATTRIBUTES_BUILTIN, {},
Pointer.createImmutable(true), Pointer.createImmutable(0));

// String(e, minimumLength=0, leftJustified=true)
Expand All @@ -188,7 +188,7 @@ constant Function STRING_ENUM = Function.FUNCTION(Path.IDENT("String"),
Slot.SLOT("e", SlotType.POSITIONAL, NONE(), NONE()),
Slot.SLOT("minimumLength", SlotType.NAMED, SOME(Expression.INTEGER(0)), NONE()),
Slot.SLOT("leftJustified", SlotType.NAMED, SOME(Expression.BOOLEAN(true)), NONE())
}, Type.STRING(), DAE.FUNCTION_ATTRIBUTES_BUILTIN,
}, Type.STRING(), DAE.FUNCTION_ATTRIBUTES_BUILTIN, {},
Pointer.createImmutable(true), Pointer.createImmutable(0));

constant InstNode STRING_NODE = InstNode.CLASS_NODE("String",
Expand All @@ -213,67 +213,67 @@ constant ComponentRef STRING_CREF =

constant Function ABS_REAL = Function.FUNCTION(Path.IDENT("abs"),
InstNode.EMPTY_NODE(), {REAL_PARAM, REAL_PARAM}, {REAL_PARAM}, {}, {},
Type.REAL(), DAE.FUNCTION_ATTRIBUTES_BUILTIN,
Type.REAL(), DAE.FUNCTION_ATTRIBUTES_BUILTIN, {},
Pointer.createImmutable(true), Pointer.createImmutable(0));

constant Function MAX_INT = Function.FUNCTION(Path.IDENT("max"),
InstNode.EMPTY_NODE(), {INT_PARAM, INT_PARAM}, {INT_PARAM}, {}, {},
Type.INTEGER(), DAE.FUNCTION_ATTRIBUTES_BUILTIN,
Type.INTEGER(), DAE.FUNCTION_ATTRIBUTES_BUILTIN, {},
Pointer.createImmutable(true), Pointer.createImmutable(0));

constant Function MAX_REAL = Function.FUNCTION(Path.IDENT("max"),
InstNode.EMPTY_NODE(), {REAL_PARAM, REAL_PARAM}, {REAL_PARAM}, {}, {},
Type.REAL(), DAE.FUNCTION_ATTRIBUTES_BUILTIN,
Type.REAL(), DAE.FUNCTION_ATTRIBUTES_BUILTIN, {},
Pointer.createImmutable(true), Pointer.createImmutable(0));

constant Function DIV_INT = Function.FUNCTION(Path.IDENT("div"),
InstNode.EMPTY_NODE(), {INT_PARAM, INT_PARAM}, {INT_PARAM}, {}, {},
Type.INTEGER(), DAE.FUNCTION_ATTRIBUTES_BUILTIN,
Type.INTEGER(), DAE.FUNCTION_ATTRIBUTES_BUILTIN, {},
Pointer.createImmutable(true), Pointer.createImmutable(0));

constant Function FLOOR = Function.FUNCTION(Path.IDENT("floor"),
InstNode.EMPTY_NODE(), {REAL_PARAM}, {REAL_PARAM}, {}, {},
Type.REAL(), DAE.FUNCTION_ATTRIBUTES_BUILTIN,
Type.REAL(), DAE.FUNCTION_ATTRIBUTES_BUILTIN, {},
Pointer.createImmutable(true), Pointer.createImmutable(0));

constant Function INTEGER_REAL = Function.FUNCTION(Path.IDENT("integer"),
InstNode.EMPTY_NODE(), {REAL_PARAM}, {INT_PARAM}, {}, {},
Type.INTEGER(), DAE.FUNCTION_ATTRIBUTES_BUILTIN,
Type.INTEGER(), DAE.FUNCTION_ATTRIBUTES_BUILTIN, {},
Pointer.createImmutable(true), Pointer.createImmutable(0));

constant Function INTEGER_ENUM = Function.FUNCTION(Path.IDENT("Integer"),
InstNode.EMPTY_NODE(), {ENUM_PARAM}, {INT_PARAM}, {}, {},
Type.INTEGER(), DAE.FUNCTION_ATTRIBUTES_BUILTIN,
Type.INTEGER(), DAE.FUNCTION_ATTRIBUTES_BUILTIN, {},
Pointer.createImmutable(true), Pointer.createImmutable(0));

constant Function POSITIVE_MAX_REAL = Function.FUNCTION(Path.IDENT("$OMC$PositiveMax"),
InstNode.EMPTY_NODE(), {REAL_PARAM, REAL_PARAM}, {REAL_PARAM}, {}, {},
Type.REAL(), DAE.FUNCTION_ATTRIBUTES_BUILTIN,
Type.REAL(), DAE.FUNCTION_ATTRIBUTES_BUILTIN, {},
Pointer.createImmutable(true), Pointer.createImmutable(0));

constant Function IN_STREAM = Function.FUNCTION(Path.IDENT("inStream"),
InstNode.EMPTY_NODE(), {REAL_PARAM}, {REAL_PARAM}, {}, {},
Type.REAL(), DAE.FUNCTION_ATTRIBUTES_BUILTIN,
Type.REAL(), DAE.FUNCTION_ATTRIBUTES_BUILTIN, {},
Pointer.createImmutable(true), Pointer.createImmutable(0));

constant Function PROMOTE = Function.FUNCTION(Path.IDENT("promote"),
InstNode.EMPTY_NODE(), {}, {}, {}, {},
Type.UNKNOWN(), DAE.FUNCTION_ATTRIBUTES_BUILTIN,
Type.UNKNOWN(), DAE.FUNCTION_ATTRIBUTES_BUILTIN, {},
Pointer.createImmutable(true), Pointer.createImmutable(0));

constant Function CAT = Function.FUNCTION(Path.IDENT("cat"),
InstNode.EMPTY_NODE(), {}, {}, {}, {},
Type.UNKNOWN(), DAE.FUNCTION_ATTRIBUTES_BUILTIN,
Type.UNKNOWN(), DAE.FUNCTION_ATTRIBUTES_BUILTIN, {},
Pointer.createImmutable(true), Pointer.createImmutable(0));

constant Function ARRAY_FUNC = Function.FUNCTION(Path.IDENT("array"),
InstNode.EMPTY_NODE(), {}, {}, {}, {},
Type.UNKNOWN(), DAE.FUNCTION_ATTRIBUTES_BUILTIN,
Type.UNKNOWN(), DAE.FUNCTION_ATTRIBUTES_BUILTIN, {},
Pointer.createImmutable(true), Pointer.createImmutable(0));

constant Function FILL_FUNC = Function.FUNCTION(Path.IDENT("fill"),
InstNode.EMPTY_NODE(), {}, {}, {}, {},
Type.UNKNOWN(), DAE.FUNCTION_ATTRIBUTES_BUILTIN,
Type.UNKNOWN(), DAE.FUNCTION_ATTRIBUTES_BUILTIN, {},
Pointer.createImmutable(true), Pointer.createImmutable(0));

annotation(__OpenModelica_Interface="frontend");
Expand Down
2 changes: 1 addition & 1 deletion Compiler/NFFrontEnd/NFConvertDAE.mo
Expand Up @@ -925,7 +925,7 @@ algorithm
else DAE.FunctionDefinition.FUNCTION_DEF(listReverse(elems));
end match;
then
Function.toDAE(func, {def});
Function.toDAE(func, def);

case Class.INSTANCED_CLASS(restriction = Restriction.RECORD_CONSTRUCTOR())
then DAE.Function.RECORD_CONSTRUCTOR(Function.name(func),
Expand Down
16 changes: 7 additions & 9 deletions Compiler/NFFrontEnd/NFEvalFunction.mo
Expand Up @@ -52,6 +52,7 @@ import ElementSource;
import ModelicaExternalC;
import System;
import NFTyping.ExpOrigin;
import SCode;

encapsulated package ReplTree
import BaseAvlTree;
Expand Down Expand Up @@ -759,21 +760,18 @@ end isKnownExternalFunc;

function isKnownLibrary
input Option<SCode.Annotation> extAnnotation;
output Boolean isKnown;
output Boolean isKnown = false;
protected
SCode.Annotation ann;
Absyn.Exp exp;
Option<Absyn.Exp> oexp;
algorithm
if isSome(extAnnotation) then
SOME(ann) := extAnnotation;
oexp := SCode.getModifierBinding(SCode.lookupNamedAnnotation(ann, "Library"));

try
isKnown := isKnownLibraryExp(SCode.getNamedAnnotation(ann, "Library"));
else
isKnown := false;
end try;
else
isKnown := false;
if isSome(oexp) then
isKnown := isKnownLibraryExp(Util.getOption(oexp));
end if;
end if;
end isKnownLibrary;

Expand Down
6 changes: 6 additions & 0 deletions Compiler/NFFrontEnd/NFFlatten.mo
Expand Up @@ -1090,6 +1090,12 @@ algorithm
Function.collect(fn);
funcs := FunctionTree.add(funcs, Function.name(fn), fn);
funcs := collectClassFunctions(fn.node, funcs);

for fn_der in fn.derivatives loop
for der_fn in Function.getCachedFuncs(fn_der.derivativeFn) loop
funcs := flattenFunction(der_fn, funcs);
end for;
end for;
end if;
end flattenFunction;

Expand Down
59 changes: 37 additions & 22 deletions Compiler/NFFrontEnd/NFFunction.mo
Expand Up @@ -38,6 +38,7 @@ import NFInstNode.InstNode;
import Type = NFType;
import NFPrefixes.*;
import List;
import FunctionDerivative = NFFunctionDerivative;

protected
import ErrorExt;
Expand Down Expand Up @@ -208,6 +209,7 @@ uniontype Function
list<Slot> slots;
Type returnType;
DAE.FunctionAttributes attributes;
list<FunctionDerivative> derivatives;
Pointer<Boolean> collected "Whether this function has already been added to the function tree or not.";
Pointer<Integer> callCounter "Used during function evaluation to limit recursion.";
end FUNCTION;
Expand All @@ -228,7 +230,7 @@ uniontype Function
// Make sure builtin functions aren't added to the function tree.
collected := Pointer.create(isBuiltinAttr(attr));
fn := FUNCTION(path, node, inputs, outputs, locals, {}, Type.UNKNOWN(),
attr, collected, Pointer.create(0));
attr, {}, collected, Pointer.create(0));
end new;

function lookupFunctionSimple
Expand Down Expand Up @@ -336,6 +338,7 @@ uniontype Function
Absyn.ComponentRef cr;
InstNode sub_fnNode;
list<Function> funcs;
list<FunctionDerivative> fn_ders;

case SCode.CLASS() guard SCode.isRecord(def)
algorithm
Expand Down Expand Up @@ -367,8 +370,9 @@ uniontype Function
algorithm
fnNode := InstNode.setNodeType(NFInstNode.InstNodeType.ROOT_CLASS(), fnNode);
fnNode := instFunction3(fnNode);
fn := Function.new(fnPath, fnNode);
fn := new(fnPath, fnNode);
specialBuiltin := isSpecialBuiltin(fn);
fn.derivatives := FunctionDerivative.instDerivatives(fnNode, fn);
fnNode := InstNode.cacheAddFunc(fnNode, fn, specialBuiltin);
then
(fnNode, specialBuiltin);
Expand Down Expand Up @@ -936,27 +940,9 @@ uniontype Function
they are not already typed."
input ComponentRef functionRef;
output list<Function> functions;
protected
InstNode fn_node;
Boolean typed, special;
String name;
algorithm
functions := match functionRef
case ComponentRef.CREF(node = fn_node)
algorithm
fn_node := InstNode.classScope(fn_node);
CachedData.FUNCTION(functions, typed, special) := InstNode.getFuncCache(fn_node);

// Type the function(s) if not already done.
if not typed then
functions := list(typeFunctionSignature(f) for f in functions);
InstNode.setFuncCache(fn_node, CachedData.FUNCTION(functions, true, special));
functions := list(typeFunctionBody(f) for f in functions);
InstNode.setFuncCache(fn_node, CachedData.FUNCTION(functions, true, special));
end if;
then
functions;

case ComponentRef.CREF() then typeNodeCache(functionRef.node);
else
algorithm
Error.assertion(false, getInstanceName() + " got invalid function call reference", sourceInfo());
Expand All @@ -965,6 +951,28 @@ uniontype Function
end match;
end typeRefCache;

function typeNodeCache
"Returns the function(s) in the cache of the given node, and types them if
they are not already typed."
input InstNode functionNode;
output list<Function> functions;
protected
InstNode fn_node;
Boolean typed, special;
String name;
algorithm
fn_node := InstNode.classScope(functionNode);
CachedData.FUNCTION(functions, typed, special) := InstNode.getFuncCache(fn_node);

// Type the function(s) if not already done.
if not typed then
functions := list(typeFunctionSignature(f) for f in functions);
InstNode.setFuncCache(fn_node, CachedData.FUNCTION(functions, true, special));
functions := list(typeFunctionBody(f) for f in functions);
InstNode.setFuncCache(fn_node, CachedData.FUNCTION(functions, true, special));
end if;
end typeNodeCache;

function typeFunction
input output Function fn;
algorithm
Expand Down Expand Up @@ -1015,6 +1023,11 @@ uniontype Function

// Type the algorithm section of the function, if it has one.
Typing.typeFunctionSections(fn.node, ExpOrigin.FUNCTION);

// Type any derivatives of the function.
for fn_der in fn.derivatives loop
FunctionDerivative.typeDerivative(fn_der);
end for;
end typeFunctionBody;

function isBuiltin
Expand Down Expand Up @@ -1154,19 +1167,21 @@ uniontype Function

function toDAE
input Function fn;
input list<DAE.FunctionDefinition> defs;
input DAE.FunctionDefinition def;
output DAE.Function daeFn;
protected
SCode.Visibility vis;
Boolean par, impr;
DAE.InlineType ity;
DAE.Type ty;
list<DAE.FunctionDefinition> defs;
algorithm
vis := SCode.PUBLIC(); // TODO: Use the actual visibility.
par := false; // TODO: Use the actual partial prefix.
impr := fn.attributes.isImpure;
ity := fn.attributes.inline;
ty := makeDAEType(fn);
defs := def :: list(FunctionDerivative.toDAE(fn_der) for fn_der in fn.derivatives);
daeFn := DAE.FUNCTION(fn.path, defs, ty, vis, par, impr, ity,
DAE.emptyElementSource, SCode.getElementComment(InstNode.definition(fn.node)));
end toDAE;
Expand Down

0 comments on commit 6533bcd

Please sign in to comment.