Browse Source

Fixed PM enactment code from set to list (for double enactment of e.g., join)

Yentl Van Tendeloo 6 years ago
parent
commit
0e48e93215

+ 21 - 9
bootstrap/core_algorithm.alc

@@ -838,6 +838,8 @@ Boolean function enact_action(pm : Element, element : String, mapping : Element)
 
 	result = execute_operation(transformation_id, inputs, input_traceability_model)
 
+	log(string_join("Finished: ", read_attribute(pm, element, "name")))
+
 	if (element_eq(result, read_root())):
 		// Something went wrong!
 		output("Failure")
@@ -936,48 +938,55 @@ Void function enact_PM(pm : Element, mapping : Element):
 		dict_add(activity_to_task, set_pop(exec_nodes), set_create())
 
 	// Create the worklist with the Start instance as first element
-	worklist = set_create()
-	set_add(worklist, set_pop(allInstances(pm, "Start")))
+	worklist = list_create()
+	list_append(worklist, set_pop(allInstances(pm, "Start")))
 
 	// Keep on iterating until we reach finish
 	while (True):
 		// Check if there are PM elements to expand
-		if (set_len(worklist) > 0):
+		if (list_len(worklist) > 0):
 			// There is something we can do, so do it!
-			element = set_pop(worklist)
+			element = list_pop_final(worklist)
 
 			// Find the type (to see what to do with it)
 			//   this does not yet yield the type of transformation, if it is an Execution
 			type = read_type(pm, element)
+			log("Process type " + type)
 
 			// Some types have nothing to do, such as start and fork
 			// Therefore, they are not mentioned in the following conditional
 
 			if (type == "Finish"):
 				// We have finished, so terminate
+				log("Finish")
 				break!
 			elif (type == "Join"):
 				// Only do this if all dependencies are fullfilled
 				// So add to the counter of this Join
+				log("Join")
 				dict_overwrite(counters, element, integer_addition(counters[element], 1))
 
 				// Now check whether we have enough tokens to execute the Join itself
 				Integer required
 				Integer got
-				required = set_len(allIncomingAssociationInstances(pm, element, "Next")) + set_len(allIncomingAssociationInstances(pm, element, "Else"))
+				required = set_len(allIncomingAssociationInstances(pm, element, "Next")) + set_len(allIncomingAssociationInstances(pm, element, "Else")) + set_len(allIncomingAssociationInstances(pm, element, "Then"))
 				got = counters[element]
 				if (got == required):
 					// Reset counter to 0
 					dict_overwrite(counters, element, 0)
+					log("Got all!")
 
 					// And continue
 				else:
 					// We haven't gotten all yet, so we wait (i.e., continue without adding Next link to worklist)
+					log("Insufficient: " + cast_value(got))
+					log("Required: " + cast_value(required))
 					continue!
 
 			elif (type == "Exec"):
 				// Execute a transformation
 				// This the difficult part!
+				log("Exec")
 
 				Element args
 				String taskname
@@ -998,7 +1007,7 @@ Void function enact_PM(pm : Element, mapping : Element):
 			String next
 			while (set_len(all_next) > 0):
 				next = set_pop(all_next)
-				set_add(worklist, next)
+				list_append(worklist, next)
 		else:
 			// No new tasks to spawn, so go and check on all running activities
 			if (dict_len(task_to_result) > 0):
@@ -1009,6 +1018,7 @@ Void function enact_PM(pm : Element, mapping : Element):
 				keys = dict_keys(task_to_result)
 				while (set_len(keys) > 0):
 					task = set_pop(keys)
+					log("Detected finished " + cast_value(task_to_activity[task]))
 					result = task_to_result[task]
 
 					Element all_next
@@ -1016,22 +1026,24 @@ Void function enact_PM(pm : Element, mapping : Element):
 					String next
 					while (set_len(all_next) > 0):
 						next = set_pop(all_next)
+						log("Next: " + cast_value(next))
 
 						if (read_type(pm, next) == "Decision"):
 							// Got decision node, so expand immediately
 							if (result):
-								set_add(worklist, set_pop(allAssociationDestinations(pm, next, "Then")))
+								list_append(worklist, set_pop(allAssociationDestinations(pm, next, "Then")))
 							else:
