Parcourir la source

Various tweaks; particularly optimized dict_eq with compiled function

Yentl Van Tendeloo il y a 8 ans
Parent
commit
3d5d2f6e11

+ 0 - 6
bootstrap/transform.alc

@@ -55,8 +55,6 @@ Element function make_matching_schedule(schedule_model : Element, LHS : String,
 					// If it is an edge, we should also add the target and source
 					if (is_edge(schedule_model["model"][next])):
 						// Add the target/source to the schedule
-						//set_add(workset, reverseKeyLookup(schedule_model["model"], read_edge_src(schedule_model["model"][next])))
-						//set_add(workset, reverseKeyLookup(schedule_model["model"], read_edge_dst(schedule_model["model"][next])))
 						set_add(workset, reverse[cast_id2s(read_edge_src(schedule_model["model"][next]))])
 						set_add(workset, reverse[cast_id2s(read_edge_dst(schedule_model["model"][next]))])
 
@@ -65,7 +63,6 @@ Element function make_matching_schedule(schedule_model : Element, LHS : String,
 					while (counter > 0):
 						counter = counter - 1
 						if (set_in_node(schedule_model["model"], read_out(schedule_model["model"][next], counter))):
-							//set_add(workset, reverseKeyLookup(schedule_model["model"], read_out(schedule_model["model"][next], counter)))
 							set_add(workset, reverse[cast_id2s(read_out(schedule_model["model"][next], counter))])
 
 					// And incoming links
@@ -73,7 +70,6 @@ Element function make_matching_schedule(schedule_model : Element, LHS : String,
 					while (counter > 0):
 						counter = counter - 1
 						if (set_in_node(schedule_model["model"], read_in(schedule_model["model"][next], counter))):
-							//set_add(workset, reverseKeyLookup(schedule_model["model"], read_in(schedule_model["model"][next], counter)))
 							set_add(workset, reverse[cast_id2s(read_in(schedule_model["model"][next], counter))])
 
 	return schedule!
@@ -386,8 +382,6 @@ Void function rewrite(host_model : Element, schedule_model : Element, RHS : Stri
 		label = list_pop(labels_to_add, read_nr_out(labels_to_add) - 1)
 		if (is_edge(schedule_model["model"][RHS_map[label]])):
 			// Edge
-			//src = read_attribute(schedule_model, reverseKeyLookup(schedule_model["model"], read_edge_src(schedule_model["model"][RHS_map[label]])), "label")
-			//dst = read_attribute(schedule_model, reverseKeyLookup(schedule_model["model"], read_edge_dst(schedule_model["model"][RHS_map[label]])), "label")
 			src = read_attribute(schedule_model, reverse[cast_id2s(read_edge_src(schedule_model["model"][RHS_map[label]]))], "label")
 			dst = read_attribute(schedule_model, reverse[cast_id2s(read_edge_dst(schedule_model["model"][RHS_map[label]]))], "label")
 

+ 16 - 0
kernel/modelverse_kernel/compiled.py

@@ -117,3 +117,19 @@ def make_reverse_dictionary(a, **remainder):
     values = yield [("RDN", [a, i]) for i in key_nodes]
     yield [("CD", [reverse, str(v), k]) for k, v in zip(key_nodes, values)]
     raise PrimitiveFinished(reverse)
+
+def dict_eq(a, b, **remainder):
+    key_nodes, = yield [("RDK", [a])]
+    key_values = yield [("RV", [i]) for i in key_nodes]
+    values = yield [("RD", [a, i]) for i in key_values]
+    values = yield [("RV", [i]) for i in values]
+    a_dict = dict(zip(key_values, values))
+
+    key_nodes, = yield [("RDK", [b])]
+    key_values = yield [("RV", [i]) for i in key_nodes]
+    values = yield [("RD", [b, i]) for i in key_values]
+    values = yield [("RV", [i]) for i in values]
+    b_dict = dict(zip(key_values, values))
+
+    result, = yield [("CNV", [a_dict == b_dict])]
+    raise PrimitiveFinished(result)

+ 22 - 15
kernel/modelverse_kernel/request_handler.py

@@ -15,30 +15,32 @@ class GeneratorStackEntry(object):
         self.function_origin = None
         self.pending_requests = None
         self.finished_requests = True
-        self.replies = []
-        self.has_reply = False
+        self.replies = None
 
     def append_reply(self, new_reply):
         """Appends a reply to the this entry's list of pending replies."""
-        self.replies.append(new_reply)
-        self.has_reply = True
+        if self.replies is None:
+            self.replies = [new_reply]
+        else:
+            self.replies.append(new_reply)
 
     def extend_replies(self, new_replies):
         """Appends a list of replies to this entry's list of pending replies."""
         if new_replies is not None:
-            self.replies.extend(new_replies)
-            self.has_reply = True
+            if self.replies is None:
+                self.replies = new_replies
+            else:
+                self.replies.extend(new_replies)
 
     def step(self):
         """Performs a single step: accumulated replies are fed to the generator,
            which then produces requests."""
         # Send the replies to the generator, and ask for new requests.
-        self.pending_requests = self.generator.send(self.replies if self.has_reply else None)
+        self.pending_requests = self.generator.send(self.replies)
 
         # Reset some data structures.
         self.finished_requests = False
-        self.replies = []
-        self.has_reply = False
+        self.replies = None
 
 def format_stack_trace(stack_trace):
     """Formats a list of (function name, debug info, origin) triples."""
@@ -95,6 +97,7 @@ class RequestHandler(object):
             # Silence pylint's warning about catching Exception.
             # pylint: disable=I0011,W0703
             try:
+                """
                 if self.has_pending_requests():
                     try:
                         # Try to pop a request for the modelverse state.
@@ -105,7 +108,16 @@ class RequestHandler(object):
 
                 if not self.has_pending_requests():
                     # Perform a single generator step.
-                    self.step()
+                    self.generator_stack[-1].step()
+                """
+                if self.has_pending_requests():
+                    try:
+                        return self.pop_requests()
+                    except KnownRequestHandled:
+                        pass
+                else:
+                    self.generator_stack[-1].step()
+
             except StopIteration:
                 # Done, so remove the generator
                 self.pop_generator()
@@ -174,11 +186,6 @@ class RequestHandler(object):
         """Appends a list of replies to the top-of-stack generator's list of pending replies."""
         self.generator_stack[-1].extend_replies(new_replies)
 
-    def step(self):
-        """Performs a single step: accumulated replies are fed to the generator,
-           which then produces requests."""
-        self.generator_stack[-1].step()
-
     def handle_exception(self, exception):
         """Handles the given exception. A Boolean is returned that tells if
            the exception was handled."""

+ 1 - 0
models/reachability.alc

@@ -137,6 +137,7 @@ Element function reachability_graph(params : Element, output_mms : Element):
 
 				keys = dict_keys(reachable_states)
 				target_id = -1
+				Float start
 				while (read_nr_out(keys) > 0):
 					other_state_id = set_pop(keys)
 

+ 2 - 2
scripts/run_local_modelverse.py

@@ -10,5 +10,5 @@ else:
     # There's no need to specify `--kernel=baseline-jit` here, because that's the default kernel.
     # Also, specifying a kernel here breaks the performance tests.
 
-    #subprocess.call([sys.executable, "run_mvk_server.py"] + sys.argv[1:], cwd="hybrid_server")
-    subprocess.call([sys.executable, "-m", "cProfile", "-s", "tottime", "run_mvk_server.py"] + sys.argv[1:], cwd="hybrid_server", stdout=open("/tmp/stdout", 'w'), stderr=open("/tmp/stderr", "w"))
+    subprocess.call([sys.executable, "run_mvk_server.py"] + sys.argv[1:], cwd="hybrid_server")
+    #subprocess.call([sys.executable, "-m", "cProfile", "-s", "tottime", "run_mvk_server.py"] + sys.argv[1:], cwd="hybrid_server", stdout=open("/tmp/stdout", 'w'), stderr=open("/tmp/stderr", "w"))

+ 36 - 1
state/modelverse_state/main.py

@@ -199,7 +199,7 @@ class ModelverseState(object):
             s, t = v
             return ([s, t], status.SUCCESS)
 
-    def read_dict(self, node, value):
+    def read_dict_old(self, node, value):
         e, s = self.read_dict_edge(node, value)
         if s != status.SUCCESS:
             return (None, {status.FAIL_RDICTE_UNKNOWN: status.FAIL_RDICT_UNKNOWN,
@@ -209,6 +209,41 @@ class ModelverseState(object):
                            status.FAIL_RDICTE_AMBIGUOUS: status.FAIL_RDICT_AMBIGUOUS}[s])
         return (self.edges[e][1], status.SUCCESS)
 
+    def read_dict(self, node, value):
+        try:
+            first = self.cache[node][value]
+            # Got hit, so validate
+            if (self.edges[first][0] == node) and \
+                (len(self.outgoing[first]) == 1) and \
+                (self.values[self.edges[list(self.outgoing[first])[0]][1]] == value):
+                return (self.edges[first][1], status.SUCCESS)
+            # Hit but invalid now
+            del self.cache[node][value]
+        except KeyError:
+            # Didn't exist
+            pass
+
+        if node not in self.nodes and node not in self.edges:
+            return (None, status.FAIL_RDICT_UNKNOWN)
+        if not self.is_valid_datavalue(value):
+            return (None, status.FAIL_RDICT_OOB)
+            
+        # Get all outgoing links
+        for e1 in self.outgoing.get(node, set()):
+            data_links = self.outgoing.get(e1, set())
+            # For each link, we read the links that might link to a data value
+            for e2 in data_links:
+                # Now read out the target of the link
+                target = self.edges[e2][1]
+                # And access its value
+                v = self.values.get(target, None)
+                if v == value:
+                    # Found a match
+                    # Now get the target of the original link
+                    self.cache.setdefault(node, {})[value] = e1
+                    return (self.edges[e1][1], status.SUCCESS)
+        return (None, status.FAIL_RDICT_NOT_FOUND)
+
     def read_dict_keys(self, node):
         if node not in self.nodes and node not in self.edges:
             return (None, status.FAIL_RDICTKEYS_UNKNOWN)