Skip to content

Commit

Permalink
Reopens #9485: Optimize live execution of modified graphs (#12835)
Browse files Browse the repository at this point in the history
* optimization of execution of modified graphs

* fix live execution tests for modified inputs

* code cleanup

* code fix

* code fixes

* mark added subtrees as input subtrees

* Fix incorrect merge conflict flix

* Changes to fix build

* Run second exection via ApplyUpdate similar to previous run model

* add support for string input

* Ignore unsupported inputs (dropdown, datetime, etc)

* update for case with modified UI node

* support multiple modified inputs

* reset stackframe pointer after removing LX register

* cleanup

* cleanup

* revert breaking change of converting from struct to class

* cleanup update register for deleted ASTs

* make subtree a class again at the risk of breaking API for users

* keep Subtree a public struct

* optimize

Co-authored-by: Craig Long <[email protected]>
Co-authored-by: Craig Long <[email protected]>
  • Loading branch information
3 people authored May 19, 2022
1 parent c8a7dbd commit 7a5df1b
Show file tree
Hide file tree
Showing 16 changed files with 363 additions and 86 deletions.
33 changes: 33 additions & 0 deletions src/DynamoCore/Engine/EngineController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,39 @@ private bool VerifyGraphSyncData(IEnumerable<NodeModel> nodes)
}
}

foreach (var node in nodes)
{
if (!node.IsInputNode) continue;

// Only one or the other of the two lists, Added or Modified, will match the node GUID if they do.
bool isAdded = false;
for (int i = 0; i < graphSyncdata.AddedSubtrees.Count; i++)
{
if (graphSyncdata.AddedSubtrees[i].GUID == node.GUID)
{
graphSyncdata.AddedSubtrees[i] = new Subtree(graphSyncdata.AddedSubtrees[i])
{
IsInput = true
};
isAdded = true;
break;
}
}
if (isAdded) continue;

for (int i = 0; i < graphSyncdata.ModifiedSubtrees.Count; i++)
{
if (graphSyncdata.ModifiedSubtrees[i].GUID == node.GUID)
{
graphSyncdata.ModifiedSubtrees[i] = new Subtree(graphSyncdata.ModifiedSubtrees[i])
{
IsInput = true
};
break;
}
}
}