-								set_add(worklist, set_pop(allAssociationDestinations(pm, next, "Else")))
+								list_append(worklist, set_pop(allAssociationDestinations(pm, next, "Else")))
 						else:
 							// Other node, so just append for further processing
-							set_add(worklist, next)
+							list_append(worklist, next)
 
 					set_remove(activity_to_task[task_to_activity[task]], task)
 					dict_delete(task_to_result, task)
 					dict_delete(task_to_activity, task)
 			else:
 				// No finished activities either, so we sleep for some time
+				log("No finished activities...")
 				sleep(0.1)
 
 	// Remove all mock locations again

+ 2 - 0
hybrid_server/classes/mvkcontroller.xml

@@ -298,6 +298,7 @@
                     </state>
                 </state>
 
+                <!--
                 <state id="mvs_GC" initial="suspend_tasks">
                     <state id="suspend_tasks">
                         <onentry>
@@ -317,6 +318,7 @@
                         <transition after="self.sccd_yield() + 10" target="."/>
                     </state>
                 </state>
+                -->
             </parallel>
 
             <state id="remove_sockets">

+ 1 - 0
hybrid_server/classes/socket.xml

@@ -146,6 +146,7 @@
             </state>
             <transition event="close" target="../close"/>
         </parallel>
+
         <state id="close">
             <onentry>
                 <raise port="socket_out" event="close_socket">

+ 28 - 24
kernel/modelverse_kernel/main.py

@@ -201,7 +201,8 @@ class ModelverseKernel(object):
                    "  " * (nested_indent + 2) + "yield [('CD', [_root, 'input', nxt])]\n" + \
                    "  " * (nested_indent + 2) + "_result = val\n" + \
                    "  " * (nested_indent + 2) + "break\n" + \
-                   "  " * (nested_indent + 1)+ "else:\n" + \
+                   "  " * (nested_indent + 1) + "else:\n" + \
+                   "  " * (nested_indent + 2) + "print('WAIT FOR INPUT...')\n" + \
                    "  " * (nested_indent + 2) + "yield None\n"
             instruction = "_result"
 
@@ -217,15 +218,18 @@ class ModelverseKernel(object):
                           "  " * indent + "yield [('DE', [_outputs_e])]\n" + \
                           "  " * indent + "yield [('CD', [_root, 'last_output', _new])]\n"
 
-
         elif inst_type["value"] == "resolve":
             value, = yield [("RD", [inst, "var"])]
             str_value, = yield [("RV", [value])]
             if str_value:
                 # Is a global
                 prev = \
-                       "  " * nested_indent + "%s, = yield [('RD', [_globs, '%s'])]\n" % (str_value, str_value) + \
-                       "  " * nested_indent + "%s, = yield [('RD', [%s, 'value'])]\n" % (str_value, str_value)
+                       "  " * nested_indent + "if '%s' not in _cache:\n" % str_value + \
+                       "  " * (nested_indent + 1) + "%s, = yield [('RD', [_globs, '%s'])]\n" % (str_value, str_value) + \
+                       "  " * (nested_indent + 1) + "%s, = yield [('RD', [%s, 'value'])]\n" % (str_value, str_value) + \
+                       "  " * (nested_indent + 1) + "_cache['%s'] = %s\n" % (str_value, str_value) + \
+                       "  " * nested_indent + "else:\n" + \
+                       "  " * (nested_indent + 1) + "%s = _cache['%s']\n" % (str_value, str_value)
                 instruction = str_value
 
                 if self.jit.get_global_body_id(str_value) is None:
@@ -235,7 +239,6 @@ class ModelverseKernel(object):
                     val, = yield [("RD", [val, 'value'])]
                     val, = yield [("RD", [val, 'body'])]
 
-                    print("Registering global " + str(str_value) + " using " + str(val))
                     self.jit.register_global(val, str_value)
             else:
                 # Is a local
@@ -280,24 +283,24 @@ class ModelverseKernel(object):
                 computation += prev_res
                 param_list[name] = instruction_res
 
+            value = "func_result_" + str(ModelverseKernel.counter)
+            ModelverseKernel.counter += 1
+
             if func_name in intrinsics:
