updated ROS, MicroROS SLG transformers to support handling of LocalModeCondition
diff --git a/load_generator/plugins/org.eclipse.app4mc.slg.commons.m2t/src/org/eclipse/app4mc/slg/commons/m2t/transformers/sw/RunnableTransformer.java b/load_generator/plugins/org.eclipse.app4mc.slg.commons.m2t/src/org/eclipse/app4mc/slg/commons/m2t/transformers/sw/RunnableTransformer.java
index a52ff89..0d0fa24 100644
--- a/load_generator/plugins/org.eclipse.app4mc.slg.commons.m2t/src/org/eclipse/app4mc/slg/commons/m2t/transformers/sw/RunnableTransformer.java
+++ b/load_generator/plugins/org.eclipse.app4mc.slg.commons.m2t/src/org/eclipse/app4mc/slg/commons/m2t/transformers/sw/RunnableTransformer.java
@@ -25,7 +25,6 @@
import java.util.Map;
import java.util.Properties;
-import org.eclipse.app4mc.amalthea.model.ActivityGraph;
import org.eclipse.app4mc.amalthea.model.ActivityGraphItem;
import org.eclipse.app4mc.amalthea.model.Runnable;
import org.eclipse.app4mc.amalthea.model.StringObject;
@@ -39,8 +38,8 @@
import org.eclipse.app4mc.slg.config.ConfigModel;
import org.eclipse.app4mc.slg.config.util.ConfigModelUtils;
import org.eclipse.app4mc.transformation.TransformationConstants;
-import org.eclipse.app4mc.util.sessionlog.SessionLogger;
import org.eclipse.app4mc.transformation.util.OutputBuffer;
+import org.eclipse.app4mc.util.sessionlog.SessionLogger;
import org.eclipse.emf.ecore.EObject;
import com.google.inject.Inject;
@@ -154,9 +153,9 @@
}
public boolean processCustomProperties(boolean extOverwrite, final List<String> calls,
- final List<String> callsOverwrite, final EObject parentOfActivityGraphItem) {
+ final List<String> callsOverwrite, final EObject elementContainingCustomProperties) {
- for (EObject item : parentOfActivityGraphItem.eContents()) {
+ for (EObject item : elementContainingCustomProperties.eContents()) {
if (item instanceof CustomPropertyImpl) // custom property:
{
diff --git a/load_generator/plugins/org.eclipse.app4mc.slg.ros2/src/org/eclipse/app4mc/slg/microros/transformers/MicroRosRunnableTransformer.java b/load_generator/plugins/org.eclipse.app4mc.slg.ros2/src/org/eclipse/app4mc/slg/microros/transformers/MicroRosRunnableTransformer.java
index 40e52ae..d319ce1 100644
--- a/load_generator/plugins/org.eclipse.app4mc.slg.ros2/src/org/eclipse/app4mc/slg/microros/transformers/MicroRosRunnableTransformer.java
+++ b/load_generator/plugins/org.eclipse.app4mc.slg.ros2/src/org/eclipse/app4mc/slg/microros/transformers/MicroRosRunnableTransformer.java
@@ -17,8 +17,10 @@
import java.util.ArrayList;
import java.util.HashSet;
+import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
+import java.util.Map;
import org.eclipse.app4mc.amalthea.model.ActivityGraphItem;
import org.eclipse.app4mc.amalthea.model.AmaltheaFactory;
@@ -26,11 +28,20 @@
import org.eclipse.app4mc.amalthea.model.Channel;
import org.eclipse.app4mc.amalthea.model.ChannelReceive;
import org.eclipse.app4mc.amalthea.model.ChannelSend;
+import org.eclipse.app4mc.amalthea.model.ConditionDisjunction;
+import org.eclipse.app4mc.amalthea.model.ConditionDisjunctionEntry;
import org.eclipse.app4mc.amalthea.model.DataSize;
+import org.eclipse.app4mc.amalthea.model.ILocalModeValueSource;
import org.eclipse.app4mc.amalthea.model.InterProcessStimulus;
import org.eclipse.app4mc.amalthea.model.InterProcessTrigger;
import org.eclipse.app4mc.amalthea.model.Label;
+import org.eclipse.app4mc.amalthea.model.LocalModeCondition;
+import org.eclipse.app4mc.amalthea.model.LocalModeLabel;
+import org.eclipse.app4mc.amalthea.model.ModeLiteral;
+import org.eclipse.app4mc.amalthea.model.ModeLiteralConst;
import org.eclipse.app4mc.amalthea.model.Runnable;
+import org.eclipse.app4mc.amalthea.model.Switch;
+import org.eclipse.app4mc.amalthea.model.SwitchEntry;
import org.eclipse.app4mc.amalthea.model.Tag;
import org.eclipse.app4mc.slg.commons.m2t.CustomObjectsStore;
import org.eclipse.app4mc.slg.commons.m2t.transformers.SLGTranslationUnit;
@@ -41,6 +52,9 @@
import org.eclipse.app4mc.slg.ros2.transformers.sw.RosRunnableCache;
import org.eclipse.app4mc.slg.ros2.transformers.utils.Utils;
import org.eclipse.app4mc.transformation.util.OutputBuffer;
+import org.eclipse.emf.common.util.BasicEList;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.ecore.EObject;
import com.google.inject.Inject;
@@ -71,6 +85,20 @@
}
@Override
protected void genFiles(SLGTranslationUnit tu, Runnable runnable) {
+
+ customObjsStore.indexData(tu.getCall(), runnable);
+
+ final Map<SwitchEntry,List<String>> switchBasedCalls = new LinkedHashMap<SwitchEntry, List<String>>();
+
+ final Map<SwitchEntry,List<String>> switchBasedCallsOverwrite = new LinkedHashMap<SwitchEntry, List<String>>(); //overwrite codehook fct
+
+ final List<SwitchEntry> switchEntries=new ArrayList<SwitchEntry>();
+
+ final Map<SwitchEntry, Boolean> switchEntryOverwriteActivityGraph=new LinkedHashMap<SwitchEntry, Boolean>();
+
+ final EList<ActivityGraphItem> defaultActivityGraphItems=new BasicEList<ActivityGraphItem>();
+
+
if (isSrcFileEmpty(tu)) { // all stuff only required once regardless of runnable instance
srcAppend(tu, "#include \"" + getIncFile(tu) + "\"\n");
}
@@ -96,104 +124,35 @@
if (runnable != null && runnable.getActivityGraph() != null) {
- for (ActivityGraphItem item : runnable.getActivityGraph().getItems()) {
+ EList<ActivityGraphItem> activityGraphItems = runnable.getActivityGraph().getItems();
- final SLGTranslationUnit graphItemTU = activityGraphItemTransformer.transform(item,tag);
- String graphItemIncFile = getIncFile(graphItemTU);
- if (graphItemIncFile != null && !graphItemIncFile.isEmpty() && !getIncFile(tu).equals(graphItemIncFile)) {
- if (item instanceof ChannelReceive)
- {
- includes.add("labels.h");
- }
- else
- {
- includes.add(graphItemIncFile);
- }
- }
+ for (ActivityGraphItem activityGraphItem : activityGraphItems) {
- // check if item is publisher
+ if(activityGraphItem instanceof Switch) {
- if (item instanceof ChannelSend) {
- ChannelSend cs = (ChannelSend) item;
- Channel data = cs.getData();
-
- publishers.add(tag.getName().toLowerCase()+"Node_"+data.getName().toLowerCase() + "_publisher");
-
- //nodeParams.add("&"+tag.getName().toLowerCase()+"Node_"+data.getName().toLowerCase() + "_publisher");
- //nodeParams.add("&"+tag.getName().toLowerCase()+"Node_"+data.getName().toLowerCase() + "_msg");
- nodeParams.add(tag.getName().toLowerCase()+"Node_"+data.getName().toLowerCase() + "_msg");
-
- // params.add(" rcl_publisher_t * " +tag.getName().toLowerCase()+"Node_"+data.getName().toLowerCase() + "_publisher");
- params.add(" std_msgs__msg__String " +tag.getName().toLowerCase()+"Node_"+data.getName().toLowerCase() + "_msg");
-
-
- //
-
-// localParamNames.add("&"+tag.getName()+"Node_"+data.getName() + "_publisher");
-// localParamNames.add("&"+tag.getName()+"Node_"+data.getName() + "_msg");
-//
-//
-// localParamWithSignature.add(" rcl_publisher_t * " +tag.getName()+"Node_"+data.getName() + "_publisher");
-// localParamWithSignature.add(" std_msgs__msg__String * " +tag.getName()+"Node_"+data.getName() + "_msg");
-//
-
-
+ for(SwitchEntry entry: ((Switch)activityGraphItem).getEntries()) {
+ switchBasedCalls.put(entry, new ArrayList<String>());
+ switchBasedCallsOverwrite.put(entry, new ArrayList<String>());
+ switchEntries.add(entry);
+ }
+ }else {
+ defaultActivityGraphItems.add(activityGraphItem);
}
- if (item instanceof InterProcessTrigger) {
- /*-InterProcessTrigger trigger = (InterProcessTrigger) item;
- InterProcessStimulus stimulus = trigger.getStimulus();
-
- String stimName = stimulus.getName();
- String idlName = Utils.toIdlCompliantName(stimName + "_service");
-
- includes.add(stimName + "_service/srv/" + stimName + "_service" + ".hpp");
- clientDeclarations.add("rclcpp::Client<" + stimName + "_service::srv::" + idlName + ">::SharedPtr " + stimName + "_client");
- clientInits.add(stimName + "_client = this->create_client<" + stimName + "_service::srv::" + idlName + ">" + "(\"" + stimName + "_service\")");
- nodeParams.add(stimName + "_client");
- params.add("rclcpp::Client<" + stimName + "_service::srv::" + idlName + ">::SharedPtr& " + stimName + "_client");*/
- }
-
- if (item instanceof ChannelReceive) {
-
-
- ChannelReceive cr = (ChannelReceive) item;
- Channel data = cr.getData();
- String subLabelName = data.getName()+ "_sub_label";
-
- // check for the second channel receive
- //AmaltheaIndex.getElements(context, name, targetClass)
- // AmaltheaIndex.getElements((@NonNull Notifier) customObjsStore, subLabelName, customObjsStore.getInstance(RosLabelTransformer.class) );
-
-
- Label temp = AmaltheaFactory.eINSTANCE.createLabel();
- temp.setName(subLabelName);
-
- DataSize value = data.getSize();
- System.out.print(temp.getName()+": ");
- System.out.print(value +"\n");
- //temp.setSize(value); // transformation error
-
-
- // with injection
- microrosLabelTransformer.transform(temp);
-
- calls.add("//ChannelReceiveCall"); // temporary
- calls.add("read_"+temp.getName()+"("+value.getNumberBytes()+")");
-
- nodeParams.add("msg");
- params.add(" const std_msgs__msg__String * msg");
- calls.add("printf("+"\"Callback: I heard: %s\\n\""+ ", msg->data.data)");
-
-
- }
-
- final String call = graphItemTU.getCall();
- if (call != null && !call.isEmpty()) {
- calls.add(call);
- }
}
}
+
+
+ extracted(tu, runnable, includes, calls, params, nodeParams, publishers, runnable.getActivityGraph(), defaultActivityGraphItems);
+
+ for(SwitchEntry switchEntry: switchEntries) {
+
+
+ extracted(tu, runnable, includes, switchBasedCalls.get(switchEntry), params, nodeParams, publishers, switchEntry, switchEntry.getItems());
+
+
+
+ }
String nodeParam = String.join(",", nodeParams);
String param = String.join(",", params);
@@ -202,24 +161,139 @@
rosRunnableCache.storeValues(tu, runnable, param, nodeParam, publishers, clientDeclarations, clientInits);
String fullCall = "run_" + runnable.getName() + "(" + param + ")";
+
+ String fullCall_with_context = "run_" + runnable.getName()+"_Context" + "(" + param + ","+getParamNames(runnable.getLocalLabels())+" )";
+
// write header
incAppend(tu, "\n//Runnable " + runnable.getName() + "----\n");
- toH(tu, includes, fullCall);
+ toH(tu, includes, fullCall,fullCall_with_context);
// write body
srcAppend(tu, "\n//Runnable " + runnable.getName() + "----\n");
- toCpp(tu, runnable.getName(), fullCall, calls, measurePerformance);
+ toCpp(tu, runnable.getName(), fullCall, fullCall_with_context,calls, measurePerformance,switchEntries, switchBasedCalls, runnable);
+ }
+ private void extracted(SLGTranslationUnit tu, Runnable runnable, final HashSet<String> includes,
+ final List<String> calls, final List<String> params, final List<String> nodeParams,
+ final List<String> publishers, final EObject elementContainingCustomProps, final EList<ActivityGraphItem> activityGraphItems) {
+
+ for (ActivityGraphItem item : activityGraphItems) {
+
+ final SLGTranslationUnit graphItemTU = activityGraphItemTransformer.transform(item,tag);
+ String graphItemIncFile = getIncFile(graphItemTU);
+ if (graphItemIncFile != null && !graphItemIncFile.isEmpty() && !getIncFile(tu).equals(graphItemIncFile)) {
+ if (item instanceof ChannelReceive)
+ {
+ includes.add("labels.h");
+ }
+ else
+ {
+ includes.add(graphItemIncFile);
+ }
+ }
+
+ // check if item is publisher
+
+ if (item instanceof ChannelSend) {
+ ChannelSend cs = (ChannelSend) item;
+ Channel data = cs.getData();
+
+ publishers.add(tag.getName().toLowerCase()+"Node_"+data.getName().toLowerCase() + "_publisher");
+
+ //nodeParams.add("&"+tag.getName().toLowerCase()+"Node_"+data.getName().toLowerCase() + "_publisher");
+ //nodeParams.add("&"+tag.getName().toLowerCase()+"Node_"+data.getName().toLowerCase() + "_msg");
+ nodeParams.add(tag.getName().toLowerCase()+"Node_"+data.getName().toLowerCase() + "_msg");
+
+ // params.add(" rcl_publisher_t * " +tag.getName().toLowerCase()+"Node_"+data.getName().toLowerCase() + "_publisher");
+ params.add(" std_msgs__msg__String " +tag.getName().toLowerCase()+"Node_"+data.getName().toLowerCase() + "_msg");
+
+
+ //
+
+// localParamNames.add("&"+tag.getName()+"Node_"+data.getName() + "_publisher");
+// localParamNames.add("&"+tag.getName()+"Node_"+data.getName() + "_msg");
+//
+//
+// localParamWithSignature.add(" rcl_publisher_t * " +tag.getName()+"Node_"+data.getName() + "_publisher");
+// localParamWithSignature.add(" std_msgs__msg__String * " +tag.getName()+"Node_"+data.getName() + "_msg");
+//
+
+
+ }
+
+ if (item instanceof InterProcessTrigger) {
+ /*-InterProcessTrigger trigger = (InterProcessTrigger) item;
+ InterProcessStimulus stimulus = trigger.getStimulus();
+
+ String stimName = stimulus.getName();
+ String idlName = Utils.toIdlCompliantName(stimName + "_service");
+
+ includes.add(stimName + "_service/srv/" + stimName + "_service" + ".hpp");
+ clientDeclarations.add("rclcpp::Client<" + stimName + "_service::srv::" + idlName + ">::SharedPtr " + stimName + "_client");
+ clientInits.add(stimName + "_client = this->create_client<" + stimName + "_service::srv::" + idlName + ">" + "(\"" + stimName + "_service\")");
+ nodeParams.add(stimName + "_client");
+ params.add("rclcpp::Client<" + stimName + "_service::srv::" + idlName + ">::SharedPtr& " + stimName + "_client");*/
+ }
+
+ if (item instanceof ChannelReceive) {
+
+
+ ChannelReceive cr = (ChannelReceive) item;
+ Channel data = cr.getData();
+ String subLabelName = data.getName()+ "_sub_label";
+
+ // check for the second channel receive
+ //AmaltheaIndex.getElements(context, name, targetClass)
+ // AmaltheaIndex.getElements((@NonNull Notifier) customObjsStore, subLabelName, customObjsStore.getInstance(RosLabelTransformer.class) );
+
+
+ Label temp = AmaltheaFactory.eINSTANCE.createLabel();
+ temp.setName(subLabelName);
+
+ DataSize value = data.getSize();
+ System.out.print(temp.getName()+": ");
+ System.out.print(value +"\n");
+ //temp.setSize(value); // transformation error
+
+
+ // with injection
+ microrosLabelTransformer.transform(temp);
+
+ calls.add("//ChannelReceiveCall"); // temporary
+ calls.add("read_"+temp.getName()+"("+value.getNumberBytes()+")");
+
+ nodeParams.add("msg");
+ params.add(" const std_msgs__msg__String * msg");
+ calls.add("printf("+"\"Callback: I heard: %s\\n\""+ ", msg->data.data)");
+
+
+ }
+
+ final String call = graphItemTU.getCall();
+ if (call != null && !call.isEmpty()) {
+ calls.add(call);
+ }
+ }
}
- protected void toH(SLGTranslationUnit tu, final HashSet<String> includes, final String fullCall) {
+ protected void toH(SLGTranslationUnit tu, final HashSet<String> includes, final String fullCall, String fullCall_with_context) {
for (String include : includes) {
incAppend(tu, "#include \"" + include + "\"\n");
}
incAppend(tu, "void " + fullCall + ";\n");
+
+ Runnable data = customObjsStore.getData(tu.getCall());
+ EList<LocalModeLabel> localLabels = ((Runnable)data).getLocalLabels();
+
+
+ if(localLabels.size()>0)
+ incAppend(tu, "void " +fullCall_with_context+" ;\n");
+
+
+
}
- protected void toCpp(SLGTranslationUnit tu, final String runnableName, final String fullCall, final List<String> calls, boolean measurePerformance) {
+ protected void toCpp(SLGTranslationUnit tu, final String runnableName, final String fullCall, String fullCall_with_context, final List<String> calls, boolean measurePerformance,List<SwitchEntry> switchEntries, Map<SwitchEntry, List<String>> switchBasedCalls , Runnable runnable) {
srcAppend(tu, "void " + fullCall + "{\n");
if (measurePerformance) {
srcAppend(tu,
@@ -236,6 +310,38 @@
srcAppend(tu, "instrument_stop(fd, \"" + runnableName + ".log\");\n");
}
srcAppend(tu, "}\n\n");
+
+ //Adding additional method
+
+ if(runnable.getLocalLabels().size()>0) {
+
+ srcAppend(tu, "void " + fullCall_with_context + "{\n"+ "\n");
+ if (measurePerformance) {
+ srcAppend(tu,
+ "uint64_t event_list[] = {0x11, 0x13, 0x17}; //CPU CYCLES, MEM ACCESS, L2 Cache Refill\n"
+ + "int total_events = sizeof(event_list)/sizeof(event_list[0]);\n"
+ + "int fd = instrument_start(0,event_list, total_events);\n");
+ }
+
+ for(SwitchEntry switchEntry: switchEntries) {
+
+ {
+ srcAppend(tu, "if("+getConditionString(switchEntry)+"){" + "\n");
+
+ for (String call : switchBasedCalls.get(switchEntry)) {
+ srcAppend(tu, call + ";" + "\n");
+ }
+ srcAppend(tu, "\n" + "}" + "\n");
+ }
+
+ }
+
+ if (measurePerformance) {
+ srcAppend(tu, "instrument_stop(fd, \"" + runnableName + "_context.log\");\n");
+ }
+ srcAppend(tu, "}\n\n");
+ }
+
}
@Override
@@ -250,4 +356,53 @@
return super.transform(runnable);
}
+ private String getParamNames(EList<LocalModeLabel> localLabels) {
+
+ List<String> ls=new ArrayList<String>();
+
+ for (LocalModeLabel localModeLabel : localLabels) {
+ ls.add("char* "+localModeLabel.getName());
+ }
+
+ return String.join(",", ls);
+ }
+
+ private String getConditionString(SwitchEntry switchEntry) {
+
+ ConditionDisjunction condition = switchEntry.getCondition();
+
+ if(condition !=null) {
+
+ EList<ConditionDisjunctionEntry> entries = condition.getEntries();
+
+ for (ConditionDisjunctionEntry conditionDisjunctionEntry : entries) {
+
+ if(conditionDisjunctionEntry instanceof LocalModeCondition) {
+ LocalModeLabel localLabel = ((LocalModeCondition) conditionDisjunctionEntry).getLabel();
+
+ if(localLabel !=null) {
+
+ String localVariableName = localLabel.getName();
+
+
+ ILocalModeValueSource valueSource = ((LocalModeCondition) conditionDisjunctionEntry).getValueSource();
+
+ if(valueSource !=null && valueSource instanceof ModeLiteralConst) {
+ ModeLiteral value = ((ModeLiteralConst)valueSource).getValue();
+
+ String caseName= value.getName();
+
+ return "strcmp("+localVariableName+",\""+caseName+"\")==0";
+ }
+ }
+ }
+ }
+ }
+
+
+
+ return "false";
+ }
}
+
+
diff --git a/load_generator/plugins/org.eclipse.app4mc.slg.ros2/src/org/eclipse/app4mc/slg/microros/transformers/MicroRosTaskTransformer.java b/load_generator/plugins/org.eclipse.app4mc.slg.ros2/src/org/eclipse/app4mc/slg/microros/transformers/MicroRosTaskTransformer.java
index c943f19..e730e21 100644
--- a/load_generator/plugins/org.eclipse.app4mc.slg.ros2/src/org/eclipse/app4mc/slg/microros/transformers/MicroRosTaskTransformer.java
+++ b/load_generator/plugins/org.eclipse.app4mc.slg.ros2/src/org/eclipse/app4mc/slg/microros/transformers/MicroRosTaskTransformer.java
@@ -94,10 +94,10 @@
includes.add(getIncFile(runnableTU));
if (hasTagNamed(runnableCall, "initialize")) {
- initCalls.add(runnableStore.getNodeCall());
+ initCalls.add(runnableStore.getNodeCall(runnableCall));
} else {
- stepCalls.add(runnableStore.getNodeCall());
- System.out.println("\n Stepcall: " + runnableStore.getNodeCall()+ "\n");
+ stepCalls.add(runnableStore.getNodeCall(runnableCall));
+ System.out.println("\n Stepcall: " + runnableStore.getNodeCall(runnableCall)+ "\n");
}
// TODO: Make set
@@ -119,9 +119,9 @@
includes.add(getIncFile(runnableTU));
if (hasTagNamed(runnableCall, "initialize")) {
- initCalls.add(runnableStore.getNodeCall());
+ initCalls.add(runnableStore.getNodeCall(runnableCall));
} else {
- stepCalls.add(runnableStore.getNodeCall());
+ stepCalls.add(runnableStore.getNodeCall(runnableCall));
}
// TODO: add terminate function, if requested
}
diff --git a/load_generator/plugins/org.eclipse.app4mc.slg.ros2/src/org/eclipse/app4mc/slg/ros2/transformers/sw/RosRunnableCache.java b/load_generator/plugins/org.eclipse.app4mc.slg.ros2/src/org/eclipse/app4mc/slg/ros2/transformers/sw/RosRunnableCache.java
index 802eb44..bcc2351 100644
--- a/load_generator/plugins/org.eclipse.app4mc.slg.ros2/src/org/eclipse/app4mc/slg/ros2/transformers/sw/RosRunnableCache.java
+++ b/load_generator/plugins/org.eclipse.app4mc.slg.ros2/src/org/eclipse/app4mc/slg/ros2/transformers/sw/RosRunnableCache.java
@@ -15,12 +15,19 @@
package org.eclipse.app4mc.slg.ros2.transformers.sw;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
+import org.eclipse.app4mc.amalthea.model.ILocalModeValueSource;
+import org.eclipse.app4mc.amalthea.model.LocalModeLabelAssignment;
+import org.eclipse.app4mc.amalthea.model.ModeLiteralConst;
import org.eclipse.app4mc.amalthea.model.Runnable;
+import org.eclipse.app4mc.amalthea.model.RunnableCall;
import org.eclipse.app4mc.slg.commons.m2t.transformers.SLGTranslationUnit;
+import org.eclipse.emf.common.util.EList;
import com.google.inject.Singleton;
@@ -81,13 +88,56 @@
return clientInits;
}
- public String getCall() {
+ public String getCall1() {
return "run_" + runnable.getName() + "(" + param + ")";
}
- public String getNodeCall() {
+ public String getNodeCall1() {
return "run_" + runnable.getName() + "(" + nodeParam + ")";
}
+
+ public String getCall(RunnableCall runnableCall) {
+ List<String> contextParameters = getContextParameters(runnableCall);
+ if(contextParameters.size()>0) {
+ return "run_" + runnable.getName() +"_Context"+ "(" + param + "\","+String.join(",", contextParameters)+");";
+ }else {
+ return "run_" + runnable.getName() + "(" + param + ")";
+
+ }
+ }
+
+ public String getNodeCall(RunnableCall runnableCall) {
+ List<String> contextParameters = getContextParameters(runnableCall);
+
+ if(contextParameters.size()>0) {
+ return "run_" + runnable.getName() +"_Context"+ "(" + nodeParam + "\","+String.join(",", contextParameters)+");";
+ }else {
+ return "run_" + runnable.getName() + "(" + nodeParam + ")";
+ }
+ }
+
+
+ private List<String> getContextParameters(RunnableCall item){
+
+ final Runnable runnable = ((RunnableCall) item).getRunnable();
+ List<String> contextParameters=new ArrayList<String>();
+ if ((runnable != null)) {
+
+
+ EList<LocalModeLabelAssignment> context = ((RunnableCall)item).getContext();
+
+ for (LocalModeLabelAssignment localModeLabelAssignment : context) {
+
+ ILocalModeValueSource valueSource = localModeLabelAssignment.getValueSource();
+
+ if(valueSource !=null && valueSource instanceof ModeLiteralConst) {
+
+ contextParameters.add("\""+((ModeLiteralConst)valueSource).getValue().getName()+"\"");
+ }
+ }
+ }
+ return contextParameters;
+ }
}
}
diff --git a/load_generator/plugins/org.eclipse.app4mc.slg.ros2/src/org/eclipse/app4mc/slg/ros2/transformers/sw/RosRunnableTransformer.java b/load_generator/plugins/org.eclipse.app4mc.slg.ros2/src/org/eclipse/app4mc/slg/ros2/transformers/sw/RosRunnableTransformer.java
index f7604b2..542f011 100644
--- a/load_generator/plugins/org.eclipse.app4mc.slg.ros2/src/org/eclipse/app4mc/slg/ros2/transformers/sw/RosRunnableTransformer.java
+++ b/load_generator/plugins/org.eclipse.app4mc.slg.ros2/src/org/eclipse/app4mc/slg/ros2/transformers/sw/RosRunnableTransformer.java
@@ -18,8 +18,10 @@
import java.io.File;
import java.util.ArrayList;
import java.util.HashSet;
+import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
+import java.util.Map;
import java.util.Properties;
import org.eclipse.app4mc.amalthea.model.ActivityGraph;
@@ -31,11 +33,20 @@
import org.eclipse.app4mc.amalthea.model.Channel;
import org.eclipse.app4mc.amalthea.model.ChannelReceive;
import org.eclipse.app4mc.amalthea.model.ChannelSend;
+import org.eclipse.app4mc.amalthea.model.ConditionDisjunction;
+import org.eclipse.app4mc.amalthea.model.ConditionDisjunctionEntry;
import org.eclipse.app4mc.amalthea.model.DataSize;
+import org.eclipse.app4mc.amalthea.model.ILocalModeValueSource;
import org.eclipse.app4mc.amalthea.model.InterProcessStimulus;
import org.eclipse.app4mc.amalthea.model.InterProcessTrigger;
import org.eclipse.app4mc.amalthea.model.Label;
+import org.eclipse.app4mc.amalthea.model.LocalModeCondition;
+import org.eclipse.app4mc.amalthea.model.LocalModeLabel;
+import org.eclipse.app4mc.amalthea.model.ModeLiteral;
+import org.eclipse.app4mc.amalthea.model.ModeLiteralConst;
import org.eclipse.app4mc.amalthea.model.Runnable;
+import org.eclipse.app4mc.amalthea.model.Switch;
+import org.eclipse.app4mc.amalthea.model.SwitchEntry;
import org.eclipse.app4mc.amalthea.model.Value;
import org.eclipse.app4mc.amalthea.model.emf.AmaltheaEObjectImpl;
import org.eclipse.app4mc.slg.commons.m2t.CustomObjectsStore;
@@ -51,6 +62,7 @@
import org.eclipse.app4mc.transformation.TransformationConstants;
import org.eclipse.app4mc.transformation.util.OutputBuffer;
import org.eclipse.app4mc.util.sessionlog.SessionLogger;
+import org.eclipse.emf.common.util.BasicEList;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
@@ -83,10 +95,24 @@
srcAppend(tu, "#include \"" + getIncFile(tu) + "\"\n");
}
+ customObjsStore.indexData(tu.getCall(), runnable);
+
+
boolean extOverwrite = false; // enabling codehook overwriting
final List<String> callsOverwrite = new ArrayList<>(); //overwrite codehook fct
final HashSet<String> includes = new LinkedHashSet<>();
final List<String> calls = new ArrayList<>();
+
+ final Map<SwitchEntry,List<String>> switchBasedCalls = new LinkedHashMap<SwitchEntry, List<String>>();
+
+ final Map<SwitchEntry,List<String>> switchBasedCallsOverwrite = new LinkedHashMap<SwitchEntry, List<String>>(); //overwrite codehook fct
+
+ final List<SwitchEntry> switchEntries=new ArrayList<SwitchEntry>();
+
+ final Map<SwitchEntry, Boolean> switchEntryOverwriteActivityGraph=new LinkedHashMap<SwitchEntry, Boolean>();
+
+ final EList<ActivityGraphItem> defaultActivityGraphItems=new BasicEList<ActivityGraphItem>();
+
boolean measurePerformance = false;
if (runnable != null && runnable.getCustomProperties().get("measure_performance") instanceof BooleanObject) {
@@ -113,96 +139,58 @@
}
}
}
- //------------------------------------------------------------------------
+ //------------------------------------------------------------------------+
+
// Compute characteristic values of runnable
- final List<String> params = new ArrayList<>();
- final List<String> nodeParams = new ArrayList<>();
- final List<String> publishers = new ArrayList<>();
- final List<String> clientDeclarations = new ArrayList<>();
- final List<String> clientInits = new ArrayList<>();
-
- extOverwrite = processCustomProperties(extOverwrite, calls, callsOverwrite, runnable.getActivityGraph()); // for codehooks implementation
- if (runnable != null && runnable.getActivityGraph() != null) {
- for (ActivityGraphItem item : runnable.getActivityGraph().getItems()) {
-
- final SLGTranslationUnit graphItemTU = activityGraphItemTransformer.transform(item);
- String graphItemIncFile = getIncFile(graphItemTU);
- if (graphItemIncFile != null && !graphItemIncFile.isEmpty() && !getIncFile(tu).equals(graphItemIncFile)) { //includes problem is in here. It should be if .. is empty.
-
-
- if (!(item instanceof ChannelReceive)) // temporary
- {
- includes.add(graphItemIncFile);
- System.out.println(graphItemIncFile);
- }
- }
-
- // check if item is publisher
-
- if (item instanceof ChannelSend) {
- ChannelSend cs = (ChannelSend) item;
- Channel data = cs.getData();
-
- publishers.add(data.getName() + "_publisher");
- nodeParams.add(data.getName() + "_publisher");
- params.add("rclcpp::Publisher<std_msgs::msg::String>::SharedPtr& " + data.getName() + "_publisher");
-
- }
-
- if (item instanceof InterProcessTrigger) {
- InterProcessTrigger trigger = (InterProcessTrigger) item;
- InterProcessStimulus stimulus = trigger.getStimulus();
-
- String stimName = stimulus.getName();
- String idlName = Utils.toIdlCompliantName(stimName + "_service");
-
- includes.add(stimName + "_service/srv/" + stimName + "_service" + ".hpp");
- clientDeclarations.add("rclcpp::Client<" + stimName + "_service::srv::" + idlName + ">::SharedPtr " + stimName + "_client");
- clientInits.add(stimName + "_client = this->create_client<" + stimName + "_service::srv::" + idlName + ">" + "(\"" + stimName + "_service\")");
- nodeParams.add(stimName + "_client");
- params.add("rclcpp::Client<" + stimName + "_service::srv::" + idlName + ">::SharedPtr& " + stimName + "_client");
- }
-
- // check if item is subscriber.
- if (item instanceof ChannelReceive) {
-
-
- ChannelReceive cr = (ChannelReceive) item;
- Channel data = cr.getData();
- String subLabelName = data.getName()+ "_sub_label";
-
- // check for the second channel receive
- //AmaltheaIndex.getElements(context, name, targetClass)
- // AmaltheaIndex.getElements((@NonNull Notifier) customObjsStore, subLabelName, customObjsStore.getInstance(RosLabelTransformer.class) );
-
-
- Label temp = AmaltheaFactory.eINSTANCE.createLabel();
- temp.setName(subLabelName);
-
- DataSize value = data.getSize();
- System.out.print(temp.getName()+": ");
- System.out.print(value +"\n");
- //temp.setSize(value); // transformation error
- //Without injection:
- //LabelTransformer labelTransformer = new LabelTransformer();
-
- // with injection
- rosLabelTransformer.transform(temp);
-
- calls.add("//ChannelReceiveTry"); // temporary
- calls.add("read_"+temp.getName()+"("+value.getNumberBytes()+")");
-
-
- }
-
+ final List<String> params = new ArrayList<>();
+ final List<String> nodeParams = new ArrayList<>();
+ final List<String> publishers = new ArrayList<>();
+ final List<String> clientDeclarations = new ArrayList<>();
+ final List<String> clientInits = new ArrayList<>();
- final String call = graphItemTU.getCall();
- if (call != null && !call.isEmpty()) {
- calls.add(call);
+
+ if (runnable != null && runnable.getActivityGraph() != null) {
+
+ EList<ActivityGraphItem> activityGraphItems = runnable.getActivityGraph().getItems();
+
+ for (ActivityGraphItem activityGraphItem : activityGraphItems) {
+
+ if(activityGraphItem instanceof Switch) {
+
+ for(SwitchEntry entry: ((Switch)activityGraphItem).getEntries()) {
+ switchBasedCalls.put(entry, new ArrayList<String>());
+ switchBasedCallsOverwrite.put(entry, new ArrayList<String>());
+ switchEntries.add(entry);
+ }
+ }else {
+ defaultActivityGraphItems.add(activityGraphItem);
}
+
}
+
+ extOverwrite = extracted(tu, extOverwrite, callsOverwrite, includes, calls, params, nodeParams,
+ publishers, clientDeclarations, clientInits, runnable.getActivityGraph(), defaultActivityGraphItems);
+
+
+ for(SwitchEntry switchEntry: switchEntries) {
+
+ Boolean extOverwriteActivityGraph_switch = extracted(tu, extOverwrite, switchBasedCallsOverwrite.get(switchEntry), includes, switchBasedCalls.get(switchEntry), params, nodeParams,
+ publishers, clientDeclarations, clientInits, switchEntry, switchEntry.getItems());
+
+ switchEntryOverwriteActivityGraph.put(switchEntry, extOverwriteActivityGraph_switch);
+
+ }
+
+
}
+
+
+
+ //
+
+
+
String nodeParam = String.join(",", nodeParams);
String param = String.join(",", params);
@@ -212,10 +200,14 @@
String fullCall = "run_" + runnable.getName() + "(" + param + ")";
+ String fullCall_with_context = "run_" + runnable.getName()+"_Context" + "(" + param + ","+getParamNames(runnable.getLocalLabels())+" )";
+
// write header
incAppend(tu, "\n//Runnable " + runnable.getName() + "----\n");
- toH(tu, includes, fullCall);
+ toH(tu, includes, fullCall,param);
+
+
//------------------------ write body with overwrite codehook function
@@ -228,18 +220,170 @@
srcAppend(tu, call + ";" + "\n");
}
srcAppend(tu, "\n" + "}" + "\n");
+
+ if(runnable.getLocalLabels().size()>0) {
+
+ //additional method for switch
+ srcAppend(tu, "void " + call_overwrite+"_Context"+ "("+ param+ ","+getParamNames(runnable.getLocalLabels())+" ){\n" + "\n");
+
+ for(SwitchEntry switchEntry: switchEntries) {
+
+ if(switchEntryOverwriteActivityGraph.get(switchEntry)) {
+
+ srcAppend(tu, getConditionString(switchEntry) + "\n");
+
+ for (String call : switchBasedCallsOverwrite.get(switchEntry)) {
+ srcAppend(tu, call + ";" + "\n");
+ }
+
+ }else {
+ for (String call : switchBasedCalls.get(switchEntry)) {
+ srcAppend(tu, call + ";" + "\n");
+ }
+ }
+
+ }
+ srcAppend(tu, "\n" + "}" + "\n");
+ }
+
}
// ------------------------
else {
// write body
srcAppend(tu, "\n//Runnable " + runnable.getName() + "----\n");
- toCpp(tu, runnable.getName(), fullCall, calls, measurePerformance);
+ toCustomCpp(tu, runnable.getName(), fullCall, fullCall_with_context,calls, measurePerformance,switchEntries,switchBasedCalls,runnable);
}
}
+
+ private String getConditionString(SwitchEntry switchEntry) {
+
+ ConditionDisjunction condition = switchEntry.getCondition();
+
+ if(condition !=null) {
+
+ EList<ConditionDisjunctionEntry> entries = condition.getEntries();
+
+ for (ConditionDisjunctionEntry conditionDisjunctionEntry : entries) {
+
+ if(conditionDisjunctionEntry instanceof LocalModeCondition) {
+ LocalModeLabel localLabel = ((LocalModeCondition) conditionDisjunctionEntry).getLabel();
+
+ if(localLabel !=null) {
+
+ String localVariableName = localLabel.getName();
+
+
+ ILocalModeValueSource valueSource = ((LocalModeCondition) conditionDisjunctionEntry).getValueSource();
+
+ if(valueSource !=null && valueSource instanceof ModeLiteralConst) {
+ ModeLiteral value = ((ModeLiteralConst)valueSource).getValue();
+
+ String caseName= value.getName();
+
+ return "strcmp("+localVariableName+",\""+caseName+"\")==0";
+ }
+ }
+ }
+ }
+ }
+
+
+
+ return "false";
+ }
- protected void toH(SLGTranslationUnit tu, final HashSet<String> includes, final String fullCall) {
+ private boolean extracted(SLGTranslationUnit tu, boolean extOverwrite,
+ final List<String> callsOverwrite, final HashSet<String> includes, final List<String> calls,
+ final List<String> params, final List<String> nodeParams, final List<String> publishers,
+ final List<String> clientDeclarations, final List<String> clientInits, final EObject elementContainingCustomProps, final EList<ActivityGraphItem> activityGraphItems ) {
+
+ extOverwrite = processCustomProperties(extOverwrite, calls, callsOverwrite,elementContainingCustomProps); // for codehooks implementation
+
+ for (ActivityGraphItem item : activityGraphItems) {
+
+ final SLGTranslationUnit graphItemTU = activityGraphItemTransformer.transform(item);
+ String graphItemIncFile = getIncFile(graphItemTU);
+ if (graphItemIncFile != null && !graphItemIncFile.isEmpty() && !getIncFile(tu).equals(graphItemIncFile)) { //includes problem is in here. It should be if .. is empty.
+
+
+ if (!(item instanceof ChannelReceive)) // temporary
+ {
+ includes.add(graphItemIncFile);
+ System.out.println(graphItemIncFile);
+ }
+ }
+
+ // check if item is publisher
+
+ if (item instanceof ChannelSend) {
+ ChannelSend cs = (ChannelSend) item;
+ Channel data = cs.getData();
+
+ publishers.add(data.getName() + "_publisher");
+ nodeParams.add(data.getName() + "_publisher");
+ params.add("rclcpp::Publisher<std_msgs::msg::String>::SharedPtr& " + data.getName() + "_publisher");
+
+ }
+
+ if (item instanceof InterProcessTrigger) {
+ InterProcessTrigger trigger = (InterProcessTrigger) item;
+ InterProcessStimulus stimulus = trigger.getStimulus();
+
+ String stimName = stimulus.getName();
+ String idlName = Utils.toIdlCompliantName(stimName + "_service");
+
+ includes.add(stimName + "_service/srv/" + stimName + "_service" + ".hpp");
+ clientDeclarations.add("rclcpp::Client<" + stimName + "_service::srv::" + idlName + ">::SharedPtr " + stimName + "_client");
+ clientInits.add(stimName + "_client = this->create_client<" + stimName + "_service::srv::" + idlName + ">" + "(\"" + stimName + "_service\")");
+ nodeParams.add(stimName + "_client");
+ params.add("rclcpp::Client<" + stimName + "_service::srv::" + idlName + ">::SharedPtr& " + stimName + "_client");
+ }
+
+ // check if item is subscriber.
+ if (item instanceof ChannelReceive) {
+
+
+ ChannelReceive cr = (ChannelReceive) item;
+ Channel data = cr.getData();
+ String subLabelName = data.getName()+ "_sub_label";
+
+ // check for the second channel receive
+ //AmaltheaIndex.getElements(context, name, targetClass)
+ // AmaltheaIndex.getElements((@NonNull Notifier) customObjsStore, subLabelName, customObjsStore.getInstance(RosLabelTransformer.class) );
+
+
+ Label temp = AmaltheaFactory.eINSTANCE.createLabel();
+ temp.setName(subLabelName);
+
+ DataSize value = data.getSize();
+ System.out.print(temp.getName()+": ");
+ System.out.print(value +"\n");
+ //temp.setSize(value); // transformation error
+ //Without injection:
+ //LabelTransformer labelTransformer = new LabelTransformer();
+
+ // with injection
+ rosLabelTransformer.transform(temp);
+
+ calls.add("//ChannelReceiveTry"); // temporary
+ calls.add("read_"+temp.getName()+"("+value.getNumberBytes()+")");
+
+
+ }
+
+
+ final String call = graphItemTU.getCall();
+ if (call != null && !call.isEmpty()) {
+ calls.add(call);
+ }
+ }
+
+ return extOverwrite;
+ }
+
+ protected void toH(SLGTranslationUnit tu, final HashSet<String> includes, final String fullCall, String param) {
for (String include : includes) {
incAppend(tu, "#include \"" + include + "\"\n");
}
@@ -248,6 +392,24 @@
incAppend(tu, "#include \"labels.h\"\n");
}
incAppend(tu, "void " + fullCall + ";\n");
+
+ Runnable data = customObjsStore.getData(tu.getCall());
+ EList<LocalModeLabel> localLabels = ((Runnable)data).getLocalLabels();
+
+
+ if(localLabels.size()>0)
+ incAppend(tu, "void " + "run_" + data.getName() +"_Context" + "("+param+","+getParamNames(localLabels)+" );\n");
+ }
+
+ private String getParamNames(EList<LocalModeLabel> localLabels) {
+
+ List<String> ls=new ArrayList<String>();
+
+ for (LocalModeLabel localModeLabel : localLabels) {
+ ls.add("char* "+localModeLabel.getName());
+ }
+
+ return String.join(",", ls);
}
protected void toCpp(SLGTranslationUnit tu, final String runnableName, final String fullCall, final List<String> calls, boolean measurePerformance) {
@@ -268,6 +430,65 @@
}
srcAppend(tu, "}\n\n");
}
+
+
+ protected void toCustomCpp(SLGTranslationUnit tu, final String runnableName, final String fullCall, final String fullCall_with_context, final List<String> calls, boolean measurePerformance, List<SwitchEntry> switchEntries, Map<SwitchEntry, List<String>> switchBasedCalls, Runnable runnable) {
+ srcAppend(tu, "void " + fullCall + "{\n");
+ if (measurePerformance) {
+ srcAppend(tu,
+ "uint64_t event_list[] = {0x11, 0x13, 0x17}; //CPU CYCLES, MEM ACCESS, L2 Cache Refill\n"
+ + "int total_events = sizeof(event_list)/sizeof(event_list[0]);\n"
+ + "int fd = instrument_start(0,event_list, total_events);\n");
+ }
+
+ for (String call : calls) {
+ srcAppend(tu, "\t" + call + ";\n");
+ }
+
+ if (measurePerformance) {
+ srcAppend(tu, "instrument_stop(fd, \"" + runnableName + ".log\");\n");
+ }
+ srcAppend(tu, "}\n\n");
+
+
+ //Adding additional method
+
+ if(runnable.getLocalLabels().size()>0) {
+
+ srcAppend(tu, "void " + fullCall_with_context + "{\n"+ "\n");
+ if (measurePerformance) {
+ srcAppend(tu,
+ "uint64_t event_list[] = {0x11, 0x13, 0x17}; //CPU CYCLES, MEM ACCESS, L2 Cache Refill\n"
+ + "int total_events = sizeof(event_list)/sizeof(event_list[0]);\n"
+ + "int fd = instrument_start(0,event_list, total_events);\n");
+ }
+
+ for(SwitchEntry switchEntry: switchEntries) {
+
+ {
+ srcAppend(tu, "if("+getConditionString(switchEntry)+"){" + "\n");
+
+ for (String call : switchBasedCalls.get(switchEntry)) {
+ srcAppend(tu, call + ";" + "\n");
+ }
+ srcAppend(tu, "\n" + "}" + "\n");
+ }
+
+ }
+
+ if (measurePerformance) {
+ srcAppend(tu, "instrument_stop(fd, \"" + runnableName + "_context.log\");\n");
+ }
+ srcAppend(tu, "}\n\n");
+ }
+
+
+
+
+
+ }
+
+
@Override
public boolean createCMake() {
diff --git a/load_generator/plugins/org.eclipse.app4mc.slg.ros2/src/org/eclipse/app4mc/slg/ros2/transformers/sw/RosTaskTransformer.java b/load_generator/plugins/org.eclipse.app4mc.slg.ros2/src/org/eclipse/app4mc/slg/ros2/transformers/sw/RosTaskTransformer.java
index d8ac16d..d924f01 100644
--- a/load_generator/plugins/org.eclipse.app4mc.slg.ros2/src/org/eclipse/app4mc/slg/ros2/transformers/sw/RosTaskTransformer.java
+++ b/load_generator/plugins/org.eclipse.app4mc.slg.ros2/src/org/eclipse/app4mc/slg/ros2/transformers/sw/RosTaskTransformer.java
@@ -78,14 +78,14 @@
includes.add(getIncFile(runnableTU));
if (hasTagNamed(runnableCall, "initialize")) {
- initCalls.add(runnableStore.getNodeCall());
+ initCalls.add(runnableStore.getNodeCall(runnableCall));
} else {
if (extOverwrite)
{
stepCalls.addAll(callsOverwrite);
}
else {
- stepCalls.add(runnableStore.getNodeCall());
+ stepCalls.add(runnableStore.getNodeCall(runnableCall));
}
}
@@ -108,9 +108,9 @@
includes.add(getIncFile(runnableTU));
if (hasTagNamed(runnableCall, "initialize")) {
- initCalls.add(runnableStore.getNodeCall());
+ initCalls.add(runnableStore.getNodeCall(runnableCall));
} else {
- stepCalls.add(runnableStore.getNodeCall());
+ stepCalls.add(runnableStore.getNodeCall(runnableCall));
}
// TODO: add terminate function, if requested
}
diff --git a/load_generator/releng/org.eclipse.app4mc.slg.ros2.product/input/localmodecondition/localmodecondition_pingpong.amxmi b/load_generator/releng/org.eclipse.app4mc.slg.ros2.product/input/localmodecondition/localmodecondition_pingpong.amxmi
new file mode 100644
index 0000000..e81d58c
--- /dev/null
+++ b/load_generator/releng/org.eclipse.app4mc.slg.ros2.product/input/localmodecondition/localmodecondition_pingpong.amxmi
@@ -0,0 +1,112 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<am:Amalthea xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:am="http://app4mc.eclipse.org/amalthea/2.1.0">
+ <commonElements>
+ <tags xmi:id="Ping?type=Tag" name="Ping" tagType="ROS">
+ <customProperties key="executor_type">
+ <value xsi:type="am:StringObject" value="single_thread"/>
+ </customProperties>
+ </tags>
+ <tags xmi:id="Pong?type=Tag" name="Pong" tagType="MicroROS"/>
+ </commonElements>
+ <swModel>
+ <tasks xmi:id="initalPing?type=Task" name="initalPing" tags="Ping?type=Tag" stimuli="timer_50_ms?type=PeriodicStimulus" multipleTaskActivationLimit="0">
+ <activityGraph>
+ <items xsi:type="am:RunnableCall" runnable="initialPing?type=Runnable">
+ <context label="initialPing/localContextA?type=LocalModeLabel">
+ <valueSource xsi:type="am:ModeLiteralConst" value="Variants/cuda?type=ModeLiteral"/>
+ </context>
+ </items>
+ </activityGraph>
+ </tasks>
+ <tasks xmi:id="pingCallback?type=Task" name="pingCallback" tags="Pong?type=Tag" stimuli="ping?type=EventStimulus" multipleTaskActivationLimit="0">
+ <activityGraph>
+ <items xsi:type="am:RunnableCall" runnable="pingCallback?type=Runnable">
+ <context label="initialPing/localContextA?type=LocalModeLabel">
+ <valueSource xsi:type="am:ModeLiteralConst" value="Variants/cuda?type=ModeLiteral"/>
+ </context>
+ </items>
+ </activityGraph>
+ </tasks>
+ <tasks xmi:id="pongCallback?type=Task" name="pongCallback" tags="Ping?type=Tag" stimuli="pong?type=EventStimulus" multipleTaskActivationLimit="0">
+ <activityGraph>
+ <items xsi:type="am:RunnableCall" runnable="pongCallback?type=Runnable">
+ <context label="initialPing/localContextA?type=LocalModeLabel">
+ <valueSource xsi:type="am:ModeLiteralConst" value="Variants/cuda?type=ModeLiteral"/>
+ </context>
+ </items>
+ </activityGraph>
+ </tasks>
+ <runnables xmi:id="initialPing?type=Runnable" name="initialPing" callback="false" service="false">
+ <localLabels xmi:id="initialPing/localContextA?type=LocalModeLabel" name="localContextA" mode="Variants?type=EnumMode" defaultValue="cpu"/>
+ <activityGraph>
+ <items xsi:type="am:Switch">
+ <entries name="">
+ <items xsi:type="am:ChannelSend" data="ping?type=Channel" elements="1"/>
+ <condition>
+ <entries xsi:type="am:LocalModeCondition" label="initialPing/localContextA?type=LocalModeLabel" relation="EQUAL">
+ <valueSource xsi:type="am:ModeLiteralConst" value="Variants/cuda?type=ModeLiteral"/>
+ </entries>
+ </condition>
+ </entries>
+ </items>
+ </activityGraph>
+ </runnables>
+ <runnables xmi:id="pingCallback?type=Runnable" name="pingCallback" callback="false" service="false">
+ <localLabels xmi:id="pingCallback/localContextA?type=LocalModeLabel" name="localContextA" mode="Variants?type=EnumMode" defaultValue="cpu"/>
+ <activityGraph>
+ <items xsi:type="am:Ticks">
+ <default xsi:type="am:DiscreteValueConstant" value="80000000"/>
+ </items>
+ <items xsi:type="am:ChannelSend" data="pong?type=Channel" elements="1"/>
+ <items xsi:type="am:ChannelReceive" data="ping?type=Channel" elements="0" dataMustBeNew="false" elementIndex="0" lowerBound="0"/>
+ </activityGraph>
+ </runnables>
+ <runnables xmi:id="pongCallback?type=Runnable" name="pongCallback" callback="false" service="false">
+ <localLabels xmi:id="pongCallback/localContextA?type=LocalModeLabel" name="localContextA" mode="Variants?type=EnumMode" defaultValue="cpu"/>
+ <activityGraph>
+ <items xsi:type="am:Ticks">
+ <default xsi:type="am:DiscreteValueConstant" value="80000000"/>
+ </items>
+ <items xsi:type="am:LabelAccess" data="label?type=Label" access="read"/>
+ <items xsi:type="am:ChannelReceive" data="pong?type=Channel" elements="0" dataMustBeNew="false" elementIndex="0" lowerBound="0"/>
+ </activityGraph>
+ </runnables>
+ <runnables xmi:id="serviceCallback?type=Runnable" name="serviceCallback" callback="false" service="false">
+ <localLabels xmi:id="serviceCallback/localContextA?type=LocalModeLabel" name="localContextA" mode="Variants?type=EnumMode" defaultValue="cpu"/>
+ <activityGraph>
+ <items xsi:type="am:Ticks">
+ <default xsi:type="am:DiscreteValueConstant" value="800000"/>
+ </items>
+ </activityGraph>
+ </runnables>
+ <labels xmi:id="label?type=Label" name="label" constant="false" bVolatile="false">
+ <size value="8" unit="bit"/>
+ </labels>
+ <channels xmi:id="ping?type=Channel" name="ping" defaultElements="0" maxElements="0">
+ <size value="90" unit="B"/>
+ </channels>
+ <channels xmi:id="pong?type=Channel" name="pong" defaultElements="0" maxElements="0">
+ <size value="100" unit="B"/>
+ </channels>
+ <typeDefinitions xsi:type="am:DataTypeDefinition" xmi:id="int64?type=DataTypeDefinition" name="int64">
+ <size value="64" unit="bit"/>
+ </typeDefinitions>
+ <modes xsi:type="am:EnumMode" xmi:id="Variants?type=EnumMode" name="Variants">
+ <literals xmi:id="Variants/cuda?type=ModeLiteral" name="cuda"/>
+ <literals xmi:id="Variants/openmp?type=ModeLiteral" name="openmp"/>
+ <literals xmi:id="Variants/cpu?type=ModeLiteral" name="cpu"/>
+ </modes>
+ </swModel>
+ <stimuliModel>
+ <stimuli xsi:type="am:PeriodicStimulus" xmi:id="timer_50_ms?type=PeriodicStimulus" name="timer_50_ms">
+ <recurrence value="50" unit="ms"/>
+ </stimuli>
+ <stimuli xsi:type="am:EventStimulus" xmi:id="ping?type=EventStimulus" name="ping" triggeringEvents="Ping_Event?type=ChannelEvent"/>
+ <stimuli xsi:type="am:EventStimulus" xmi:id="pong?type=EventStimulus" name="pong" triggeringEvents="Pong_Event?type=ChannelEvent"/>
+ <stimuli xsi:type="am:InterProcessStimulus" xmi:id="ips?type=InterProcessStimulus" name="ips"/>
+ </stimuliModel>
+ <eventModel>
+ <events xsi:type="am:ChannelEvent" xmi:id="Ping_Event?type=ChannelEvent" name="Ping_Event" entity="ping?type=Channel"/>
+ <events xsi:type="am:ChannelEvent" xmi:id="Pong_Event?type=ChannelEvent" name="Pong_Event" entity="pong?type=Channel"/>
+ </eventModel>
+</am:Amalthea>