if (graphSyncdata.AddedSubtrees.Any() || graphSyncdata.ModifiedSubtrees.Any() || graphSyncdata.DeletedSubtrees.Any())
{
lock (graphSyncDataQueue)
Expand Down
4 changes: 2 additions & 2 deletions src/DynamoCore/Graph/Workspaces/HomeWorkspaceModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -865,11 +865,11 @@ public void Run()
/// <param name="showRunPreview">This parameter controls the delta state computation </param>
internal void GetExecutingNodes(bool showRunPreview)
{
var task = new PreviewGraphAsyncTask(scheduler, VerboseLogging);

//The Graph is executed and Show node execution is checked on the Settings menu
if (graphExecuted && showRunPreview)
{
var task = new PreviewGraphAsyncTask(scheduler, VerboseLogging);

if (task.Initialize(EngineController, this) != null)
{
task.Completed += OnPreviewGraphCompleted;
Expand Down
19 changes: 12 additions & 7 deletions src/Engine/ProtoAssociative/CodeGen.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5408,18 +5408,23 @@ private void EmitBinaryExpressionNode(AssociativeNode node, ref ProtoCore.Type i
symbolnode.datatype = inferedType;
}

//
// Jun Comment:
// Update system uses the following registers:
// _ex stores prev value of ident 't' - VM assigned
// _fx stores new value - VM assigned
//

if (bnode.LeftNode is TypedIdentifierNode)
{
EmitCast(castType.UID, castType.rank);
}

if (bnode.IsInputExpression)
{
StackValue regLX = StackValue.BuildRegister(Registers.LX);
EmitInstrConsole(kw.pop, kw.regLX);
EmitPopUpdateInstruction(regLX, bnode.OriginalAstID);

graphNode.updateBlock.updateRegisterStartPC = pc;

EmitInstrConsole(kw.push, kw.regLX);
EmitPushUpdateInstruction(regLX, bnode.OriginalAstID);
}

if (core.Options.RunMode != ProtoCore.DSASM.InterpreterMode.Expression)
{
if (dimensions == 0)
Expand Down
1 change: 1 addition & 0 deletions src/Engine/ProtoAssociative/CodeGen_SSA.cs
Original file line number Diff line number Diff line change
Expand Up @@ -488,6 +488,7 @@ private void DFSEmitSSA_AST(AssociativeNode node, Stack<AssociativeNode> ssaStac

var bnode = AstFactory.BuildAssignment(leftNode, rightNode);
bnode.isSSAAssignment = isSSAAssignment;
bnode.IsInputExpression = astBNode.IsInputExpression;

astlist.Add(bnode);
ssaStack.Push(bnode);
Expand Down
6 changes: 2 additions & 4 deletions src/Engine/ProtoCore/AssociativeGraph.cs
Original file line number Diff line number Diff line change
Expand Up @@ -746,8 +746,8 @@ public static ProtoCore.AssociativeGraph.GraphNode GetFirstSSAGraphnode(int inde
/// <param name="core"></param>
/// <param name="nodeList"></param>
/// <returns></returns>
public static AssociativeGraph.GraphNode MarkGraphNodesDirtyAtGlobalScope
(RuntimeCore core, IEnumerable<AST.AssociativeAST.AssociativeNode> nodeList)
public static AssociativeGraph.GraphNode MarkGraphNodesDirtyAtGlobalScope(
RuntimeCore core, IEnumerable<AST.AssociativeAST.AssociativeNode> nodeList)
{
if (nodeList == null)
{
Expand All @@ -767,9 +767,7 @@ public static AssociativeGraph.GraphNode MarkGraphNodesDirtyAtGlobalScope
{
if (gnode.isActive && gnode.OriginalAstID == bNode.OriginalAstID)
{

gnode.isDirty = true;
gnode.isActive = true;
if (gnode.updateBlock.updateRegisterStartPC != Constants.kInvalidIndex)
{
gnode.updateBlock.startpc = gnode.updateBlock.updateRegisterStartPC;
Expand Down
36 changes: 36 additions & 0 deletions src/Engine/ProtoCore/CodeGen.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1286,6 +1286,25 @@ protected void EmitPop(StackValue op,
AppendInstruction(instr, line, col);
}

protected void EmitPopUpdateInstruction(StackValue op,
int astID,
int blockId = Constants.kInvalidIndex,
int line = Constants.kInvalidIndex, int col = Constants.kInvalidIndex,
int eline = Constants.kInvalidIndex, int ecol = Constants.kInvalidIndex)
{
Instruction instr = new Instruction();
instr.opCode = OpCode.POP;
instr.op1 = op;
instr.op2 = StackValue.BuildInt(astID);
instr.op3 = StackValue.BuildBlockIndex(blockId);

// For debugging, assert here but these should raise runtime errors in the VM
Validity.Assert(op.IsRegister);

++pc;
AppendInstruction(instr, line, col);
}

protected void EmitSetElement(SymbolNode symbol,
int blockId,
int line = Constants.kInvalidIndex,
Expand Down Expand Up @@ -1409,6 +1428,23 @@ protected void EmitPush(StackValue op,
AppendInstruction(instr, line, col);
}

protected void EmitPushUpdateInstruction(StackValue op,
int astID,
int blockID = 0,
int line = Constants.kInvalidIndex,
int col = Constants.kInvalidIndex)
{
SetEntry();
Instruction instr = new Instruction();
instr.opCode = OpCode.PUSH;
instr.op1 = op;
instr.op2 = StackValue.BuildInt(astID);
instr.op3 = StackValue.BuildBlockIndex(blockID);

++pc;
AppendInstruction(instr, line, col);
}

private void AppendInstruction(Instruction instr, int line = Constants.kInvalidIndex, int col = Constants.kInvalidIndex)
{
if (DSASM.InterpreterMode.Expression == core.Options.RunMode)
Expand Down
53 changes: 39 additions & 14 deletions src/Engine/ProtoCore/DSASM/Executive.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ public RuntimeCore RuntimeCore
private InstructionStream istream;
public RuntimeMemory rmem { get; set; }

// Collection of registers that cache values of input literals that can be modified
// and simply accessed in an update execution cycle.
private Dictionary<long, StackValue> updateRegisters = new Dictionary<long, StackValue>();

public StackValue RX { get; set; }
public StackValue TX { get; set; }

Expand Down Expand Up @@ -66,7 +70,21 @@ enum DebugFlags
/// This is updated for every bounce and function call
/// </summary>
private List<AssociativeGraph.GraphNode> graphNodesInProgramScope;


internal void SetAssociativeUpdateRegister(long astID, StackValue sv)
{
if(updateRegisters.ContainsKey(astID))
{
updateRegisters[astID] = sv;
}
else updateRegisters.Add(astID, sv);
}

internal void DeleteUpdateRegister(long astID)
{
updateRegisters.Remove(astID);
}

public Executive(RuntimeCore runtimeCore, bool isFep = false)
{
IsExplicitCall = false;
Expand Down Expand Up @@ -731,15 +749,14 @@ public StackValue Callr(int blockDeclId,
CallSite callsite = runtimeCore.RuntimeData.GetCallSite(classIndex, fNode.Name, exe, runtimeCore);
Validity.Assert(null != callsite);

List<StackValue> registers = GetRegisters();

// Get the execution states of the current stackframe
int currentScopeClass = Constants.kInvalidIndex;
int currentScopeFunction = Constants.kInvalidIndex;
GetCallerInformation(out currentScopeClass, out currentScopeFunction);

// Handle execution states at the FEP
var stackFrame = new StackFrame(svThisPtr, ci, fi, returnAddr, blockDecl, runtimeCore.RunningBlock, fepRun ? StackFrameType.Function : StackFrameType.LanguageBlock, StackFrameType.Function, 0, rmem.FramePointer, blockDeclId, registers, 0);
var stackFrame = new StackFrame(svThisPtr, ci, fi, returnAddr, blockDecl, runtimeCore.RunningBlock,
fepRun ? StackFrameType.Function : StackFrameType.LanguageBlock, StackFrameType.Function, 0, rmem.FramePointer, blockDeclId, GetRegisters(), 0);
StackValue sv = StackValue.Null;

if (runtimeCore.Options.IDEDebugMode && runtimeCore.Options.RunMode != InterpreterMode.Expression)
Expand Down Expand Up @@ -880,9 +897,8 @@ private StackValue CallrForMemberFunction(int blockIndex,
return StackValue.Null;
}

var registers = GetRegisters();

var stackFrame = new StackFrame(thisObject, classIndex, procIndex, pc + 1, 0, runtimeCore.RunningBlock, fepRun ? StackFrameType.Function : StackFrameType.LanguageBlock, StackFrameType.Function, 0, rmem.FramePointer, 0, registers, 0);
var stackFrame = new StackFrame(thisObject, classIndex, procIndex, pc + 1, 0, runtimeCore.RunningBlock,
fepRun ? StackFrameType.Function : StackFrameType.LanguageBlock, StackFrameType.Function, 0, rmem.FramePointer, 0, GetRegisters(), 0);

var callsite = runtimeCore.RuntimeData.GetCallSite(classIndex, procNode.Name, exe, runtimeCore);

Expand Down Expand Up @@ -2339,6 +2355,13 @@ private StackValue GetOperandData(int blockId, StackValue opSymbol, StackValue o
case AddressType.Register:
switch (opSymbol.Register)
{
case Registers.LX:
if (updateRegisters.TryGetValue(opClass.IntegerValue, out StackValue sv))
{
data = sv;
}
else data = opSymbol;
break;
case Registers.RX:
data = RX;
break;
Expand Down Expand Up @@ -2452,6 +2475,13 @@ protected StackValue PopTo(int blockId, StackValue op1, StackValue op2, StackVal
StackValue data = opVal;
switch (op1.Register)
{
case Registers.LX:
if (updateRegisters.TryGetValue(op2.IntegerValue, out StackValue sv))
{
opPrev = sv;
}
SetAssociativeUpdateRegister(op2.IntegerValue, data);
break;
case Registers.RX:
opPrev = RX;
RX = data;
Expand Down Expand Up @@ -4252,19 +4282,14 @@ private void CALL_Handler(Instruction instruction)
StackValue svCallConvention = StackValue.BuildCallingConversion((int)CallingConvention.CallType.ExplicitBase);
TX = svCallConvention;


// On implicit call, the SX is set in JIL Fep
// On explicit call, the SX should be directly set here

List<StackValue> registers = GetRegisters();

// Comment Jun: the depth is always 0 for a function call as we are reseting this for each function call
// This is only incremented for every language block bounce
int depth = 0;

StackFrameType type = StackFrameType.Function;

StackFrame stackFrame = new StackFrame(svThisPointer, ci, fi, pc + 1, blockDecl, blockCaller, callerType, type, depth, rmem.FramePointer, blockDecl, registers, 0);
StackFrame stackFrame = new StackFrame(svThisPointer, ci, fi, pc + 1, blockDecl, blockCaller,
callerType, type, depth, rmem.FramePointer, blockDecl, GetRegisters(), 0);

rmem.PushFrameForLocals(fNode.LocalCount);
rmem.PushStackFrame(stackFrame);
Expand Down
1 change: 1 addition & 0 deletions src/Engine/ProtoCore/DSASM/InstructionSet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ namespace ProtoCore.DSASM
public enum Registers
{
RX,
LX,
}

public enum AddressType: int
Expand Down
5 changes: 2 additions & 3 deletions src/Engine/ProtoCore/Lang/BuiltInFunctionEndPoint.cs
Original file line number Diff line number Diff line change
Expand Up @@ -540,14 +540,13 @@ private StackValue InlineConditionalMethod(List<StackValue> formalParameters, Pr
StackValue svCallconvention = StackValue.BuildCallingConversion((int)ProtoCore.DSASM.CallingConvention.BounceType.Implicit);
interpreter.runtime.TX = svCallconvention;

List<StackValue> registers = interpreter.runtime.GetRegisters();

// Comment Jun: the caller type is the current type in the stackframe
StackFrameType callerType = stackFrame.StackFrameType;


blockCaller = runtimeCore.DebugProps.CurrentBlockId;
StackFrame bounceStackFrame = new StackFrame(svThisPtr, ci, fi, returnAddr, blockDecl, blockCaller, callerType, type, depth, framePointer, 0, registers, 0);
StackFrame bounceStackFrame = new StackFrame(svThisPtr, ci, fi, returnAddr, blockDecl, blockCaller, callerType, type,
depth, framePointer, 0, interpreter.runtime.GetRegisters(), 0);

StackValue ret = interpreter.runtime.Bounce(blockId, 0, bounceStackFrame, 0, false, runtimeCore.CurrentExecutive.CurrentDSASMExec, runtimeCore.Breakpoints);

Expand Down
4 changes: 1 addition & 3 deletions src/Engine/ProtoCore/Lang/FunctionPointerEvaluator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -107,9 +107,7 @@ public StackValue Evaluate(List<StackValue> args, StackFrame stackFrame)
interpreter.runtime.TX = StackValue.BuildCallingConversion((int)ProtoCore.DSASM.CallingConvention.BounceType.Implicit);

StackValue svBlockDecl = StackValue.BuildBlockIndex(blockDecl);
// interpreter.runtime.SX = svBlockDecl;

List<StackValue> registers = interpreter.runtime.GetRegisters();
var newStackFrame = new StackFrame(thisPtr,
classScopeCaller,
1,
Expand All @@ -121,7 +119,7 @@ public StackValue Evaluate(List<StackValue> args, StackFrame stackFrame)
0, // depth
framePointer,
svBlockDecl.BlockIndex,
registers,
interpreter.runtime.GetRegisters(),
0);

bool isInDebugMode = runtimeCore.Options.IDEDebugMode &&
Expand Down
4 changes: 1 addition & 3 deletions src/Engine/ProtoCore/Lang/JILFunctionEndPoint.cs
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,6 @@ public override StackValue Execute(ProtoCore.Runtime.Context c, List<StackValue>

StackFrameType callerType = stackFrame.CallerStackFrameType;

List<StackValue> registers = new List<DSASM.StackValue>();

StackValue svCallConvention;
bool isDispose = CoreUtils.IsDisposeMethod(procedureNode.Name);

Expand All @@ -118,7 +116,7 @@ public override StackValue Execute(ProtoCore.Runtime.Context c, List<StackValue>
// TODO Jun:
// The stackframe carries the current set of registers
// Determine if this can be done even for the non explicit call implementation
registers.AddRange(stackFrame.GetRegisters());
var registers = stackFrame.GetRegisters();


// Comment Jun: the depth is always 0 for a function call as we are reseting this for each function call
Expand Down
6 changes: 5 additions & 1 deletion src/Engine/ProtoCore/Parser/AssociativeAST.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2082,6 +2082,7 @@ public class BinaryExpressionNode : AssociativeNode
public AssociativeNode LeftNode { get; set; }
public Operator Optr { get; set; }
public AssociativeNode RightNode { get; set; }
public bool IsInputExpression { get; set; }
public bool isSSAPointerAssignment { get; set; }
public bool IsFirstIdentListNode { get; set; }

Expand All @@ -2097,6 +2098,7 @@ public BinaryExpressionNode(AssociativeNode left = null, AssociativeNode right =
LeftNode = left;
Optr = optr;
RightNode = right;
IsInputExpression = false;
IsFirstIdentListNode = false;
}

Expand All @@ -2117,6 +2119,7 @@ public BinaryExpressionNode(BinaryExpressionNode rhs) : base(rhs)
{
RightNode = NodeUtils.Clone(rhs.RightNode);
}
IsInputExpression = rhs.IsInputExpression;
IsFirstIdentListNode = rhs.IsFirstIdentListNode;
}

Expand All @@ -2140,7 +2143,8 @@ public BinaryExpressionNode(IdentifierNode lhs, AssociativeNode rhs)
Optr = Operator.assign;
LeftNode = lhs;
RightNode = NodeUtils.Clone(rhs);
IsFirstIdentListNode = false;
IsInputExpression = false;
IsFirstIdentListNode = false;

}

Expand Down
Loading

0 comments on commit 7a5df1b

Please sign in to comment.