-                #instruction = "  " * indent + intrinsics[func_name](*param_list)
-                # TODO
-                pass
+                #TODO test and fix
+                actual_computation = value + " = " + intrinsics[func_name](*param_list)
             else:
-                value = "func_result_" + str(ModelverseKernel.counter)
-                ModelverseKernel.counter += 1
                 param_list = "{" + ", ".join(["'%s': %s" % (k, v) for k, v in param_list.items()]) + "}"
                 actual_computation = "%s, = yield [('CALL_ARGS', [_mvk.execute_jit_internal, (_root, %s, _taskname, %s)])]\n" % (value, func_name, param_list)
 
-                if indent == 0:
-                    # No indent, meaning that we use it inline
-                    # Therefore, we output the prev and value individually
-                    prev, instruction = prev_func_name + computation + "  " * nested_indent + actual_computation, value
-                else:
-                    # Some indentation, meaning that we don't even use the return value
-                    # Therefore, we only do the yield
-                    prev, instruction = prev_func_name + computation, "  " * indent + actual_computation
+            if indent == 0:
+                # No indent, meaning that we use it inline
+                # Therefore, we output the prev and value individually
+                prev, instruction = prev_func_name + computation + "  " * nested_indent + actual_computation, value
+            else:
+                # Some indentation, meaning that we don't even use the return value
+                # Therefore, we only do the yield
+                prev, instruction = prev_func_name + computation, "  " * indent + actual_computation
 
         elif inst_type["value"] == "access":
             value, = yield [("RD", [inst, "var"])]
@@ -333,24 +336,25 @@ class ModelverseKernel(object):
             print("Ignoring mutable or unreadable: %s" % suggested_name)
             raise jit.JitCompilationFailedException("FAIL")
 
-        print("Reading function: %s" % suggested_name)
+        #print("Reading function: %s" % suggested_name)
         (prev, printed), = yield [("CALL_ARGS", [self.print_instruction, (inst, 1)])]
         preamble = "  _globs, = yield [('RD', [kwargs['task_root'], 'globals'])]\n" + \
                    "  _root = kwargs['task_root']\n" + \
                    "  _taskname = kwargs['taskname']\n" + \
-                   "  _mvk = kwargs['mvk']\n"
+                   "  _mvk = kwargs['mvk']\n" + \
+                   "  _cache = {}\n"
         printed = preamble + prev + printed
-        print("Total printed function: ")
+        #print("Total printed function: ")
         if params:
             func = "def " + suggested_name + "(" + ", ".join([chr(ord('a') + i) for i in range(len(params))]) + ", **kwargs):\n" + "".join(["  var_%s = %s\n" % (param, chr(ord('a') + i)) for i, param in enumerate(params)]) + printed
         else:
             func = "def " + suggested_name + "(**kwargs):\n" + printed
         
-        print(func)
+        #print(func)
 
         # To write out all generated functions
-        #with open('/tmp/junk/%s' % suggested_name, 'w') as f:
-        #    f.write(func)
+        with open('/tmp/junk/%s' % suggested_name, 'w') as f:
+            f.write(func)
 
         raise primitive_functions.PrimitiveFinished(func)
 

+ 1 - 0
run_pw.py

@@ -1,5 +1,6 @@
 import shutil
 import sys
+import os
 sys.path.append("wrappers")
 from modelverse import *
 import threading

+ 3 - 0
scripts/run_local_modelverse.py

@@ -36,6 +36,9 @@ try:
     sys.path.append(".")
     os.chdir("hybrid_server")
 
+    import stacktracer
+    stacktracer.trace_start("trace.html",interval=5,auto=True) # Set auto flag to always update file!
+
     import server
     import sccd.runtime.socket2event as socket2event
 

+ 1 - 1
wrappers/modelverse_SCCD.py

@@ -1,7 +1,7 @@
 """
 Generated by Statechart compiler by Glenn De Jonghe, Joeri Exelmans, Simon Van Mierlo, and Yentl Van Tendeloo (for the inspiration)
 
-Date:   Tue Apr 24 14:39:15 2018
+Date:   Tue Apr 24 17:47:15 2018
 
 Model author: Yentl Van Tendeloo
 Model name:   MvK Server