Skip to content

Commit

Permalink
Generating more instructions
Browse files Browse the repository at this point in the history
  • Loading branch information
lsk567 committed Jun 16, 2023
1 parent e426968 commit 252912e
Show file tree
Hide file tree
Showing 12 changed files with 157 additions and 30 deletions.
14 changes: 12 additions & 2 deletions core/src/main/java/org/lflang/analyses/evm/Instruction.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package org.lflang.analyses.evm;

public interface Instruction {
abstract public class Instruction {

/** VM Instruction Set */
public enum Opcode {
Expand All @@ -26,5 +26,15 @@ public enum Opcode {
WU, // WU rs1, rs2 : Wait Until a counting variable (rs1) to reach a desired value (rs2).
}

public Opcode getOpcode();
/** Opcode of this instruction */
protected Opcode opcode;

/** A getter of the opcode */
public Opcode getOpcode() {
return this.opcode;
}

public String toString() {
return opcode.toString();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package org.lflang.analyses.evm;

public class InstructionBIT extends Instruction {
public InstructionBIT() {
this.opcode = Opcode.BIT;
}
}
19 changes: 19 additions & 0 deletions core/src/main/java/org/lflang/analyses/evm/InstructionDU.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package org.lflang.analyses.evm;

import org.lflang.TimeValue;

public class InstructionDU extends Instruction {

/** The physical time point to delay until */
TimeValue releaseTime;

public InstructionDU(TimeValue releaseTime) {
this.opcode = Opcode.DU;
this.releaseTime = releaseTime;
}

@Override
public String toString() {
return "DU: " + releaseTime;
}
}
11 changes: 2 additions & 9 deletions core/src/main/java/org/lflang/analyses/evm/InstructionEIT.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,17 @@

import org.lflang.generator.ReactionInstance;

public class InstructionEIT implements Instruction {

/** Opcode of this instruction */
private final Opcode opcode = Opcode.EIT;
public class InstructionEIT extends Instruction {

/** Reaction to be executed */
public ReactionInstance reaction;

/** Constructor */
public InstructionEIT(ReactionInstance reaction) {
this.opcode = Opcode.EIT;
this.reaction = reaction;
}

@Override
public Opcode getOpcode() {
return this.opcode;
}

@Override
public String toString() {
return opcode + ": " + this.reaction;
Expand Down
11 changes: 2 additions & 9 deletions core/src/main/java/org/lflang/analyses/evm/InstructionEXE.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,17 @@

import org.lflang.generator.ReactionInstance;

public class InstructionEXE implements Instruction {

/** Opcode of this instruction */
private final Opcode opcode = Opcode.EXE;
public class InstructionEXE extends Instruction {

/** Reaction to be executed */
public ReactionInstance reaction;

/** Constructor */
public InstructionEXE(ReactionInstance reaction) {
this.opcode = Opcode.EXE;
this.reaction = reaction;
}

@Override
public Opcode getOpcode() {
return this.opcode;
}

@Override
public String toString() {
return opcode + ": " + this.reaction;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
import java.util.List;
import java.util.Map;
import java.util.Queue;

import org.lflang.TargetConfig;
import org.lflang.analyses.dag.Dag;
import org.lflang.analyses.dag.DagEdge;
import org.lflang.analyses.dag.DagNode;
Expand All @@ -18,16 +20,19 @@ public class InstructionGenerator {
/** A partitioned Dag */
Dag dag;

TargetConfig targetConfig;

/** Number of workers */
int workers;

/** Instructions for all workers */
List<List<Instruction>> instructions;

/** Constructor */
public InstructionGenerator(Dag dagParitioned, int workers) {
public InstructionGenerator(Dag dagParitioned, TargetConfig targetConfig) {
this.dag = dagParitioned;
this.workers = workers;
this.targetConfig = targetConfig;
this.workers = targetConfig.workers;

// Initialize instructions array.
instructions = new ArrayList<>();
Expand All @@ -45,6 +50,13 @@ public void generate() {
// Debug
int count = 0;

// If timeout is specified, add BIT instructions.
if (this.targetConfig.timeout != null) {
for (var schedule : instructions) {
schedule.add(new InstructionBIT());
}
}

// Initialize indegree of all nodes to be the size of their respective upstream node set.
for (DagNode node : dag.dagNodes) {
indegree.put(node, dag.dagEdgesRev.getOrDefault(node, new HashMap<>()).size());
Expand All @@ -63,19 +75,55 @@ public void generate() {
current.setDotDebugMsg("count: " + count++);
System.out.println("Current: " + current);

/* Generate instructions for the current node */
// Get the upstream nodes.
List<DagNode> upstream =
dag.dagEdgesRev.getOrDefault(current, new HashMap<>()).keySet().stream().toList();
System.out.println("Upstream: " + upstream);
List<DagNode> upstreamReactionNodes = dag.dagEdgesRev
.getOrDefault(current, new HashMap<>())
.keySet().stream()
.filter(n -> n.nodeType == dagNodeType.REACTION)
.toList();
System.out.println("Upstream: " + upstreamReactionNodes);

// If the reaction is triggered by a timer,
// generate an EXE instructions.
// FIXME: Handle a reaction triggered by timers and ports.
/* Generate instructions for the current node */
if (current.nodeType == dagNodeType.REACTION) {
ReactionInstance reaction = current.getReaction();

// If the reaction is triggered by a timer,
// generate an EXE instruction.
// FIXME: Handle a reaction triggered by both timers and ports.
if (reaction.triggers.stream().anyMatch(trigger -> trigger instanceof TimerInstance)) {
instructions.get(current.getWorker()).add(new InstructionEXE(reaction));
instructions.get(current.getWorker()).add(new InstructionINC2());
}
// Otherwise, generate an EIT instruction.
else {
// If the reaction depends on upstream reactions owned by other
// workers, generate WU instructions to resolve the dependencies.
for (DagNode n : upstreamReactionNodes) {
int upstreamOwner = n.getWorker();
if (upstreamOwner != current.getWorker()) {
instructions.get(current.getWorker()).add(
new InstructionWU(
upstreamOwner,
n.nodeReaction
));
}
}

instructions.get(current.getWorker()).add(new InstructionEIT(reaction));
instructions.get(current.getWorker()).add(new InstructionINC2());
}
}
else if (current.nodeType == dagNodeType.SYNC) {
if (current != dag.head && current != dag.tail) {
for (DagNode n : upstreamReactionNodes) {
instructions.get(n.getWorker()).add(new InstructionDU(current.timeStep));
}
}
else if (current == dag.tail) {
for (var schedule : instructions) {
schedule.add(new InstructionSAC());
schedule.add(new InstructionDU(current.timeStep));
}
}
}

Expand All @@ -101,6 +149,12 @@ public void generate() {
throw new RuntimeException(
"The graph has at least one cycle, thus cannot be topologically sorted.");
}

// Add JMP and STP instructions.
for (var schedule : instructions) {
schedule.add(new InstructionJMP());
schedule.add(new InstructionSTP());
}
}

public Dag getDag() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package org.lflang.analyses.evm;

public class InstructionINC2 extends Instruction {
public InstructionINC2() {
this.opcode = Opcode.INC2;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package org.lflang.analyses.evm;

public class InstructionJMP extends Instruction {
public InstructionJMP() {
this.opcode = Opcode.JMP;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package org.lflang.analyses.evm;

public class InstructionSAC extends Instruction {
public InstructionSAC() {
this.opcode = Opcode.SAC;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package org.lflang.analyses.evm;

public class InstructionSTP extends Instruction {
public InstructionSTP() {
this.opcode = Opcode.STP;
}
}
23 changes: 23 additions & 0 deletions core/src/main/java/org/lflang/analyses/evm/InstructionWU.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package org.lflang.analyses.evm;

import org.lflang.generator.ReactionInstance;

public class InstructionWU extends Instruction {

/** The reaction this WU instruction waits on */
ReactionInstance reaction;

/** ID of the worker processing the reaction */
int worker;

public InstructionWU(int worker, ReactionInstance reaction) {
this.opcode = Opcode.WU;
this.worker = worker;
this.reaction = reaction;
}

@Override
public String toString() {
return "WU: worker " + worker + " finish " + reaction;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ public StaticScheduler createStaticScheduler(Dag dag) {
/** Generate VM instructions for each DAG partition. */
public void generateInstructionsFromPartitions(Dag dagParitioned) {
InstructionGenerator instGen =
new InstructionGenerator(dagParitioned, this.targetConfig.workers);
new InstructionGenerator(dagParitioned, this.targetConfig);
instGen.generate();
instGen.display();

Expand Down

0 comments on commit 252912e

Please sign in to comment.