From 0e1db7e22918d2cf0164a10502bbe2f0ca09b340 Mon Sep 17 00:00:00 2001 From: Jakob Louis Therkelsen Date: Mon, 4 Nov 2024 10:13:37 -0500 Subject: [PATCH 01/84] init push with some testing --- __jac_gen__/__init__.py | 0 __jac_gen__/test.jbc | Bin 0 -> 226 bytes __jac_gen__/test.py | 2 ++ __jac_gen__/test.registry.pkl | Bin 0 -> 76 bytes test.dot | 4 ++++ test.jac | 1 + 6 files changed, 7 insertions(+) create mode 100644 __jac_gen__/__init__.py create mode 100644 __jac_gen__/test.jbc create mode 100644 __jac_gen__/test.py create mode 100644 __jac_gen__/test.registry.pkl create mode 100644 test.dot create mode 100644 test.jac diff --git a/__jac_gen__/__init__.py b/__jac_gen__/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/__jac_gen__/test.jbc b/__jac_gen__/test.jbc new file mode 100644 index 0000000000000000000000000000000000000000..c5ad62b08efd7323d1226191316914eb0cb88725 GIT binary patch literal 226 zcmYdhKmyDVHsfanAY(d13PTEG4nrTj_Y6lLa>tYr8M z(*4U+KeRZts8~NMF*`r0BqOybJ2j^`HBa9qKe;qFHLnCDQ=FQdshgge7pz~BT3n)+ um6-gC!zMRBr8Fniu80$83dmK({6OLZGb1D8T}IW;)Cs;<`IL&-fnorWcsz3e literal 0 HcmV?d00001 diff --git a/__jac_gen__/test.py b/__jac_gen__/test.py new file mode 100644 index 0000000000..e1ea9a2ff0 --- /dev/null +++ b/__jac_gen__/test.py @@ -0,0 +1,2 @@ +from __future__ import annotations +print('hello world') \ No newline at end of file diff --git a/__jac_gen__/test.registry.pkl b/__jac_gen__/test.registry.pkl new file mode 100644 index 0000000000000000000000000000000000000000..fcc40737ab201e2e21c2b051cffc799b0798c715 GIT binary patch literal 76 zcmZo*nd-;@0X>pgiOD&MdFgt|`MCv|IjKc@#i_X^iAg!BQ+l|AQ*(n-(=&@piYli} Vo}$?}rFKdWM-fb Date: Mon, 4 Nov 2024 13:29:16 -0500 Subject: [PATCH 02/84] threading example --- __jac_gen__/test.jbc | Bin 226 -> 232 bytes __jac_gen__/test.py | 2 +- test.jac | 2 +- thread_example.py | 25 +++++++++++++++++++++++++ 4 files changed, 27 insertions(+), 2 deletions(-) create mode 100644 thread_example.py diff --git a/__jac_gen__/test.jbc b/__jac_gen__/test.jbc index c5ad62b08efd7323d1226191316914eb0cb88725..095bdb1a970c0bc05535476014e4444637940686 100644 GIT binary patch delta 53 zcmaFF_=0glprAlTYEDkRLV12sPKrWWX>#_&*jz~g1_p)?%#4hTcNw)hQ!j|9UFB0R IVh0KW0OYt2@c;k- delta 47 zcmaFC_=s^rAP;v&YEDkRLV12sPRhijTnT;#28IvJjEszT8C5$|C-`3FQz~KyiU9z4 CZVl=H diff --git a/__jac_gen__/test.py b/__jac_gen__/test.py index e1ea9a2ff0..9c5bbda160 100644 --- a/__jac_gen__/test.py +++ b/__jac_gen__/test.py @@ -1,2 +1,2 @@ from __future__ import annotations -print('hello world') \ No newline at end of file +print('hello world fuck') \ No newline at end of file diff --git a/test.jac b/test.jac index 0df93fcce2..67fe17fcbc 100644 --- a/test.jac +++ b/test.jac @@ -1 +1 @@ -with entry { print('hello world'); } +with entry { print('hello world fuck'); } diff --git a/thread_example.py b/thread_example.py new file mode 100644 index 0000000000..ea935e8c9d --- /dev/null +++ b/thread_example.py @@ -0,0 +1,25 @@ +import threading +import os + +def task1(): + print("Task 1 assigned to thread: {}".format(threading.current_thread().name)) + print("ID of process running task 1: {}".format(os.getpid())) + +def task2(): + print("Task 2 assigned to thread: {}".format(threading.current_thread().name)) + print("ID of process running task 2: {}".format(os.getpid())) + +if __name__ == "__main__": + + print("ID of process running main program: {}".format(os.getpid())) + + print("Main thread name: {}".format(threading.current_thread().name)) + + t1 = threading.Thread(target=task1, name='t1') + t2 = threading.Thread(target=task2, name='t2') + + t1.start() + t2.start() + + t1.join() + t2.join() \ No newline at end of file From 0deb391dd187802d152605034491ed19ab1537ce Mon Sep 17 00:00:00 2001 From: Jakob Louis Therkelsen Date: Tue, 5 Nov 2024 13:32:29 -0500 Subject: [PATCH 03/84] initial gins stuff --- jac/jaclang/cli/cli.py | 10 +++++----- jac/jaclang/runtimelib/machine.py | 13 +++++++++++++ 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/jac/jaclang/cli/cli.py b/jac/jaclang/cli/cli.py index 3bfac181eb..8f8f4ec885 100644 --- a/jac/jaclang/cli/cli.py +++ b/jac/jaclang/cli/cli.py @@ -22,11 +22,12 @@ from jaclang.plugin.feature import JacFeature as Jac from jaclang.runtimelib.constructs import WalkerArchitype from jaclang.runtimelib.context import ExecutionContext -from jaclang.runtimelib.machine import JacMachine, JacProgram +from jaclang.runtimelib.machine import JacMachine, JacProgram, ShellGhost from jaclang.utils.helpers import debugger as db from jaclang.utils.lang_tools import AstTool + Cmd.create_cmd() Jac.setup() @@ -68,7 +69,7 @@ def format_file(filename: str) -> None: @cmd_registry.register def run( - filename: str, session: str = "", main: bool = True, cache: bool = True + filename: str, session: str = "", main: bool = True, cache: bool = True, gins: bool = False ) -> None: """Run the specified .jac file.""" # if no session specified, check if it was defined when starting the command shell @@ -82,10 +83,10 @@ def run( else "" ) + gins_instance = ShellGhost(is_running=gins) base, mod = os.path.split(filename) base = base if base else "./" mod = mod[:-4] - jctx = ExecutionContext.create(session=session) if filename.endswith(".jac"): @@ -496,7 +497,6 @@ def jac2py(filename: str) -> None: else: print("Not a .jac file.") - def start_cli() -> None: """ Start the command line interface. @@ -526,4 +526,4 @@ def start_cli() -> None: if __name__ == "__main__": - start_cli() + start_cli() \ No newline at end of file diff --git a/jac/jaclang/runtimelib/machine.py b/jac/jaclang/runtimelib/machine.py index f1b5fecf53..d90ddd3469 100644 --- a/jac/jaclang/runtimelib/machine.py +++ b/jac/jaclang/runtimelib/machine.py @@ -6,6 +6,7 @@ import sys import tempfile import types +from threading import Thread from contextvars import ContextVar from typing import Optional, Union @@ -299,3 +300,15 @@ def get_bytecode( return marshal.loads(result.ir.gen.py_bytecode) else: return None + + +class ShellGhost: + def __init__(self, is_running:bool = False): + self.__daemon_thread = Thread( + target = self.worker(), + daemon = True + ) + + def worker(self): + print("doesn't do anything") + os.sleep(2) \ No newline at end of file From db2503e38e64e8c3eaf47a68d8b31a5064c6b4e7 Mon Sep 17 00:00:00 2001 From: clin155 Date: Tue, 5 Nov 2024 13:35:00 -0500 Subject: [PATCH 04/84] g --- __jac_gen__/test.jbc | Bin 232 -> 237 bytes jac/jaclang/runtimelib/machine.py | 7 ++++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/__jac_gen__/test.jbc b/__jac_gen__/test.jbc index 095bdb1a970c0bc05535476014e4444637940686..e8c2d0527eda22f365a22b2ea09d1b969233e7f4 100644 GIT binary patch delta 70 zcmaFC_?B@(tBsX@XmM&$v3_z!QD$*TenCcRQBG!_zDsIxHjt<9oRe5woLa1(l~|mb YoT;0hnHQ{Il3HA%mz9`&YvLXq0McC>!2kdN delta 65 zcmaFM_=0gltGTIuXmM&$v3^!!c79SxMru)ZYEE%#p1w Date: Tue, 5 Nov 2024 13:59:38 -0500 Subject: [PATCH 05/84] g --- jac/jaclang/cli/cli.py | 2 +- jac/jaclang/runtimelib/machine.py | 17 ++++++++++------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/jac/jaclang/cli/cli.py b/jac/jaclang/cli/cli.py index 8f8f4ec885..82b39a8e85 100644 --- a/jac/jaclang/cli/cli.py +++ b/jac/jaclang/cli/cli.py @@ -83,7 +83,7 @@ def run( else "" ) - gins_instance = ShellGhost(is_running=gins) + gins_instance = ShellGhost(filename, is_running=gins) base, mod = os.path.split(filename) base = base if base else "./" mod = mod[:-4] diff --git a/jac/jaclang/runtimelib/machine.py b/jac/jaclang/runtimelib/machine.py index a63222fdc4..afd90c39ca 100644 --- a/jac/jaclang/runtimelib/machine.py +++ b/jac/jaclang/runtimelib/machine.py @@ -12,7 +12,8 @@ from typing import Optional, Union from jaclang.compiler.absyntree import Module -from jaclang.compiler.compile import compile_jac +from jaclang.compiler.compile import compile_jac, jac_file_to_pass + from jaclang.compiler.constant import Constants as Con from jaclang.runtimelib.architype import ( Architype, @@ -21,7 +22,7 @@ WalkerArchitype, ) from jaclang.utils.log import logging - +from jaclang.compiler.passes.main.schedules import py_code_gen, type_checker_sched logger = logging.getLogger(__name__) @@ -304,12 +305,14 @@ def get_bytecode( class ShellGhost: - def __init__(self, is_running:bool = False): + def __init__(self, file_name:str, is_running:bool = False): self.__daemon_thread = Thread( - target = self.worker, - daemon = True - ) + target = self.worker, args=(file_name,)) self.__daemon_thread.start() - def worker(self): + def worker(self, file_name): print("doesn't do anything") + ir = jac_file_to_pass( + file_name, schedule=[*(py_code_gen[:-1]), *type_checker_sched] + ).ir + print(ir.pp()) time.sleep(2) \ No newline at end of file From 2bdcf34621ff4569a792c74a718ceaac38be795d Mon Sep 17 00:00:00 2001 From: Jakob Louis Therkelsen Date: Tue, 5 Nov 2024 14:29:10 -0500 Subject: [PATCH 06/84] family friendly test statement --- test.jac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test.jac b/test.jac index 67fe17fcbc..0df93fcce2 100644 --- a/test.jac +++ b/test.jac @@ -1 +1 @@ -with entry { print('hello world fuck'); } +with entry { print('hello world'); } From d35e18e05f488c4a65cbd709c5f516b1ebc37c2a Mon Sep 17 00:00:00 2001 From: Jakob Louis Therkelsen Date: Wed, 6 Nov 2024 20:06:05 -0500 Subject: [PATCH 07/84] remove cached files --- __jac_gen__/__init__.py | 0 __jac_gen__/test.jbc | Bin 237 -> 0 bytes __jac_gen__/test.py | 2 -- __jac_gen__/test.registry.pkl | Bin 76 -> 0 bytes 4 files changed, 2 deletions(-) delete mode 100644 __jac_gen__/__init__.py delete mode 100644 __jac_gen__/test.jbc delete mode 100644 __jac_gen__/test.py delete mode 100644 __jac_gen__/test.registry.pkl diff --git a/__jac_gen__/__init__.py b/__jac_gen__/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/__jac_gen__/test.jbc b/__jac_gen__/test.jbc deleted file mode 100644 index e8c2d0527eda22f365a22b2ea09d1b969233e7f4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 237 zcmYdhKmyDVHsfanAY(d13PTEG4nrD@r|+DTSX`W1te=%woSK}e zo1U2$tY4B^T%wnin0$-FCO1E&G$+-rh!bcO$bH2EK;i>4BO~KoMy<}&3nFS)`P7Tp Gfr0>flRz~9 diff --git a/__jac_gen__/test.py b/__jac_gen__/test.py deleted file mode 100644 index 9c5bbda160..0000000000 --- a/__jac_gen__/test.py +++ /dev/null @@ -1,2 +0,0 @@ -from __future__ import annotations -print('hello world fuck') \ No newline at end of file diff --git a/__jac_gen__/test.registry.pkl b/__jac_gen__/test.registry.pkl deleted file mode 100644 index fcc40737ab201e2e21c2b051cffc799b0798c715..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 76 zcmZo*nd-;@0X>pgiOD&MdFgt|`MCv|IjKc@#i_X^iAg!BQ+l|AQ*(n-(=&@piYli} Vo}$?}rFKdWM-fb Date: Fri, 8 Nov 2024 18:04:58 -0500 Subject: [PATCH 08/84] Cleanup ShellGhost --- jac/jaclang/cli/cli.py | 3 ++- jac/jaclang/runtimelib/machine.py | 35 +++++++++++++++++++++++++++---- 2 files changed, 33 insertions(+), 5 deletions(-) diff --git a/jac/jaclang/cli/cli.py b/jac/jaclang/cli/cli.py index 82b39a8e85..6b4ba4234d 100644 --- a/jac/jaclang/cli/cli.py +++ b/jac/jaclang/cli/cli.py @@ -83,11 +83,12 @@ def run( else "" ) - gins_instance = ShellGhost(filename, is_running=gins) base, mod = os.path.split(filename) base = base if base else "./" mod = mod[:-4] jctx = ExecutionContext.create(session=session) + if gins: + JacMachine(base).attach_gin(ShellGhost(filename)) if filename.endswith(".jac"): jac_import( diff --git a/jac/jaclang/runtimelib/machine.py b/jac/jaclang/runtimelib/machine.py index afd90c39ca..80b9b2ea20 100644 --- a/jac/jaclang/runtimelib/machine.py +++ b/jac/jaclang/runtimelib/machine.py @@ -45,12 +45,17 @@ def __init__(self, base_path: str = "") -> None: else os.path.abspath(base_path) ) self.jac_program: Optional[JacProgram] = None + self.gin: Optional[ShellGhost] = None JACMACHINE_CONTEXT.set(self) def attach_program(self, jac_program: "JacProgram") -> None: """Attach a JacProgram to the machine.""" self.jac_program = jac_program + + def attach_gin(self, jac_gin: "ShellGhost") -> None: + """Attach a JacProgram to the machine.""" + self.gin = jac_gin def get_mod_bundle(self) -> Optional[Module]: """Retrieve the mod_bundle from the attached JacProgram.""" @@ -305,14 +310,36 @@ def get_bytecode( class ShellGhost: - def __init__(self, file_name:str, is_running:bool = False): - self.__daemon_thread = Thread( - target = self.worker, args=(file_name,)) + def __init__(self, file_name: str): + self.__daemon_thread:Thread = Thread(target=self.worker, args=(file_name,)) + self.cfg = None self.__daemon_thread.start() + def worker(self, file_name): print("doesn't do anything") ir = jac_file_to_pass( file_name, schedule=[*(py_code_gen[:-1]), *type_checker_sched] ).ir print(ir.pp()) - time.sleep(2) \ No newline at end of file + time.sleep(2) + + +# import time +# import gc +# import inspect +# with open("log.txt", "a") as log_file: +# while True: +# # Pause to avoid excessive checks +# time.sleep(10) + +# # Gather all objects in the main application +# objects = gc.get_objects() +# log_file.write("\n[Monitor] Checking objects in main application:\n") + +# for obj in objects: +# # Only monitor dictionaries (e.g., modules, function locals, etc.) +# if isinstance(obj, dict): +# for name, value in obj.items(): +# log_file.write(f"Variable '{name}' = {value}\n") +# log_file.write("\n=====================================================================\n") +# log_file.flush() # Ensure data is written immediately \ No newline at end of file From eeffd6f810276bb3565e5cd71db8accb4534bcd5 Mon Sep 17 00:00:00 2001 From: Jakob Louis Therkelsen Date: Fri, 8 Nov 2024 18:55:08 -0500 Subject: [PATCH 09/84] hot path test code --- jac/examples/ginsScripts/hot_path.jac | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 jac/examples/ginsScripts/hot_path.jac diff --git a/jac/examples/ginsScripts/hot_path.jac b/jac/examples/ginsScripts/hot_path.jac new file mode 100644 index 0000000000..b36d6f128d --- /dev/null +++ b/jac/examples/ginsScripts/hot_path.jac @@ -0,0 +1,15 @@ + +with entry { + a = 0; + b = 0; + while a < 15 { + if a % 2 == 0{ + b = 1; + } + else { + b = 2; + } + a += 1; + } + print("done"); +} \ No newline at end of file From 0c6fdbadad4b3bee8afecd992ebb9e232dc885a9 Mon Sep 17 00:00:00 2001 From: jayanaka-98 Date: Fri, 8 Nov 2024 19:18:11 -0500 Subject: [PATCH 10/84] starting pass --- .../compiler/passes/main/cfg_gen_pass.py | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 jac/jaclang/compiler/passes/main/cfg_gen_pass.py diff --git a/jac/jaclang/compiler/passes/main/cfg_gen_pass.py b/jac/jaclang/compiler/passes/main/cfg_gen_pass.py new file mode 100644 index 0000000000..b385249836 --- /dev/null +++ b/jac/jaclang/compiler/passes/main/cfg_gen_pass.py @@ -0,0 +1,32 @@ +"""Genrate a control flow graph from genarated bytecode. + +This pass generates a control flow graph from the bytecode generated by the previous pass. +""" + +import ast as ast3 +import marshal + + +import jaclang.compiler.absyntree as ast +from jaclang.compiler.passes import Pass +from jaclang.runtimelib.machine import JacMachine, JacProgram, ShellGhost + +class CfgGenPass(Pass): + """Control flow graph generation pass.""" + + def before_pass(self) -> None: + """Before pass.""" + return super().before_pass() + + def enter_module(self, node: ast.Module) -> None: + """Sub objects. + + name: str, + doc: Token, + body: Optional['Elements'], + mod_path: str, + is_imported: bool, + sym_tab: Optional[SymbolTable], + """ + + pass \ No newline at end of file From a0c9811df2861b62b8badafad11ba451d1d58582 Mon Sep 17 00:00:00 2001 From: jayanaka-98 Date: Sat, 9 Nov 2024 10:23:42 -0500 Subject: [PATCH 11/84] Bytecode extraction --- jac/jaclang/compiler/passes/main/__init__.py | 2 + .../compiler/passes/main/cfg_gen_pass.py | 106 +++++++++++++++++- jac/jaclang/compiler/passes/main/schedules.py | 2 + jac/jaclang/runtimelib/machine.py | 10 +- 4 files changed, 112 insertions(+), 8 deletions(-) diff --git a/jac/jaclang/compiler/passes/main/__init__.py b/jac/jaclang/compiler/passes/main/__init__.py index 8d755983f7..e828d08967 100644 --- a/jac/jaclang/compiler/passes/main/__init__.py +++ b/jac/jaclang/compiler/passes/main/__init__.py @@ -11,6 +11,7 @@ from .schedules import py_code_gen # noqa: I100 from .type_check_pass import JacTypeCheckPass # noqa: I100 from .registry_pass import RegistryPass # noqa: I100 +from .cfg_gen_pass import CfgGenPass # noqa: I100 pass_schedule = py_code_gen # type: ignore[has-type] @@ -27,4 +28,5 @@ "PyastGenPass", "JacTypeCheckPass", "RegistryPass", + "CfgGenPass", ] diff --git a/jac/jaclang/compiler/passes/main/cfg_gen_pass.py b/jac/jaclang/compiler/passes/main/cfg_gen_pass.py index b385249836..142a50fc50 100644 --- a/jac/jaclang/compiler/passes/main/cfg_gen_pass.py +++ b/jac/jaclang/compiler/passes/main/cfg_gen_pass.py @@ -5,11 +5,15 @@ import ast as ast3 import marshal +import dis +from collections import defaultdict +import networkx as nx +import matplotlib.pyplot as plt import jaclang.compiler.absyntree as ast from jaclang.compiler.passes import Pass -from jaclang.runtimelib.machine import JacMachine, JacProgram, ShellGhost + class CfgGenPass(Pass): """Control flow graph generation pass.""" @@ -17,7 +21,7 @@ class CfgGenPass(Pass): def before_pass(self) -> None: """Before pass.""" return super().before_pass() - + def enter_module(self, node: ast.Module) -> None: """Sub objects. @@ -28,5 +32,101 @@ def enter_module(self, node: ast.Module) -> None: is_imported: bool, sym_tab: Optional[SymbolTable], """ + mods = [node] + self.get_all_sub_nodes(node, ast.Module) + module_cfgs = generate_module_cfg(mods) + for module_name, cfg_graph in module_cfgs.items(): + print(f"Control Flow Graph for {module_name}:") + nx.draw(cfg_graph, with_labels=True) + plt.title("Control Flow Graph") + plt.show() + plt.savefig(f"{module_name}_cfg.png") + + +def disassemble_bytecode(bytecode): + code_object = marshal.loads(bytecode) + instructions = list(dis.get_instructions(code_object)) + print(f"Disassembled bytecode for {code_object.co_name}:") + print( + "\n".join( + [f"{instr.offset}: {instr.opname} {instr.argval}" for instr in instructions] + ) + ) + return instructions + + +def extract_cfg_from_instructions(instructions): + cfg = defaultdict(list) + current_block = [] + block_id = 0 + block_map = {} # Maps instruction offsets to blocks + edges = {} + + for instr in instructions: + current_block.append(instr) + if instr.opname in { + "JUMP_ABSOLUTE", + "JUMP_FORWARD", + "POP_JUMP_IF_TRUE", + "POP_JUMP_IF_FALSE", + "JUMP_IF_TRUE_OR_POP", + "JUMP_IF_FALSE_OR_POP", + }: + cfg[block_id] = current_block + block_map[instr.offset] = block_id + target = ( + instr.offset + instr.argval + 2 + if instr.opname == "JUMP_FORWARD" + else instr.argval + ) + edges[block_id] = target + block_id += 1 + + # Update edges to use block numbers instead of offsets + for block_id, target_offset in edges.items(): + if target_offset in block_map: + edges[block_id] = block_map[target_offset] + else: + print(f"Warning: Target offset {target_offset} not found in block_map") + print(edges) + return cfg, block_map, edges + + +def build_cfg_graph(cfg, block_map, edges): + graph = nx.DiGraph() + + for block_id, instructions in cfg.items(): + print(f"Block ID {block_id}:") + print( + "\n".join( + [ + f"{instr.offset}: {instr.opname} {instr.argval}" + for instr in instructions + ] + ) + ) + graph.add_node(block_id, instructions=instructions) + last_instruction = instructions[-1] if instructions else None + + # Verify last_instruction is valid and has 'opname' attribute + if last_instruction and hasattr(last_instruction, "opname"): + if ( + "JUMP" in last_instruction.opname + and last_instruction.argval in block_map + ): + target_block = block_map[last_instruction.offset] + graph.add_edge(block_id, target_block) + else: + print( + f"Warning: Block ID {block_id} does not have a valid jump target or last instruction" + ) + return graph + - pass \ No newline at end of file +def generate_module_cfg(modules): + module_cfgs = {} + for mod in modules: + bytecode = mod.gen.py_bytecode + instructions = disassemble_bytecode(bytecode) + cfg, block_map, edges = extract_cfg_from_instructions(instructions) + module_cfgs[mod.name] = build_cfg_graph(cfg, block_map, edges) + return module_cfgs diff --git a/jac/jaclang/compiler/passes/main/schedules.py b/jac/jaclang/compiler/passes/main/schedules.py index 0ac604fa9b..71c1b52f01 100644 --- a/jac/jaclang/compiler/passes/main/schedules.py +++ b/jac/jaclang/compiler/passes/main/schedules.py @@ -20,6 +20,7 @@ from .registry_pass import RegistryPass # noqa: I100 from .access_modifier_pass import AccessCheckPass # noqa: I100 from .py_collect_dep_pass import PyCollectDepsPass # noqa: I100 +from .cfg_gen_pass import CfgGenPass # noqa: I100 py_code_gen = [ SubNodeTabPass, @@ -31,6 +32,7 @@ PyastGenPass, PyJacAstLinkPass, PyBytecodeGenPass, + CfgGenPass, ] type_checker_sched = [ diff --git a/jac/jaclang/runtimelib/machine.py b/jac/jaclang/runtimelib/machine.py index 80b9b2ea20..e4ee40618b 100644 --- a/jac/jaclang/runtimelib/machine.py +++ b/jac/jaclang/runtimelib/machine.py @@ -317,11 +317,11 @@ def __init__(self, file_name: str): def worker(self, file_name): print("doesn't do anything") - ir = jac_file_to_pass( - file_name, schedule=[*(py_code_gen[:-1]), *type_checker_sched] - ).ir - print(ir.pp()) - time.sleep(2) + # ir = jac_file_to_pass( + # file_name, schedule=[*(py_code_gen[:-1]), *type_checker_sched] + # ).ir + # print(ir.pp()) + # time.sleep(2) # import time From aa9bf7e671dfb54b2e43197247a77cd511b2eedc Mon Sep 17 00:00:00 2001 From: Kellen Kanarios Date: Sat, 9 Nov 2024 10:35:39 -0500 Subject: [PATCH 12/84] claude went to work? --- jac/jaclang/compiler/passes/cfg.py | 204 +++++++++++++++++++++++++++++ 1 file changed, 204 insertions(+) create mode 100644 jac/jaclang/compiler/passes/cfg.py diff --git a/jac/jaclang/compiler/passes/cfg.py b/jac/jaclang/compiler/passes/cfg.py new file mode 100644 index 0000000000..11429bc60a --- /dev/null +++ b/jac/jaclang/compiler/passes/cfg.py @@ -0,0 +1,204 @@ +import dis +import sys +import types +from collections import defaultdict +import graphviz +from typing import Dict, Set, List, Tuple, Optional + + +class CFGNode: + def __init__(self, offset: int, instructions: List[dis.Instruction]): + self.offset = offset + self.instructions = instructions + self.next: List['CFGNode'] = [] + self.hits = 0 # Track number of times this node is executed + + def __repr__(self): + return f"Node({self.offset})" + + +class CFGTracker: + def __init__(self): + self.cfg_cache: Dict[types.CodeType, Dict[int, CFGNode]] = {} + self.coverage_data: Dict[types.CodeType, + Set[Tuple[int, int]]] = defaultdict(set) + + def build_cfg(self, code: types.CodeType) -> Dict[int, CFGNode]: + """Build CFG from bytecode""" + if code in self.cfg_cache: + return self.cfg_cache[code] + + # Get bytecode instructions + instructions = list(dis.get_instructions(code)) + + # Find basic block boundaries + leaders = {0} # First instruction is always a leader + for i, inst in enumerate(instructions): + if inst.opname in {'JUMP_ABSOLUTE', 'JUMP_FORWARD', 'POP_JUMP_IF_TRUE', + 'POP_JUMP_IF_FALSE', 'JUMP_IF_TRUE_OR_POP', + 'JUMP_IF_FALSE_OR_POP'}: + leaders.add(inst.argval) # Target of jump + if i + 1 < len(instructions): + # Instruction after jump + leaders.add(instructions[i + 1].offset) + + # Create basic blocks + blocks: Dict[int, CFGNode] = {} + current_block: List[dis.Instruction] = [] + current_leader = 0 + + for inst in instructions: + if inst.offset in leaders and current_block: + blocks[current_leader] = CFGNode(current_leader, current_block) + current_block = [] + current_leader = inst.offset + current_block.append(inst) + + if current_block: + blocks[current_leader] = CFGNode(current_leader, current_block) + + # Connect blocks + for offset, block in blocks.items(): + last_inst = block.instructions[-1] + + if last_inst.opname in {'JUMP_ABSOLUTE', 'JUMP_FORWARD'}: + block.next.append(blocks[last_inst.argval]) + elif last_inst.opname in {'POP_JUMP_IF_TRUE', 'POP_JUMP_IF_FALSE', + 'JUMP_IF_TRUE_OR_POP', 'JUMP_IF_FALSE_OR_POP'}: + block.next.append(blocks[last_inst.argval]) # Branch target + if offset + last_inst.size < instructions[-1].offset: + # Find next instruction's block + next_offset = offset + last_inst.size + while next_offset not in blocks: + next_offset += 1 + block.next.append(blocks[next_offset]) # Fall-through + elif offset + last_inst.size < instructions[-1].offset: + # Sequential flow + next_offset = offset + last_inst.size + while next_offset not in blocks: + next_offset += 1 + block.next.append(blocks[next_offset]) + + self.cfg_cache[code] = blocks + return blocks + + def trace_callback(self, frame: types.FrameType, event: str, arg: Any) -> Optional[types.TraceFunction]: + """Trace function to track executed branches""" + if event != 'line': + return self.trace_callback + + code = frame.f_code + if code not in self.cfg_cache: + self.build_cfg(code) + + # Find current basic block + blocks = self.cfg_cache[code] + current_offset = frame.f_lasti + + # Find the block containing this offset + current_block = None + for block in blocks.values(): + if block.offset <= current_offset <= block.offset + sum(inst.size for inst in block.instructions): + current_block = block + break + + if current_block: + current_block.hits += 1 + # Record taken branches + for next_block in current_block.next: + self.coverage_data[code].add( + (current_block.offset, next_block.offset)) + + return self.trace_callback + + def start_tracking(self): + """Start tracking branch coverage""" + sys.settrace(self.trace_callback) + + def stop_tracking(self): + """Stop tracking branch coverage""" + sys.settrace(None) + + def get_coverage_report(self, code: types.CodeType) -> str: + """Generate coverage report for the given code object""" + if code not in self.cfg_cache: + return "No coverage data available" + + blocks = self.cfg_cache[code] + taken_branches = self.coverage_data[code] + + # Calculate total possible branches + total_branches = sum(len(block.next) for block in blocks.values()) + covered_branches = len(taken_branches) + + report = [] + report.append(f"Branch Coverage: {covered_branches}/{total_branches} " + f"({covered_branches/total_branches*100:.1f}%)") + + # Report uncovered branches + uncovered = [] + for block in blocks.values(): + for next_block in block.next: + if (block.offset, next_block.offset) not in taken_branches: + uncovered.append((block.offset, next_block.offset)) + + if uncovered: + report.append("\nUncovered branches:") + for src, dst in sorted(uncovered): + report.append(f" {src} -> {dst}") + + return "\n".join(report) + + def visualize_cfg(self, code: types.CodeType, filename: str = 'cfg'): + """Generate a visual representation of the CFG using graphviz""" + if code not in self.cfg_cache: + self.build_cfg(code) + + dot = graphviz.Digraph(comment='Control Flow Graph') + blocks = self.cfg_cache[code] + taken_branches = self.coverage_data[code] + + # Add nodes + for block in blocks.values(): + label = f"Offset: {block.offset}\nHits: {block.hits}\n" + label += "\n".join(str(inst) for inst in block.instructions) + dot.node(str(block.offset), label) + + # Add edges + for block in blocks.values(): + for next_block in block.next: + color = 'green' if ( + block.offset, next_block.offset) in taken_branches else 'red' + dot.edge(str(block.offset), str( + next_block.offset), color=color) + + # Save the visualization + dot.render(filename, view=True) + +# Example usage + + +def example_function(x: int) -> int: + if x > 0: + if x % 2 == 0: + return x * 2 + else: + return x * 3 + return x + + +# Create tracker and start tracking +tracker = CFGTracker() +tracker.start_tracking() + +# Run some test cases +example_function(4) +example_function(3) +example_function(0) + +# Stop tracking and get report +tracker.stop_tracking() +print(tracker.get_coverage_report(example_function.__code__)) + +# Visualize the CFG +tracker.visualize_cfg(example_function.__code__, 'example_cfg') From eaef2258e75679075523fcc47829675f0be8f9a8 Mon Sep 17 00:00:00 2001 From: Kellen Kanarios Date: Sat, 9 Nov 2024 10:36:36 -0500 Subject: [PATCH 13/84] gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index c7ba5080fd..4c0607f61e 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ .jac_mypy_cache/ +.envrc From 7268ee9934a7ba93fae8055716f6c0b0ab5488d6 Mon Sep 17 00:00:00 2001 From: Jakob Louis Therkelsen Date: Sat, 9 Nov 2024 12:35:38 -0500 Subject: [PATCH 14/84] updated examples --- jac/examples/ginsScripts/hot_path.jac | 1 - jac/examples/ginsScripts/simple.jac | 8 ++++ thread_example.py | 63 ++++++++++++++++----------- 3 files changed, 46 insertions(+), 26 deletions(-) create mode 100644 jac/examples/ginsScripts/simple.jac diff --git a/jac/examples/ginsScripts/hot_path.jac b/jac/examples/ginsScripts/hot_path.jac index b36d6f128d..a85a20ef36 100644 --- a/jac/examples/ginsScripts/hot_path.jac +++ b/jac/examples/ginsScripts/hot_path.jac @@ -1,4 +1,3 @@ - with entry { a = 0; b = 0; diff --git a/jac/examples/ginsScripts/simple.jac b/jac/examples/ginsScripts/simple.jac new file mode 100644 index 0000000000..20e38ee1db --- /dev/null +++ b/jac/examples/ginsScripts/simple.jac @@ -0,0 +1,8 @@ +with entry { + a=0; + x=0; + if x >= 0{ + a=1; + } + a=-1; +} \ No newline at end of file diff --git a/thread_example.py b/thread_example.py index ea935e8c9d..79886bab9c 100644 --- a/thread_example.py +++ b/thread_example.py @@ -1,25 +1,38 @@ -import threading -import os - -def task1(): - print("Task 1 assigned to thread: {}".format(threading.current_thread().name)) - print("ID of process running task 1: {}".format(os.getpid())) - -def task2(): - print("Task 2 assigned to thread: {}".format(threading.current_thread().name)) - print("ID of process running task 2: {}".format(os.getpid())) - -if __name__ == "__main__": - - print("ID of process running main program: {}".format(os.getpid())) - - print("Main thread name: {}".format(threading.current_thread().name)) - - t1 = threading.Thread(target=task1, name='t1') - t2 = threading.Thread(target=task2, name='t2') - - t1.start() - t2.start() - - t1.join() - t2.join() \ No newline at end of file +# program to display the functioning of +# settrace() +from sys import settrace + + +# local trace function which returns itself +def my_tracer(frame, event, arg = None): + # extracts frame code + code = frame.f_code + + # extracts calling function name + func_name = code.co_name + + # extracts the line number + line_no = frame.f_lineno + + print(f"A {event} encountered in {func_name}() at line number {line_no} ") + + return my_tracer + + +# global trace function is invoked here and +# local trace function is set for fun() +def fun(): + return "GFG" + + +# global trace function is invoked here and +# local trace function is set for check() +def check(): + return fun() + + +# returns reference to local +# trace function (my_tracer) +settrace(my_tracer) + +check() \ No newline at end of file From 7771a43b9e524edf481625ac8b5115b55266b014 Mon Sep 17 00:00:00 2001 From: Jakob Louis Therkelsen Date: Sat, 9 Nov 2024 14:12:03 -0500 Subject: [PATCH 15/84] adding cfg stuff based on article --- jac/examples/ginsScripts/hot_path.jac | 1 - jac/examples/ginsScripts/hot_path_cfg.png | Bin 0 -> 2396 bytes jac/examples/ginsScripts/simple_cfg.png | Bin 0 -> 2396 bytes .../passes/main/cfg_gen_pass_class_based.py | 274 ++++++++++++++++++ 4 files changed, 274 insertions(+), 1 deletion(-) create mode 100644 jac/examples/ginsScripts/hot_path_cfg.png create mode 100644 jac/examples/ginsScripts/simple_cfg.png create mode 100644 jac/jaclang/compiler/passes/main/cfg_gen_pass_class_based.py diff --git a/jac/examples/ginsScripts/hot_path.jac b/jac/examples/ginsScripts/hot_path.jac index a85a20ef36..29ff0eaa40 100644 --- a/jac/examples/ginsScripts/hot_path.jac +++ b/jac/examples/ginsScripts/hot_path.jac @@ -10,5 +10,4 @@ with entry { } a += 1; } - print("done"); } \ No newline at end of file diff --git a/jac/examples/ginsScripts/hot_path_cfg.png b/jac/examples/ginsScripts/hot_path_cfg.png new file mode 100644 index 0000000000000000000000000000000000000000..4a41ccf737239cd900842bc7d3acf0115365d6c9 GIT binary patch literal 2396 zcmeAS@N?(olHy`uVBq!ia0y~yU}|7sV0^&A1{5*9c;^X_vMh0pC<)F_D=AMbN@eg( zEGfvzFUiSFQYcF;D$dN$GuE@zGtyDWC@Co@w$j(ng)7j@FG|-}^kcpWG=#IjBeIx* zfj<$18CTdZ&tzcWIO*x)7*a9k?KMM21_ho21_$;(f5_CQ##L2z{)`R-gVDM7K%MuD z8W None: + """Before pass.""" + return super().before_pass() + + def enter_module(self, node: ast.Module) -> None: + """Sub objects. + + name: str, + doc: Token, + body: Optional['Elements'], + mod_path: str, + is_imported: bool, + sym_tab: Optional[SymbolTable], + """ + mods = [node] + self.get_all_sub_nodes(node, ast.Module) + module_cfgs = generate_module_cfg(mods) + # for module_name, cfg_graph in module_cfgs.items(): + # print(f"Control Flow Graph for {module_name}:") + # nx.draw(cfg_graph, with_labels=True) + # plt.title("Control Flow Graph") + # plt.show() + # plt.savefig(f"{module_name}_cfg.png") + +class BytecodeOp: + def __init__(self, index: int, op: int, arg: int) -> None: + self.idx = index + self.op = op + self.arg = arg + + def next_instr_idx(self) -> int: + return self.idx + 1 + def next_instr_offset(self) -> int: + return self.next_instr_idx() * CODEUNIT_SIZE + def __repr__(self): + return f"{self.idx}: f{self.op} - {self.arg}" + def is_branch(self) -> bool: + return self.op in { + #"FOR_ITER", + #"JUMP_ABSOLUTE", + "JUMP_FORWARD", + "POP_JUMP_IF_TRUE", + "POP_JUMP_IF_FALSE", + "JUMP_IF_TRUE_OR_POP", + "JUMP_IF_FALSE_OR_POP", + } + def is_relative_branch(self) -> bool: + return self.op in { + "FOR_ITER", + "JUMP_FORWARD", + } + def next_instr_idx(self) -> int: + return self.idx+1 + def next_instr_offset(self) -> int: + return self.next_instr_idx()*CODEUNIT_SIZE + + def jump_target(self) -> int: + if self.is_relative_branch(): + return self.next_instr_offset() + self.arg + return self.arg + def jump_target_idx(self) -> int: + return self.jump_target() // CODEUNIT_SIZE + + def is_return(self) -> bool: + return self.op == "RETURN_VALUE" + + def is_raise(self) -> bool: + return self.op == "RAISE_VARARGS" + +class BytecodeSlice: + """A slice of bytecode from [start, end).""" + + def __init__( + self, + bytecode: List[BytecodeOp], + start: Optional[int] = None, + end: Optional[int] = None, + ) -> None: + self.bytecode = bytecode + self.start: int = 0 if start is None else start + self.end: int = len(bytecode) if end is None else end + + def __repr__(self) -> str: + return f"" + def size(self) -> int: + return self.end - self.start + def __iter__(self) -> Iterator[BytecodeOp]: + return iter(self.bytecode[self.start : self.end]) + +class Block: + def __init__(self, id: int, bytecode: BytecodeSlice): + self.id: int = id + self.bytecode: BytecodeSlice = bytecode + +class BlockMap: + def __init__(self) -> None: + self.idx_to_block: Dict[int, Block] = {} + + def add_block(self, idx, block): + self.idx_to_block[idx] = block + + def __repr__(self) -> str: + result = [] + for block in self.idx_to_block.values(): + result.append(f"bb{block.id}:") + for instr in block.bytecode: + if instr.is_branch(): + target_idx = instr.jump_target_idx() + target = self.idx_to_block[target_idx] + result.append(f" {instr.op} bb{target.id}") + else: + result.append(f" {instr}") + return "\n".join(result) + def __str__(self) -> str: + return self.__repr__() + +def disassemble_bytecode(bytecode): + code_object = marshal.loads(bytecode) + instructions = [] + for i, instr in enumerate(dis.get_instructions(code_object)): + instructions.append(BytecodeOp(i,instr.opname, instr.arg)) + return instructions + +def create_BBs(instructions: BytecodeSlice) -> BlockMap: + block_starts = set([0]) + block_map = BlockMap() + num_instr = instructions.size() + for instr in instructions: + if instr.is_branch(): + block_starts.add(instr.next_instr_idx()) + block_starts.add(instr.jump_target_idx()) + elif instr.is_return(): + next_instr_idx = instr.next_instr_idx() + if next_instr_idx < num_instr: + block_starts.add(next_instr_idx) + elif instr.is_raise(): + block_starts.add(instr.next_instr_idx()) + + block_starts_ordered = list(sorted(block_starts)) + + block_count = len(block_starts) + + for i, start_idx in enumerate(block_starts_ordered): + print(i) + end_idx = block_starts_ordered[i + 1] if i + 1 < block_count else num_instr + print(f"{start_idx}:{end_idx}") + block_instrs = BytecodeSlice(instructions.bytecode, start_idx, end_idx) + block_map.add_block(start_idx, Block(i, block_instrs)) + return block_map + + + +def extract_cfg_from_instructions(instructions): + cfg = defaultdict(list) + current_block = [] + block_id = 0 + block_map = {} # Maps instruction offsets to blocks + edges = {} + + for instr in instructions: + current_block.append(instr) + if instr.opname in { + "JUMP_ABSOLUTE", + "JUMP_FORWARD", + "POP_JUMP_IF_TRUE", + "POP_JUMP_IF_FALSE", + "JUMP_IF_TRUE_OR_POP", + "JUMP_IF_FALSE_OR_POP", + }: + cfg[block_id] = current_block + block_map[instr.offset] = block_id + target = ( + instr.offset + instr.argval + 2 + if instr.opname == "JUMP_FORWARD" + else instr.argval + ) + edges[block_id] = target + block_id += 1 + + # Update edges to use block numbers instead of offsets + for block_id, target_offset in edges.items(): + if target_offset in block_map: + edges[block_id] = block_map[target_offset] + else: + print(f"Warning: Target offset {target_offset} not found in block_map") + return cfg, block_map, edges + + +def build_cfg_graph(cfg, block_map, edges): + graph = nx.DiGraph() + + for block_id, instructions in cfg.items(): + print(f"Block ID {block_id}:") + print( + "\n".join( + [ + f"{instr.offset}: {instr.opname} {instr.argval}" + for instr in instructions + ] + ) + ) + graph.add_node(block_id, instructions=instructions) + last_instruction = instructions[-1] if instructions else None + + # Verify last_instruction is valid and has 'opname' attribute + if last_instruction and hasattr(last_instruction, "opname"): + if ( + "JUMP" in last_instruction.opname + and last_instruction.argval in block_map + ): + target_block = block_map[last_instruction.offset] + graph.add_edge(block_id, target_block) + else: + print( + f"Warning: Block ID {block_id} does not have a valid jump target or last instruction" + ) + return graph + + +def generate_module_cfg(modules): + module_cfgs = {} + for mod in modules: + bytecode = mod.gen.py_bytecode + instructions = disassemble_bytecode(bytecode) + bytecode_slice = BytecodeSlice(instructions) + BBs = create_BBs(bytecode_slice) + #cfg, block_map, edges = extract_cfg_from_instructions(instructions) + #module_cfgs[mod.name] = build_cfg_graph(cfg, block_map, edges) + #return module_cfgs + + +# Compile the simple function `decisions` +source_code = """ +def f(x): + if x: + y = 1 + else: + y = 2 + return y +""" +compiled_code = compile(source_code, filename="", mode="exec") + +# Extract the code object of the `decisions` function +decisions_code = compiled_code.co_consts[0] # The first constant is the code object + +# Serialize the bytecode of the function +serialized_bytecode = marshal.dumps(decisions_code) + +# Disassemble the serialized bytecode +disassembled_instructions = disassemble_bytecode(serialized_bytecode) +bytecode_slice = BytecodeSlice(disassembled_instructions) +print(bytecode_slice) + +# Generate and print basic blocks +BBs = create_BBs(bytecode_slice) +print(BBs) From 6ddea8529ab2358cb7ea3cab9e1f874f37245ebf Mon Sep 17 00:00:00 2001 From: Jakob Louis Therkelsen Date: Sun, 10 Nov 2024 17:53:43 -0500 Subject: [PATCH 16/84] vizualizing hot_path.jac --- cfg.gv | 20 +++++ cfg.gv.pdf | Bin 0 -> 11975 bytes cfg.py | 221 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 241 insertions(+) create mode 100644 cfg.gv create mode 100644 cfg.gv.pdf create mode 100644 cfg.py diff --git a/cfg.gv b/cfg.gv new file mode 100644 index 0000000000..0774a4c90f --- /dev/null +++ b/cfg.gv @@ -0,0 +1,20 @@ +// Control Flow Graph +digraph { + bb0 [label=BB0] + bb1 [label=BB1] + bb2 [label=BB2] + bb3 [label=BB3] + bb4 [label=BB4] + bb5 [label=BB5] + bb6 [label=BB6] + bb7 [label=BB7] + bb0 -> bb7 + bb0 -> bb1 + bb1 -> bb3 + bb1 -> bb2 + bb3 -> bb4 + bb4 -> bb6 + bb4 -> bb5 + bb5 -> bb1 + bb6 -> bb7 +} diff --git a/cfg.gv.pdf b/cfg.gv.pdf new file mode 100644 index 0000000000000000000000000000000000000000..e7bc8ecac30e14f6bac00898adb0564730166095 GIT binary patch literal 11975 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 None: + self.op = op + self.arg = arg + self.offset = offset + self.argval = argval + self.is_jump_target= is_jump_target + + def __repr__(self): + return f"{self.offset}: f{self.op} - {self.arg} - {self.argval}" + def is_branch(self) -> bool: + return self.op in { + "JUMP_ABSOLUTE", + "JUMP_FORWARD", + "POP_JUMP_IF_TRUE", + "POP_JUMP_IF_FALSE", + "JUMP_IF_TRUE_OR_POP", + "JUMP_IF_FALSE_OR_POP", + } + def is_relative_branch(self) -> bool: + return self.op in { + "FOR_ITER", + "JUMP_FORWARD", + } + def is_return(self) -> bool: + return self.op == "RETURN_VALUE" + + def is_raise(self) -> bool: + return self.op == "RAISE_VARARGS" + +class Block: + def __init__(self, id: int, instructions: List): + self.id: int = id + self.instructions = instructions + def __repr__(self): + instructions = "\n".join([str(instr) for instr in self.instructions]) + return f"bb{self.id}:\n{instructions}" + +class BlockMap: + def __init__(self) -> None: + self.idx_to_block: Dict[int, Block] = {} + + def add_block(self, idx, block): + self.idx_to_block[idx] = block + + def __repr__(self) -> str: + result = [] + for block in self.idx_to_block.values(): + result.append(repr(block)) + return "\n".join(result) + def __str__(self) -> str: + return self.__repr__() + +def disassemble_bytecode(bytecode): + code_object = marshal.loads(bytecode) + instructions = [] + for i, instr in enumerate(dis.get_instructions(code_object)): + instructions.append(BytecodeOp( + op = instr.opname, + arg=instr.arg, + offset=instr.offset, + argval=instr.argval, + is_jump_target=instr.is_jump_target + )) + print(instr) + return instructions + +def create_BBs(instructions: List[BytecodeOp]) -> BlockMap: + block_starts = set([0]) + block_map = BlockMap() + num_instr = len(instructions) + + # Create offset to index mapping + offset_to_index = {instr.offset: idx for idx, instr in enumerate(instructions)} + max_offset = instructions[-1].offset + CODEUNIT_SIZE + print(f"Offset to Index Mapping: {offset_to_index}") + + def valid_offset(offset): + return offset >= 0 and offset <= max_offset + # Identify all block starts + for instr in instructions: + if instr.is_branch(): + next_instr_offset = instr.offset + CODEUNIT_SIZE + if valid_offset(next_instr_offset): + block_starts.add(next_instr_offset) + + if instr.is_relative_branch(): + target_offset = instr.offset + instr.argval + else: + target_offset = instr.argval + + if valid_offset(target_offset): + block_starts.add(target_offset) + + if instr.is_jump_target: + block_starts.add(instr.offset) + + block_starts_ordered = sorted(block_starts) + print(f"Identified block starts: {block_starts_ordered}") + + for block_id, start_offset in enumerate(block_starts_ordered): + end_offset = block_starts_ordered[block_id + 1] if block_id + 1 < len(block_starts_ordered) else instructions[-1].offset + CODEUNIT_SIZE + start_index = offset_to_index[start_offset] + end_index = num_instr + + # Find the corresponding end_index + for offset in block_starts_ordered: + if offset > start_offset: + end_index = offset_to_index[offset] + break + + # Collect instructions for this block + block_instrs = instructions[start_index:end_index] + block_map.add_block(block_id, Block(block_id, block_instrs)) + + return block_map + + +class CFG: + def __init__(self): + self.nodes = set() + self.edges = {} + + def add_node(self, node_id): + self.nodes.add(node_id) + if node_id not in self.edges: + self.edges[node_id] = [] + + def add_edge(self, from_node, to_node): + if from_node in self.edges: + self.edges[from_node].append(to_node) + else: + self.edges[from_node] = [to_node] + + def __repr__(self): + result = [] + for node in self.nodes: + result.append(f'Node bb{node}:') + if node in self.edges and self.edges[node]: + for succ in self.edges[node]: + result.append(f' -> bb{succ}') + return "\n".join(result) +def create_cfg(block_map: BlockMap) -> CFG: + cfg = CFG() + + for block_id, block in block_map.idx_to_block.items(): + cfg.add_node(block_id) + + last_instr = block.instructions[-1] + + # Handle conditional jumps (e.g., POP_JUMP_IF_FALSE) + if last_instr.is_branch(): + target_offset = last_instr.argval if not last_instr.is_relative_branch() else (last_instr.offset + last_instr.argval) + target_block = find_block_by_offset(block_map, target_offset) + if target_block is not None: + cfg.add_edge(block_id, target_block) + # Fall-through to next block if it's a conditional branch + if last_instr.op.startswith('POP_JUMP_IF'): + fall_through_offset = block.instructions[-1].offset + CODEUNIT_SIZE + fall_through_block = find_block_by_offset(block_map, fall_through_offset) + if fall_through_block is not None: + cfg.add_edge(block_id, fall_through_block) + + # Handle unconditional jumps (e.g., JUMP_FORWARD, JUMP_ABSOLUTE) + elif last_instr.op.startswith("JUMP"): + target_offset = last_instr.argval if not last_instr.is_relative_branch() else (last_instr.offset + last_instr.argval) + target_block = find_block_by_offset(block_map, target_offset) + if target_block is not None: + cfg.add_edge(block_id, target_block) + + # Handle fall-through to the next block for non-control flow instructions + else: + fall_through_offset = block.instructions[-1].offset + CODEUNIT_SIZE + fall_through_block = find_block_by_offset(block_map, fall_through_offset) + if fall_through_block is not None: + cfg.add_edge(block_id, fall_through_block) + + return cfg + +def find_block_by_offset(block_map: BlockMap, offset: int) -> int: + for block_id, block in block_map.idx_to_block.items(): + if any(instr.offset == offset for instr in block.instructions): + return block_id + return None + +# Function to visualize CFG using Graphviz +def visualize_cfg(cfg: CFG): + dot = Digraph(comment="Control Flow Graph") + for node in cfg.nodes: + dot.node(f"bb{node}", f"BB{node}") + for from_node, to_nodes in cfg.edges.items(): + for to_node in to_nodes: + dot.edge(f"bb{from_node}", f"bb{to_node}") + return dot + +# Sample list of instructions for processing +##simple= +# instructions = disassemble_bytecode(b'c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x01\xf3*\x00\x00\x00\x97\x00d\x00d\x01l\x00m\x01Z\x01\x01\x00d\x00Z\x02d\x00Z\x03e\x03d\x00k\\\x00\x00r\x02d\x02Z\x02d\x03Z\x02y\x04)\x05\xe9\x00\x00\x00\x00)\x01\xda\x0bannotations\xe9\x01\x00\x00\x00\xe9\xff\xff\xff\xffN)\x04\xda\n__future__r\x02\x00\x00\x00\xda\x01a\xda\x01x\xa9\x00\xf3\x00\x00\x00\x00\xfaP/Users/jakobtherkelsen/Documents/jaseci-ginS/jac/examples/ginsScripts/simple.jac\xfa\x08r\x0b\x00\x00\x00\x01\x00\x00\x00s%\x00\x00\x00\xf0\x03\x01\x01\x01\xf5\x02\x07\x02\x03\xd8\x05\x06\x801\xd8\x05\x06\x801\xd8\x06\x07\x881\x82f\xd8\x07\x08\x80Q\xe0\x05\x07\x811r\t\x00\x00\x00') +#hot path +instructions = disassemble_bytecode(b'c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x01\xf3T\x00\x00\x00\x97\x00d\x00d\x01l\x00m\x01Z\x01\x01\x00d\x00Z\x02d\x00Z\x03e\x02d\x02k\x02\x00\x00r\x19e\x02d\x03z\x06\x00\x00d\x00k(\x00\x00r\x03d\x04Z\x03n\x02d\x03Z\x03e\x02d\x04z\r\x00\x00Z\x02e\x02d\x02k\x02\x00\x00r\x01\x8c\x18y\x05y\x05)\x06\xe9\x00\x00\x00\x00)\x01\xda\x0bannotations\xe9\x0f\x00\x00\x00\xe9\x02\x00\x00\x00\xe9\x01\x00\x00\x00N)\x04\xda\n__future__r\x02\x00\x00\x00\xda\x01a\xda\x01b\xa9\x00\xf3\x00\x00\x00\x00\xfaR/Users/jakobtherkelsen/Documents/jaseci-ginS/jac/examples/ginsScripts/hot_path.jac\xfa\x08r\x0c\x00\x00\x00\x01\x00\x00\x00sD\x00\x00\x00\xf0\x03\x01\x01\x01\xf5\x02\x0c\x02\x03\xd8\x07\x08\x801\xd8\x07\x08\x801\xd8\t\n\x88R\x8a\x16\xd8\x08\t\x88A\x89\x05\x90\x11\x8a\n\xd8\x0b\x0c\x81q\xf0\x06\x00\x0c\r\x80q\xe0\x05\x06\x88!\x81W\x80Q\xf0\x0f\x00\n\x0b\x88R\x8d\x16r\n\x00\x00\x00') +BBs = create_BBs(instructions) +print(BBs) + +cfg = create_cfg(BBs) +print("\nControl Flow Graph (CFG):") +print(cfg) + +# Visualize CFG +dot = visualize_cfg(cfg) +dot.render('cfg.gv', view=True) \ No newline at end of file From f17ed65b5ff3c84552f8af9d8f45dd60513243af Mon Sep 17 00:00:00 2001 From: Jakob Louis Therkelsen Date: Fri, 15 Nov 2024 13:40:41 -0500 Subject: [PATCH 17/84] remove code --- cfg.gv.pdf | Bin 11975 -> 11975 bytes cfg.py | 22 ++++++++++-------- .../compiler/passes/main/cfg_gen_pass.py | 3 +++ test_ai.py | 7 ++++++ 4 files changed, 22 insertions(+), 10 deletions(-) create mode 100644 test_ai.py diff --git a/cfg.gv.pdf b/cfg.gv.pdf index e7bc8ecac30e14f6bac00898adb0564730166095..e1f747ab44aefba9c2956f4e7d7f5b3f995e6529 100644 GIT binary patch delta 289 zcmV++0p9+{UB_Lpk}Q9*YQr!PhIc*1zmz6JV@bA?G?)yrA(T=GNw?BLD2HPxmXYMr zynQ7nb}5?f<4*r~oB(HHiJUVDkqahPNLLvv3MB8>j*uKwO^yLbUYoPS2P8O-_#9Aa z`qo3R?RJc)wd<^;1!b6CT^9N-qdPK7UywSN)JM$BCd3bW2BU>#e>DGsK zhivNKThn(aide+@mNC!~odUJ0bzRKT*Ac(K+n&a%3|$p{H=2(7U4+3o@*_FZTTKq> nlz9q++TYY&xWW{_^-AT{m#OdDg$vx53r)W-9&X>Wq%9)>O2Ca$ delta 289 zcmV++0p9+{UB_Lpk}QA0YQr!PMDPBJxs*DG+FHeqLohkShEPf&B)OFyge)9Gv5X{_ z=I<*xaZ1r?AG4YnmcSxfA!iW>Y0S<;EJ||S^ zv3HK(V&FZ2}gW!Zm^p)ooH*saOtE?v}u1Ai`zFw3D@bq7EU3q zH=OZ|h!_?5lG6*zpBY=sCV#Q;Q%ytFWuhT`3v03dC@N_-fr8oq%9)>@u-dG diff --git a/cfg.py b/cfg.py index 4ec3448849..7df443353b 100644 --- a/cfg.py +++ b/cfg.py @@ -1,13 +1,18 @@ """Genrate a control flow graph from genarated bytecode. This pass generates a control flow graph from the bytecode generated by the previous pass. + +Code was initially inspired by: +https://bernsteinbear.com/blog/discovering-basic-blocks/ + +The rest was extended to handle some nuance and edge conditions that were not considered. """ import marshal import dis from collections import defaultdict from typing import List, Optional, Iterator -import graphviz -from graphviz import Digraph +#import graphviz +#from graphviz import Digraph CODEUNIT_SIZE = 2 class BytecodeOp: def __init__(self, op: int, arg: int, offset: int, argval:int, is_jump_target: bool) -> None: @@ -73,7 +78,6 @@ def disassemble_bytecode(bytecode): argval=instr.argval, is_jump_target=instr.is_jump_target )) - print(instr) return instructions def create_BBs(instructions: List[BytecodeOp]) -> BlockMap: @@ -84,7 +88,6 @@ def create_BBs(instructions: List[BytecodeOp]) -> BlockMap: # Create offset to index mapping offset_to_index = {instr.offset: idx for idx, instr in enumerate(instructions)} max_offset = instructions[-1].offset + CODEUNIT_SIZE - print(f"Offset to Index Mapping: {offset_to_index}") def valid_offset(offset): return offset >= 0 and offset <= max_offset @@ -107,10 +110,9 @@ def valid_offset(offset): block_starts.add(instr.offset) block_starts_ordered = sorted(block_starts) - print(f"Identified block starts: {block_starts_ordered}") + for block_id, start_offset in enumerate(block_starts_ordered): - end_offset = block_starts_ordered[block_id + 1] if block_id + 1 < len(block_starts_ordered) else instructions[-1].offset + CODEUNIT_SIZE start_index = offset_to_index[start_offset] end_index = num_instr @@ -206,9 +208,9 @@ def visualize_cfg(cfg: CFG): # Sample list of instructions for processing ##simple= -# instructions = disassemble_bytecode(b'c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x01\xf3*\x00\x00\x00\x97\x00d\x00d\x01l\x00m\x01Z\x01\x01\x00d\x00Z\x02d\x00Z\x03e\x03d\x00k\\\x00\x00r\x02d\x02Z\x02d\x03Z\x02y\x04)\x05\xe9\x00\x00\x00\x00)\x01\xda\x0bannotations\xe9\x01\x00\x00\x00\xe9\xff\xff\xff\xffN)\x04\xda\n__future__r\x02\x00\x00\x00\xda\x01a\xda\x01x\xa9\x00\xf3\x00\x00\x00\x00\xfaP/Users/jakobtherkelsen/Documents/jaseci-ginS/jac/examples/ginsScripts/simple.jac\xfa\x08r\x0b\x00\x00\x00\x01\x00\x00\x00s%\x00\x00\x00\xf0\x03\x01\x01\x01\xf5\x02\x07\x02\x03\xd8\x05\x06\x801\xd8\x05\x06\x801\xd8\x06\x07\x881\x82f\xd8\x07\x08\x80Q\xe0\x05\x07\x811r\t\x00\x00\x00') +instructions = disassemble_bytecode(b'c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x01\xf3*\x00\x00\x00\x97\x00d\x00d\x01l\x00m\x01Z\x01\x01\x00d\x00Z\x02d\x00Z\x03e\x03d\x00k\\\x00\x00r\x02d\x02Z\x02d\x03Z\x02y\x04)\x05\xe9\x00\x00\x00\x00)\x01\xda\x0bannotations\xe9\x01\x00\x00\x00\xe9\xff\xff\xff\xffN)\x04\xda\n__future__r\x02\x00\x00\x00\xda\x01a\xda\x01x\xa9\x00\xf3\x00\x00\x00\x00\xfaP/Users/jakobtherkelsen/Documents/jaseci-ginS/jac/examples/ginsScripts/simple.jac\xda\x08r\x0b\x00\x00\x00\x01\x00\x00\x00s%\x00\x00\x00\xf0\x03\x01\x01\x01\xf5\x02\x07\x02\x03\xd8\x05\x06\x801\xd8\x05\x06\x801\xd8\x06\x07\x881\x82f\xd8\x07\x08\x80Q\xe0\x05\x07\x811r\t\x00\x00\x00') #hot path -instructions = disassemble_bytecode(b'c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x01\xf3T\x00\x00\x00\x97\x00d\x00d\x01l\x00m\x01Z\x01\x01\x00d\x00Z\x02d\x00Z\x03e\x02d\x02k\x02\x00\x00r\x19e\x02d\x03z\x06\x00\x00d\x00k(\x00\x00r\x03d\x04Z\x03n\x02d\x03Z\x03e\x02d\x04z\r\x00\x00Z\x02e\x02d\x02k\x02\x00\x00r\x01\x8c\x18y\x05y\x05)\x06\xe9\x00\x00\x00\x00)\x01\xda\x0bannotations\xe9\x0f\x00\x00\x00\xe9\x02\x00\x00\x00\xe9\x01\x00\x00\x00N)\x04\xda\n__future__r\x02\x00\x00\x00\xda\x01a\xda\x01b\xa9\x00\xf3\x00\x00\x00\x00\xfaR/Users/jakobtherkelsen/Documents/jaseci-ginS/jac/examples/ginsScripts/hot_path.jac\xfa\x08r\x0c\x00\x00\x00\x01\x00\x00\x00sD\x00\x00\x00\xf0\x03\x01\x01\x01\xf5\x02\x0c\x02\x03\xd8\x07\x08\x801\xd8\x07\x08\x801\xd8\t\n\x88R\x8a\x16\xd8\x08\t\x88A\x89\x05\x90\x11\x8a\n\xd8\x0b\x0c\x81q\xf0\x06\x00\x0c\r\x80q\xe0\x05\x06\x88!\x81W\x80Q\xf0\x0f\x00\n\x0b\x88R\x8d\x16r\n\x00\x00\x00') +#instructions = disassemble_bytecode(b'c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x01\xf3T\x00\x00\x00\x97\x00d\x00d\x01l\x00m\x01Z\x01\x01\x00d\x00Z\x02d\x00Z\x03e\x02d\x02k\x02\x00\x00r\x19e\x02d\x03z\x06\x00\x00d\x00k(\x00\x00r\x03d\x04Z\x03n\x02d\x03Z\x03e\x02d\x04z\r\x00\x00Z\x02e\x02d\x02k\x02\x00\x00r\x01\x8c\x18y\x05y\x05)\x06\xe9\x00\x00\x00\x00)\x01\xda\x0bannotations\xe9\x0f\x00\x00\x00\xe9\x02\x00\x00\x00\xe9\x01\x00\x00\x00N)\x04\xda\n__future__r\x02\x00\x00\x00\xda\x01a\xda\x01b\xa9\x00\xf3\x00\x00\x00\x00\xfaR/Users/jakobtherkelsen/Documents/jaseci-ginS/jac/examples/ginsScripts/hot_path.jac\xfa\x08r\x0c\x00\x00\x00\x01\x00\x00\x00sD\x00\x00\x00\xf0\x03\x01\x01\x01\xf5\x02\x0c\x02\x03\xd8\x07\x08\x801\xd8\x07\x08\x801\xd8\t\n\x88R\x8a\x16\xd8\x08\t\x88A\x89\x05\x90\x11\x8a\n\xd8\x0b\x0c\x81q\xf0\x06\x00\x0c\r\x80q\xe0\x05\x06\x88!\x81W\x80Q\xf0\x0f\x00\n\x0b\x88R\x8d\x16r\n\x00\x00\x00') BBs = create_BBs(instructions) print(BBs) @@ -217,5 +219,5 @@ def visualize_cfg(cfg: CFG): print(cfg) # Visualize CFG -dot = visualize_cfg(cfg) -dot.render('cfg.gv', view=True) \ No newline at end of file +# dot = visualize_cfg(cfg) +# dot.render('cfg.gv', view=True) \ No newline at end of file diff --git a/jac/jaclang/compiler/passes/main/cfg_gen_pass.py b/jac/jaclang/compiler/passes/main/cfg_gen_pass.py index 142a50fc50..91ffec7ecc 100644 --- a/jac/jaclang/compiler/passes/main/cfg_gen_pass.py +++ b/jac/jaclang/compiler/passes/main/cfg_gen_pass.py @@ -9,6 +9,7 @@ from collections import defaultdict import networkx as nx import matplotlib.pyplot as plt +import sys import jaclang.compiler.absyntree as ast @@ -126,6 +127,8 @@ def generate_module_cfg(modules): module_cfgs = {} for mod in modules: bytecode = mod.gen.py_bytecode + print(bytecode) + print(sys.version) instructions = disassemble_bytecode(bytecode) cfg, block_map, edges = extract_cfg_from_instructions(instructions) module_cfgs[mod.name] = build_cfg_graph(cfg, block_map, edges) diff --git a/test_ai.py b/test_ai.py new file mode 100644 index 0000000000..1e0217c1dc --- /dev/null +++ b/test_ai.py @@ -0,0 +1,7 @@ +import google.generativeai as genai +import os + +genai.configure(api_key="AIzaSyAU24V8wy2H7JihQvceZMiKIIBzr5Nqulc") +model = genai.GenerativeModel("gemini-1.5-flash") +response = model.generate_content("Write another") +print(response.text) \ No newline at end of file From cd217b1267450cd625ed55ae8950662b65d7a3d6 Mon Sep 17 00:00:00 2001 From: jayanaka-98 Date: Fri, 15 Nov 2024 15:26:01 -0500 Subject: [PATCH 18/84] CFG pass --- .../compiler/passes/main/cfg_gen_pass.py | 228 +++++++++-------- jac/jaclang/runtimelib/cfg.py | 233 ++++++++++++++++++ jac/jaclang/runtimelib/machine.py | 2 +- 3 files changed, 356 insertions(+), 107 deletions(-) create mode 100644 jac/jaclang/runtimelib/cfg.py diff --git a/jac/jaclang/compiler/passes/main/cfg_gen_pass.py b/jac/jaclang/compiler/passes/main/cfg_gen_pass.py index 91ffec7ecc..ef2d0899d1 100644 --- a/jac/jaclang/compiler/passes/main/cfg_gen_pass.py +++ b/jac/jaclang/compiler/passes/main/cfg_gen_pass.py @@ -3,17 +3,18 @@ This pass generates a control flow graph from the bytecode generated by the previous pass. """ -import ast as ast3 -import marshal -import dis -from collections import defaultdict -import networkx as nx -import matplotlib.pyplot as plt -import sys +import ast +# import marshal +# import dis +# from collections import defaultdict +# import networkx as nx +# import matplotlib.pyplot as plt import jaclang.compiler.absyntree as ast from jaclang.compiler.passes import Pass +from jaclang.runtimelib.cfg import visualize_cfg, disassemble_bytecode, create_BBs, create_cfg +from jaclang.runtimelib.machine import JacMachine class CfgGenPass(Pass): @@ -34,102 +35,117 @@ def enter_module(self, node: ast.Module) -> None: sym_tab: Optional[SymbolTable], """ mods = [node] + self.get_all_sub_nodes(node, ast.Module) - module_cfgs = generate_module_cfg(mods) - for module_name, cfg_graph in module_cfgs.items(): - print(f"Control Flow Graph for {module_name}:") - nx.draw(cfg_graph, with_labels=True) - plt.title("Control Flow Graph") - plt.show() - plt.savefig(f"{module_name}_cfg.png") - - -def disassemble_bytecode(bytecode): - code_object = marshal.loads(bytecode) - instructions = list(dis.get_instructions(code_object)) - print(f"Disassembled bytecode for {code_object.co_name}:") - print( - "\n".join( - [f"{instr.offset}: {instr.opname} {instr.argval}" for instr in instructions] - ) - ) - return instructions - - -def extract_cfg_from_instructions(instructions): - cfg = defaultdict(list) - current_block = [] - block_id = 0 - block_map = {} # Maps instruction offsets to blocks - edges = {} - - for instr in instructions: - current_block.append(instr) - if instr.opname in { - "JUMP_ABSOLUTE", - "JUMP_FORWARD", - "POP_JUMP_IF_TRUE", - "POP_JUMP_IF_FALSE", - "JUMP_IF_TRUE_OR_POP", - "JUMP_IF_FALSE_OR_POP", - }: - cfg[block_id] = current_block - block_map[instr.offset] = block_id - target = ( - instr.offset + instr.argval + 2 - if instr.opname == "JUMP_FORWARD" - else instr.argval - ) - edges[block_id] = target - block_id += 1 - - # Update edges to use block numbers instead of offsets - for block_id, target_offset in edges.items(): - if target_offset in block_map: - edges[block_id] = block_map[target_offset] - else: - print(f"Warning: Target offset {target_offset} not found in block_map") - print(edges) - return cfg, block_map, edges - - -def build_cfg_graph(cfg, block_map, edges): - graph = nx.DiGraph() - - for block_id, instructions in cfg.items(): - print(f"Block ID {block_id}:") - print( - "\n".join( - [ - f"{instr.offset}: {instr.opname} {instr.argval}" - for instr in instructions - ] - ) - ) - graph.add_node(block_id, instructions=instructions) - last_instruction = instructions[-1] if instructions else None - - # Verify last_instruction is valid and has 'opname' attribute - if last_instruction and hasattr(last_instruction, "opname"): - if ( - "JUMP" in last_instruction.opname - and last_instruction.argval in block_map - ): - target_block = block_map[last_instruction.offset] - graph.add_edge(block_id, target_block) - else: - print( - f"Warning: Block ID {block_id} does not have a valid jump target or last instruction" - ) - return graph - - -def generate_module_cfg(modules): - module_cfgs = {} - for mod in modules: - bytecode = mod.gen.py_bytecode - print(bytecode) - print(sys.version) - instructions = disassemble_bytecode(bytecode) - cfg, block_map, edges = extract_cfg_from_instructions(instructions) - module_cfgs[mod.name] = build_cfg_graph(cfg, block_map, edges) - return module_cfgs + module_cfgs = {} + for mod in mods: + bytecode = mod.gen.py_bytecode + instructions = disassemble_bytecode(bytecode) + BBs = create_BBs(instructions) + cfg = create_cfg(BBs) + module_cfgs[mod.name] = cfg + for cfg in module_cfgs.values(): + dot = visualize_cfg(cfg) + print(dot) + dot.render('cfg.gv', view=True) + + + + + + # cfg, block_map, edges = extract_cfg_from_instructions(instructions) + # module_cfgs[mod.name] = build_cfg_graph(cfg, block_map, edges) + # for module_name, cfg_graph in module_cfgs.items(): + # print(f"Control Flow Graph for {module_name}:") + # nx.draw(cfg_graph, with_labels=True) + # plt.title("Control Flow Graph") + # plt.show() + # plt.savefig(f"{module_name}_cfg.png") + + +# def disassemble_bytecode(bytecode): +# code_object = marshal.loads(bytecode) +# instructions = list(dis.get_instructions(code_object)) +# print(f"Disassembled bytecode for {code_object.co_name}:") +# print( +# "\n".join( +# [f"{instr.offset}: {instr.opname} {instr.argval}" for instr in instructions] +# ) +# ) +# return instructions + + +# def extract_cfg_from_instructions(instructions): +# cfg = defaultdict(list) +# current_block = [] +# block_id = 0 +# block_map = {} # Maps instruction offsets to blocks +# edges = {} + +# for instr in instructions: +# current_block.append(instr) +# if instr.opname in { +# "JUMP_ABSOLUTE", +# "JUMP_FORWARD", +# "POP_JUMP_IF_TRUE", +# "POP_JUMP_IF_FALSE", +# "JUMP_IF_TRUE_OR_POP", +# "JUMP_IF_FALSE_OR_POP", +# }: +# cfg[block_id] = current_block +# block_map[instr.offset] = block_id +# target = ( +# instr.offset + instr.argval + 2 +# if instr.opname == "JUMP_FORWARD" +# else instr.argval +# ) +# edges[block_id] = target +# block_id += 1 + +# # Update edges to use block numbers instead of offsets +# for block_id, target_offset in edges.items(): +# if target_offset in block_map: +# edges[block_id] = block_map[target_offset] +# else: +# print(f"Warning: Target offset {target_offset} not found in block_map") +# print(edges) +# return cfg, block_map, edges + + +# def build_cfg_graph(cfg, block_map, edges): +# graph = nx.DiGraph() + +# for block_id, instructions in cfg.items(): +# print(f"Block ID {block_id}:") +# print( +# "\n".join( +# [ +# f"{instr.offset}: {instr.opname} {instr.argval}" +# for instr in instructions +# ] +# ) +# ) +# graph.add_node(block_id, instructions=instructions) +# last_instruction = instructions[-1] if instructions else None + +# # Verify last_instruction is valid and has 'opname' attribute +# if last_instruction and hasattr(last_instruction, "opname"): +# if ( +# "JUMP" in last_instruction.opname +# and last_instruction.argval in block_map +# ): +# target_block = block_map[last_instruction.offset] +# graph.add_edge(block_id, target_block) +# else: +# print( +# f"Warning: Block ID {block_id} does not have a valid jump target or last instruction" +# ) +# return graph + + +# def generate_module_cfg(modules): +# module_cfgs = {} +# for mod in modules: +# bytecode = mod.gen.py_bytecode +# instructions = disassemble_bytecode(bytecode) +# cfg, block_map, edges = extract_cfg_from_instructions(instructions) +# module_cfgs[mod.name] = build_cfg_graph(cfg, block_map, edges) +# return module_cfgs diff --git a/jac/jaclang/runtimelib/cfg.py b/jac/jaclang/runtimelib/cfg.py new file mode 100644 index 0000000000..9c0a71c361 --- /dev/null +++ b/jac/jaclang/runtimelib/cfg.py @@ -0,0 +1,233 @@ +"""Genrate a control flow graph from genarated bytecode. + +This pass generates a control flow graph from the bytecode generated by the previous pass. +""" +import marshal +import dis +from collections import defaultdict +from typing import List, Optional, Iterator +import graphviz +from graphviz import Digraph + +CODEUNIT_SIZE = 2 +class BytecodeOp: + def __init__(self, op: int, arg: int, offset: int, argval:int, is_jump_target: bool) -> None: + self.op = op + self.arg = arg + self.offset = offset + self.argval = argval + self.is_jump_target= is_jump_target + + def __repr__(self): + return f"{self.offset}: f{self.op} - {self.arg} - {self.argval}" + def is_branch(self) -> bool: + return self.op in { + "JUMP_ABSOLUTE", + "JUMP_FORWARD", + "POP_JUMP_IF_TRUE", + "POP_JUMP_IF_FALSE", + "JUMP_IF_TRUE_OR_POP", + "JUMP_IF_FALSE_OR_POP", + } + def is_relative_branch(self) -> bool: + return self.op in { + "FOR_ITER", + "JUMP_FORWARD", + } + def is_return(self) -> bool: + return self.op == "RETURN_VALUE" + + def is_raise(self) -> bool: + return self.op == "RAISE_VARARGS" + +class Block: + def __init__(self, id: int, instructions: List): + self.id: int = id + self.instructions = instructions + def __repr__(self): + instructions = "\n".join([str(instr) for instr in self.instructions]) + return f"bb{self.id}:\n{instructions}" + +class BlockMap: + def __init__(self) -> None: + self.idx_to_block: Dict[int, Block] = {} + + def add_block(self, idx, block): + self.idx_to_block[idx] = block + + def __repr__(self) -> str: + result = [] + for block in self.idx_to_block.values(): + result.append(repr(block)) + return "\n".join(result) + def __str__(self) -> str: + return self.__repr__() + +def disassemble_bytecode(bytecode): + code_object = marshal.loads(bytecode) + instructions = [] + for i, instr in enumerate(dis.get_instructions(code_object)): + instructions.append(BytecodeOp( + op = instr.opname, + arg=instr.arg, + offset=instr.offset, + argval=instr.argval, + is_jump_target=instr.is_jump_target + )) + # print(instr) + return instructions + +def create_BBs(instructions: List[BytecodeOp]) -> BlockMap: + block_starts = set([0]) + block_map = BlockMap() + num_instr = len(instructions) + + # Create offset to index mapping + offset_to_index = {instr.offset: idx for idx, instr in enumerate(instructions)} + max_offset = instructions[-1].offset + CODEUNIT_SIZE + # print(f"Offset to Index Mapping: {offset_to_index}") + + def valid_offset(offset): + return offset >= 0 and offset <= max_offset + # Identify all block starts + for instr in instructions: + if instr.is_branch(): + next_instr_offset = instr.offset + CODEUNIT_SIZE + if valid_offset(next_instr_offset): + block_starts.add(next_instr_offset) + + if instr.is_relative_branch(): + target_offset = instr.offset + instr.argval + else: + target_offset = instr.argval + + if valid_offset(target_offset): + block_starts.add(target_offset) + + if instr.is_jump_target: + block_starts.add(instr.offset) + + block_starts_ordered = sorted(block_starts) + # print(f"Identified block starts: {block_starts_ordered}") + + for block_id, start_offset in enumerate(block_starts_ordered): + end_offset = block_starts_ordered[block_id + 1] if block_id + 1 < len(block_starts_ordered) else instructions[-1].offset + CODEUNIT_SIZE + start_index = offset_to_index[start_offset] + end_index = num_instr + + # Find the corresponding end_index + for offset in block_starts_ordered: + if offset > start_offset: + end_index = offset_to_index[offset] + break + + # Collect instructions for this block + block_instrs = instructions[start_index:end_index] + block_map.add_block(block_id, Block(block_id, block_instrs)) + + return block_map + + +class CFG: + def __init__(self): + self.nodes = set() + self.edges = {} + + def add_node(self, node_id): + self.nodes.add(node_id) + if node_id not in self.edges: + self.edges[node_id] = [] + + def add_edge(self, from_node, to_node): + if from_node in self.edges: + self.edges[from_node].append(to_node) + else: + self.edges[from_node] = [to_node] + + def __repr__(self): + result = [] + for node in self.nodes: + result.append(f'Node bb{node}:') + if node in self.edges and self.edges[node]: + for succ in self.edges[node]: + result.append(f' -> bb{succ}') + return "\n".join(result) +def create_cfg(block_map: BlockMap) -> CFG: + cfg = CFG() + + for block_id, block in block_map.idx_to_block.items(): + cfg.add_node(block_id) + + last_instr = block.instructions[-1] + + # Handle conditional jumps (e.g., POP_JUMP_IF_FALSE) + if last_instr.is_branch(): + target_offset = last_instr.argval if not last_instr.is_relative_branch() else (last_instr.offset + last_instr.argval) + target_block = find_block_by_offset(block_map, target_offset) + if target_block is not None: + cfg.add_edge(block_id, target_block) + # Fall-through to next block if it's a conditional branch + if last_instr.op.startswith('POP_JUMP_IF'): + fall_through_offset = block.instructions[-1].offset + CODEUNIT_SIZE + fall_through_block = find_block_by_offset(block_map, fall_through_offset) + if fall_through_block is not None: + cfg.add_edge(block_id, fall_through_block) + + # Handle unconditional jumps (e.g., JUMP_FORWARD, JUMP_ABSOLUTE) + elif last_instr.op.startswith("JUMP"): + target_offset = last_instr.argval if not last_instr.is_relative_branch() else (last_instr.offset + last_instr.argval) + target_block = find_block_by_offset(block_map, target_offset) + if target_block is not None: + cfg.add_edge(block_id, target_block) + + # Handle fall-through to the next block for non-control flow instructions + else: + fall_through_offset = block.instructions[-1].offset + CODEUNIT_SIZE + fall_through_block = find_block_by_offset(block_map, fall_through_offset) + if fall_through_block is not None: + cfg.add_edge(block_id, fall_through_block) + + return cfg + +def find_block_by_offset(block_map: BlockMap, offset: int) -> int: + for block_id, block in block_map.idx_to_block.items(): + if any(instr.offset == offset for instr in block.instructions): + return block_id + return None + +# def disassemble_bytecode(bytecode): +# code_object = marshal.loads(bytecode) +# instructions = list(dis.get_instructions(code_object)) +# print(f"Disassembled bytecode for {code_object.co_name}:") +# print( +# "\n".join( +# [f"{instr.offset}: {instr.opname} {instr.argval}" for instr in instructions] +# ) +# ) +# return instructions + +# Function to visualize CFG using Graphviz +def visualize_cfg(cfg: CFG): + dot = Digraph(comment="Control Flow Graph") + for node in cfg.nodes: + dot.node(f"bb{node}", f"BB{node}") + for from_node, to_nodes in cfg.edges.items(): + for to_node in to_nodes: + dot.edge(f"bb{from_node}", f"bb{to_node}") + return dot + +# Sample list of instructions for processing +##simple= +# instructions = disassemble_bytecode(b'c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x01\xf3*\x00\x00\x00\x97\x00d\x00d\x01l\x00m\x01Z\x01\x01\x00d\x00Z\x02d\x00Z\x03e\x03d\x00k\\\x00\x00r\x02d\x02Z\x02d\x03Z\x02y\x04)\x05\xe9\x00\x00\x00\x00)\x01\xda\x0bannotations\xe9\x01\x00\x00\x00\xe9\xff\xff\xff\xffN)\x04\xda\n__future__r\x02\x00\x00\x00\xda\x01a\xda\x01x\xa9\x00\xf3\x00\x00\x00\x00\xfaP/Users/jakobtherkelsen/Documents/jaseci-ginS/jac/examples/ginsScripts/simple.jac\xfa\x08r\x0b\x00\x00\x00\x01\x00\x00\x00s%\x00\x00\x00\xf0\x03\x01\x01\x01\xf5\x02\x07\x02\x03\xd8\x05\x06\x801\xd8\x05\x06\x801\xd8\x06\x07\x881\x82f\xd8\x07\x08\x80Q\xe0\x05\x07\x811r\t\x00\x00\x00') +#hot path +# instructions = disassemble_bytecode(b'c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x01\xf3T\x00\x00\x00\x97\x00d\x00d\x01l\x00m\x01Z\x01\x01\x00d\x00Z\x02d\x00Z\x03e\x02d\x02k\x02\x00\x00r\x19e\x02d\x03z\x06\x00\x00d\x00k(\x00\x00r\x03d\x04Z\x03n\x02d\x03Z\x03e\x02d\x04z\r\x00\x00Z\x02e\x02d\x02k\x02\x00\x00r\x01\x8c\x18y\x05y\x05)\x06\xe9\x00\x00\x00\x00)\x01\xda\x0bannotations\xe9\x0f\x00\x00\x00\xe9\x02\x00\x00\x00\xe9\x01\x00\x00\x00N)\x04\xda\n__future__r\x02\x00\x00\x00\xda\x01a\xda\x01b\xa9\x00\xf3\x00\x00\x00\x00\xfaR/Users/jakobtherkelsen/Documents/jaseci-ginS/jac/examples/ginsScripts/hot_path.jac\xfa\x08r\x0c\x00\x00\x00\x01\x00\x00\x00sD\x00\x00\x00\xf0\x03\x01\x01\x01\xf5\x02\x0c\x02\x03\xd8\x07\x08\x801\xd8\x07\x08\x801\xd8\t\n\x88R\x8a\x16\xd8\x08\t\x88A\x89\x05\x90\x11\x8a\n\xd8\x0b\x0c\x81q\xf0\x06\x00\x0c\r\x80q\xe0\x05\x06\x88!\x81W\x80Q\xf0\x0f\x00\n\x0b\x88R\x8d\x16r\n\x00\x00\x00') +# BBs = create_BBs(instructions) +# print(BBs) + +# cfg = create_cfg(BBs) +# print("\nControl Flow Graph (CFG):") +# print(cfg) + +# # Visualize CFG +# dot = visualize_cfg(cfg) +# dot.render('cfg.gv', view=True) \ No newline at end of file diff --git a/jac/jaclang/runtimelib/machine.py b/jac/jaclang/runtimelib/machine.py index e4ee40618b..e1a7a2411f 100644 --- a/jac/jaclang/runtimelib/machine.py +++ b/jac/jaclang/runtimelib/machine.py @@ -312,7 +312,7 @@ def get_bytecode( class ShellGhost: def __init__(self, file_name: str): self.__daemon_thread:Thread = Thread(target=self.worker, args=(file_name,)) - self.cfg = None + self.cfgs = None self.__daemon_thread.start() def worker(self, file_name): From 32f59a485956ac0d64860fb2d56a7b46ddf8562f Mon Sep 17 00:00:00 2001 From: jayanaka-98 Date: Fri, 15 Nov 2024 16:11:32 -0500 Subject: [PATCH 19/84] access CFG from ShellGhost --- jac/jaclang/cli/cli.py | 2 +- .../compiler/passes/main/cfg_gen_pass.py | 15 ++++--- jac/jaclang/runtimelib/machine.py | 45 ++++++------------- 3 files changed, 23 insertions(+), 39 deletions(-) diff --git a/jac/jaclang/cli/cli.py b/jac/jaclang/cli/cli.py index 8f4b0c931b..ebde865689 100644 --- a/jac/jaclang/cli/cli.py +++ b/jac/jaclang/cli/cli.py @@ -92,7 +92,7 @@ def run( mod = mod[:-4] jctx = ExecutionContext.create(session=session) if gins: - JacMachine(base).attach_gin(ShellGhost(filename)) + JacMachine(base).attach_gin(ShellGhost()) if filename.endswith(".jac"): try: diff --git a/jac/jaclang/compiler/passes/main/cfg_gen_pass.py b/jac/jaclang/compiler/passes/main/cfg_gen_pass.py index ef2d0899d1..5ad629d0b8 100644 --- a/jac/jaclang/compiler/passes/main/cfg_gen_pass.py +++ b/jac/jaclang/compiler/passes/main/cfg_gen_pass.py @@ -14,7 +14,6 @@ import jaclang.compiler.absyntree as ast from jaclang.compiler.passes import Pass from jaclang.runtimelib.cfg import visualize_cfg, disassemble_bytecode, create_BBs, create_cfg -from jaclang.runtimelib.machine import JacMachine class CfgGenPass(Pass): @@ -42,11 +41,15 @@ def enter_module(self, node: ast.Module) -> None: BBs = create_BBs(instructions) cfg = create_cfg(BBs) module_cfgs[mod.name] = cfg - for cfg in module_cfgs.values(): - dot = visualize_cfg(cfg) - print(dot) - dot.render('cfg.gv', view=True) - + # for cfg in module_cfgs.values(): + # dot = visualize_cfg(cfg) + # print(dot) + # dot.render('cfg.gv', view=True) + try: + from jaclang.runtimelib.machine import JacMachine + JacMachine.get().gin.get_cfgs(cfgs=module_cfgs) + except Exception as e: + print(f"Can't save cfgs: {e}") diff --git a/jac/jaclang/runtimelib/machine.py b/jac/jaclang/runtimelib/machine.py index e46e41e073..fd70c33e2c 100644 --- a/jac/jaclang/runtimelib/machine.py +++ b/jac/jaclang/runtimelib/machine.py @@ -76,9 +76,12 @@ def get_bytecode( ) -> Optional[types.CodeType]: """Retrieve bytecode from the attached JacProgram.""" if self.jac_program: - return self.jac_program.get_bytecode( + bytecode = self.jac_program.get_bytecode( module_name, full_target, caller_dir, cachable, reload=reload ) + if self.gin: + self.gin.start_ghost() + return bytecode return None def get_sem_ir(self, mod_sem_ir: SemRegistry | None) -> None: @@ -316,8 +319,6 @@ def get_bytecode( result = compile_jac(full_target, cache_result=cachable) if result.errors_had or not result.ir.gen.py_bytecode: for alrt in result.errors_had: - # We're not logging here, it already gets logged as the errors were added to the errors_had list. - # Regardless of the logging, this needs to be sent to the end user, so we'll printing it to stderr. logger.error(alrt.pretty_print()) return None if result.ir.gen.py_bytecode is not None: @@ -327,36 +328,16 @@ def get_bytecode( class ShellGhost: - def __init__(self, file_name: str): - self.__daemon_thread:Thread = Thread(target=self.worker, args=(file_name,)) + def __init__(self): self.cfgs = None + + def get_cfgs(self,cfgs: any): + self.cfgs = cfgs + + def start_ghost(self): + self.__daemon_thread:Thread = Thread(target=self.worker) self.__daemon_thread.start() - def worker(self, file_name): - print("doesn't do anything") - # ir = jac_file_to_pass( - # file_name, schedule=[*(py_code_gen[:-1]), *type_checker_sched] - # ).ir - # print(ir.pp()) - # time.sleep(2) + def worker(self): - -# import time -# import gc -# import inspect -# with open("log.txt", "a") as log_file: -# while True: -# # Pause to avoid excessive checks -# time.sleep(10) - -# # Gather all objects in the main application -# objects = gc.get_objects() -# log_file.write("\n[Monitor] Checking objects in main application:\n") - -# for obj in objects: -# # Only monitor dictionaries (e.g., modules, function locals, etc.) -# if isinstance(obj, dict): -# for name, value in obj.items(): -# log_file.write(f"Variable '{name}' = {value}\n") -# log_file.write("\n=====================================================================\n") -# log_file.flush() # Ensure data is written immediately \ No newline at end of file + print(self.cfgs) \ No newline at end of file From 8ca61c9bc52d777ed4de17dfa4879729306d6af6 Mon Sep 17 00:00:00 2001 From: jayanaka-98 Date: Fri, 15 Nov 2024 16:27:07 -0500 Subject: [PATCH 20/84] delete outdated cfg --- cfg.py | 223 --------------------------------------------------------- 1 file changed, 223 deletions(-) delete mode 100644 cfg.py diff --git a/cfg.py b/cfg.py deleted file mode 100644 index 7df443353b..0000000000 --- a/cfg.py +++ /dev/null @@ -1,223 +0,0 @@ -"""Genrate a control flow graph from genarated bytecode. - -This pass generates a control flow graph from the bytecode generated by the previous pass. - -Code was initially inspired by: -https://bernsteinbear.com/blog/discovering-basic-blocks/ - -The rest was extended to handle some nuance and edge conditions that were not considered. -""" -import marshal -import dis -from collections import defaultdict -from typing import List, Optional, Iterator -#import graphviz -#from graphviz import Digraph -CODEUNIT_SIZE = 2 -class BytecodeOp: - def __init__(self, op: int, arg: int, offset: int, argval:int, is_jump_target: bool) -> None: - self.op = op - self.arg = arg - self.offset = offset - self.argval = argval - self.is_jump_target= is_jump_target - - def __repr__(self): - return f"{self.offset}: f{self.op} - {self.arg} - {self.argval}" - def is_branch(self) -> bool: - return self.op in { - "JUMP_ABSOLUTE", - "JUMP_FORWARD", - "POP_JUMP_IF_TRUE", - "POP_JUMP_IF_FALSE", - "JUMP_IF_TRUE_OR_POP", - "JUMP_IF_FALSE_OR_POP", - } - def is_relative_branch(self) -> bool: - return self.op in { - "FOR_ITER", - "JUMP_FORWARD", - } - def is_return(self) -> bool: - return self.op == "RETURN_VALUE" - - def is_raise(self) -> bool: - return self.op == "RAISE_VARARGS" - -class Block: - def __init__(self, id: int, instructions: List): - self.id: int = id - self.instructions = instructions - def __repr__(self): - instructions = "\n".join([str(instr) for instr in self.instructions]) - return f"bb{self.id}:\n{instructions}" - -class BlockMap: - def __init__(self) -> None: - self.idx_to_block: Dict[int, Block] = {} - - def add_block(self, idx, block): - self.idx_to_block[idx] = block - - def __repr__(self) -> str: - result = [] - for block in self.idx_to_block.values(): - result.append(repr(block)) - return "\n".join(result) - def __str__(self) -> str: - return self.__repr__() - -def disassemble_bytecode(bytecode): - code_object = marshal.loads(bytecode) - instructions = [] - for i, instr in enumerate(dis.get_instructions(code_object)): - instructions.append(BytecodeOp( - op = instr.opname, - arg=instr.arg, - offset=instr.offset, - argval=instr.argval, - is_jump_target=instr.is_jump_target - )) - return instructions - -def create_BBs(instructions: List[BytecodeOp]) -> BlockMap: - block_starts = set([0]) - block_map = BlockMap() - num_instr = len(instructions) - - # Create offset to index mapping - offset_to_index = {instr.offset: idx for idx, instr in enumerate(instructions)} - max_offset = instructions[-1].offset + CODEUNIT_SIZE - - def valid_offset(offset): - return offset >= 0 and offset <= max_offset - # Identify all block starts - for instr in instructions: - if instr.is_branch(): - next_instr_offset = instr.offset + CODEUNIT_SIZE - if valid_offset(next_instr_offset): - block_starts.add(next_instr_offset) - - if instr.is_relative_branch(): - target_offset = instr.offset + instr.argval - else: - target_offset = instr.argval - - if valid_offset(target_offset): - block_starts.add(target_offset) - - if instr.is_jump_target: - block_starts.add(instr.offset) - - block_starts_ordered = sorted(block_starts) - - - for block_id, start_offset in enumerate(block_starts_ordered): - start_index = offset_to_index[start_offset] - end_index = num_instr - - # Find the corresponding end_index - for offset in block_starts_ordered: - if offset > start_offset: - end_index = offset_to_index[offset] - break - - # Collect instructions for this block - block_instrs = instructions[start_index:end_index] - block_map.add_block(block_id, Block(block_id, block_instrs)) - - return block_map - - -class CFG: - def __init__(self): - self.nodes = set() - self.edges = {} - - def add_node(self, node_id): - self.nodes.add(node_id) - if node_id not in self.edges: - self.edges[node_id] = [] - - def add_edge(self, from_node, to_node): - if from_node in self.edges: - self.edges[from_node].append(to_node) - else: - self.edges[from_node] = [to_node] - - def __repr__(self): - result = [] - for node in self.nodes: - result.append(f'Node bb{node}:') - if node in self.edges and self.edges[node]: - for succ in self.edges[node]: - result.append(f' -> bb{succ}') - return "\n".join(result) -def create_cfg(block_map: BlockMap) -> CFG: - cfg = CFG() - - for block_id, block in block_map.idx_to_block.items(): - cfg.add_node(block_id) - - last_instr = block.instructions[-1] - - # Handle conditional jumps (e.g., POP_JUMP_IF_FALSE) - if last_instr.is_branch(): - target_offset = last_instr.argval if not last_instr.is_relative_branch() else (last_instr.offset + last_instr.argval) - target_block = find_block_by_offset(block_map, target_offset) - if target_block is not None: - cfg.add_edge(block_id, target_block) - # Fall-through to next block if it's a conditional branch - if last_instr.op.startswith('POP_JUMP_IF'): - fall_through_offset = block.instructions[-1].offset + CODEUNIT_SIZE - fall_through_block = find_block_by_offset(block_map, fall_through_offset) - if fall_through_block is not None: - cfg.add_edge(block_id, fall_through_block) - - # Handle unconditional jumps (e.g., JUMP_FORWARD, JUMP_ABSOLUTE) - elif last_instr.op.startswith("JUMP"): - target_offset = last_instr.argval if not last_instr.is_relative_branch() else (last_instr.offset + last_instr.argval) - target_block = find_block_by_offset(block_map, target_offset) - if target_block is not None: - cfg.add_edge(block_id, target_block) - - # Handle fall-through to the next block for non-control flow instructions - else: - fall_through_offset = block.instructions[-1].offset + CODEUNIT_SIZE - fall_through_block = find_block_by_offset(block_map, fall_through_offset) - if fall_through_block is not None: - cfg.add_edge(block_id, fall_through_block) - - return cfg - -def find_block_by_offset(block_map: BlockMap, offset: int) -> int: - for block_id, block in block_map.idx_to_block.items(): - if any(instr.offset == offset for instr in block.instructions): - return block_id - return None - -# Function to visualize CFG using Graphviz -def visualize_cfg(cfg: CFG): - dot = Digraph(comment="Control Flow Graph") - for node in cfg.nodes: - dot.node(f"bb{node}", f"BB{node}") - for from_node, to_nodes in cfg.edges.items(): - for to_node in to_nodes: - dot.edge(f"bb{from_node}", f"bb{to_node}") - return dot - -# Sample list of instructions for processing -##simple= -instructions = disassemble_bytecode(b'c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x01\xf3*\x00\x00\x00\x97\x00d\x00d\x01l\x00m\x01Z\x01\x01\x00d\x00Z\x02d\x00Z\x03e\x03d\x00k\\\x00\x00r\x02d\x02Z\x02d\x03Z\x02y\x04)\x05\xe9\x00\x00\x00\x00)\x01\xda\x0bannotations\xe9\x01\x00\x00\x00\xe9\xff\xff\xff\xffN)\x04\xda\n__future__r\x02\x00\x00\x00\xda\x01a\xda\x01x\xa9\x00\xf3\x00\x00\x00\x00\xfaP/Users/jakobtherkelsen/Documents/jaseci-ginS/jac/examples/ginsScripts/simple.jac\xda\x08r\x0b\x00\x00\x00\x01\x00\x00\x00s%\x00\x00\x00\xf0\x03\x01\x01\x01\xf5\x02\x07\x02\x03\xd8\x05\x06\x801\xd8\x05\x06\x801\xd8\x06\x07\x881\x82f\xd8\x07\x08\x80Q\xe0\x05\x07\x811r\t\x00\x00\x00') -#hot path -#instructions = disassemble_bytecode(b'c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x01\xf3T\x00\x00\x00\x97\x00d\x00d\x01l\x00m\x01Z\x01\x01\x00d\x00Z\x02d\x00Z\x03e\x02d\x02k\x02\x00\x00r\x19e\x02d\x03z\x06\x00\x00d\x00k(\x00\x00r\x03d\x04Z\x03n\x02d\x03Z\x03e\x02d\x04z\r\x00\x00Z\x02e\x02d\x02k\x02\x00\x00r\x01\x8c\x18y\x05y\x05)\x06\xe9\x00\x00\x00\x00)\x01\xda\x0bannotations\xe9\x0f\x00\x00\x00\xe9\x02\x00\x00\x00\xe9\x01\x00\x00\x00N)\x04\xda\n__future__r\x02\x00\x00\x00\xda\x01a\xda\x01b\xa9\x00\xf3\x00\x00\x00\x00\xfaR/Users/jakobtherkelsen/Documents/jaseci-ginS/jac/examples/ginsScripts/hot_path.jac\xfa\x08r\x0c\x00\x00\x00\x01\x00\x00\x00sD\x00\x00\x00\xf0\x03\x01\x01\x01\xf5\x02\x0c\x02\x03\xd8\x07\x08\x801\xd8\x07\x08\x801\xd8\t\n\x88R\x8a\x16\xd8\x08\t\x88A\x89\x05\x90\x11\x8a\n\xd8\x0b\x0c\x81q\xf0\x06\x00\x0c\r\x80q\xe0\x05\x06\x88!\x81W\x80Q\xf0\x0f\x00\n\x0b\x88R\x8d\x16r\n\x00\x00\x00') -BBs = create_BBs(instructions) -print(BBs) - -cfg = create_cfg(BBs) -print("\nControl Flow Graph (CFG):") -print(cfg) - -# Visualize CFG -# dot = visualize_cfg(cfg) -# dot.render('cfg.gv', view=True) \ No newline at end of file From b7a7e23f5b88ddde1b41887d640403e482a20635 Mon Sep 17 00:00:00 2001 From: jayanaka-98 Date: Fri, 15 Nov 2024 17:27:48 -0500 Subject: [PATCH 21/84] if not gin flag --- .../compiler/passes/main/cfg_gen_pass.py | 21 ++++++------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/jac/jaclang/compiler/passes/main/cfg_gen_pass.py b/jac/jaclang/compiler/passes/main/cfg_gen_pass.py index 5ad629d0b8..1c3b1ae564 100644 --- a/jac/jaclang/compiler/passes/main/cfg_gen_pass.py +++ b/jac/jaclang/compiler/passes/main/cfg_gen_pass.py @@ -4,18 +4,11 @@ """ import ast -# import marshal -# import dis -# from collections import defaultdict -# import networkx as nx -# import matplotlib.pyplot as plt - import jaclang.compiler.absyntree as ast from jaclang.compiler.passes import Pass from jaclang.runtimelib.cfg import visualize_cfg, disassemble_bytecode, create_BBs, create_cfg - class CfgGenPass(Pass): """Control flow graph generation pass.""" @@ -45,14 +38,12 @@ def enter_module(self, node: ast.Module) -> None: # dot = visualize_cfg(cfg) # print(dot) # dot.render('cfg.gv', view=True) - try: - from jaclang.runtimelib.machine import JacMachine - JacMachine.get().gin.get_cfgs(cfgs=module_cfgs) - except Exception as e: - print(f"Can't save cfgs: {e}") - - - + from jaclang.runtimelib.machine import JacMachine + if JacMachine.get().gin: + try: + JacMachine.get().gin.get_cfgs(cfgs=module_cfgs) + except Exception as e: + print(f"Can't save cfgs: {e}") # cfg, block_map, edges = extract_cfg_from_instructions(instructions) # module_cfgs[mod.name] = build_cfg_graph(cfg, block_map, edges) From 0f50b85007f34cc4b0bf38be620e25cc387913f4 Mon Sep 17 00:00:00 2001 From: Jakob Louis Therkelsen Date: Fri, 15 Nov 2024 17:32:14 -0500 Subject: [PATCH 22/84] tracing in exec --- jac/examples/ginsScripts/simple.jac | 6 +++ jac/jaclang/runtimelib/importer.py | 57 ++++++++++++++++++++++++++++- 2 files changed, 61 insertions(+), 2 deletions(-) diff --git a/jac/examples/ginsScripts/simple.jac b/jac/examples/ginsScripts/simple.jac index 20e38ee1db..3575887f03 100644 --- a/jac/examples/ginsScripts/simple.jac +++ b/jac/examples/ginsScripts/simple.jac @@ -1,8 +1,14 @@ +can foo() { + return 1; +} + with entry { + foo(); a=0; x=0; if x >= 0{ a=1; } a=-1; + print("hello"); } \ No newline at end of file diff --git a/jac/jaclang/runtimelib/importer.py b/jac/jaclang/runtimelib/importer.py index c865da6603..2e72d6aac0 100644 --- a/jac/jaclang/runtimelib/importer.py +++ b/jac/jaclang/runtimelib/importer.py @@ -63,7 +63,56 @@ def get_caller_dir(self) -> str: chomp_target = chomp_target[1:] return path.join(caller_dir, self.dir_path) - +class CFGTracker: + def __init__(self): + self.count = 0 + def start_tracking(self): + """Start tracking branch coverage""" + sys.settrace(self.trace_callback) + def stop_tracking(self): + """Stop tracking branch coverage""" + sys.settrace(None) + + def trace_callback(self, frame: types.FrameType, event: str, arg: Any) -> Optional[types.TraceFunction]: + """Trace function to track executed branches""" + if event != 'line': + return self.trace_callback + code = frame.f_code + print(f"{frame.f_lineno}") + # print(f"Function Name: {code.co_name}") + # print(f"Filename: {code.co_filename}") + # print(f"First Line Number: {code.co_firstlineno}") + # print(f"Argument Count: {code.co_argcount}") + # print(f"Constants: {code.co_consts}") + # print(f"Local Variables: {code.co_varnames}") + self.count += 1 + + # if event != 'line': + # return self.trace_callback + + # code = frame.f_code + # if code not in self.cfg_cache: + # self.build_cfg(code) + + # # Find current basic block + # blocks = self.cfg_cache[code] + # current_offset = frame.f_lasti + + # # Find the block containing this offset + # current_block = None + # for block in blocks.values(): + # if block.offset <= current_offset <= block.offset + sum(inst.size for inst in block.instructions): + # current_block = block + # break + + # if current_block: + # current_block.hits += 1 + # # Record taken branches + # for next_block in current_block.next: + # self.coverage_data[code].add( + # (current_block.offset, next_block.offset)) + + # return self.trace_callback class ImportReturn: """Import Return Object.""" @@ -153,7 +202,6 @@ def load_jac_mod_as_item( ) if not codeobj: raise ImportError(f"No bytecode found for {jac_file_path}") - exec(codeobj, new_module.__dict__) return getattr(new_module, name, new_module) except ImportError as e: @@ -351,7 +399,12 @@ def run_import( try: with sys_path_context(spec.caller_dir): + tracker = CFGTracker() + tracker.start_tracking() + print("here") exec(codeobj, module.__dict__) + tracker.stop_tracking() + print(f"count={tracker.count}") except Exception as e: logger.error(e) logger.error(dump_traceback(e)) From 617f6da084d8444d4f4f6d172b9e2c60849ad0b1 Mon Sep 17 00:00:00 2001 From: jayanaka-98 Date: Fri, 15 Nov 2024 21:55:31 -0500 Subject: [PATCH 23/84] Fixup code for validating offsets, and making gins code apply only with gins flag. --- .../compiler/passes/main/cfg_gen_pass.py | 34 ++++++++++--------- jac/jaclang/runtimelib/cfg.py | 15 +++++--- jac/jaclang/runtimelib/importer.py | 29 +++++++++------- 3 files changed, 45 insertions(+), 33 deletions(-) diff --git a/jac/jaclang/compiler/passes/main/cfg_gen_pass.py b/jac/jaclang/compiler/passes/main/cfg_gen_pass.py index 1c3b1ae564..ca305b5bb2 100644 --- a/jac/jaclang/compiler/passes/main/cfg_gen_pass.py +++ b/jac/jaclang/compiler/passes/main/cfg_gen_pass.py @@ -26,24 +26,26 @@ def enter_module(self, node: ast.Module) -> None: is_imported: bool, sym_tab: Optional[SymbolTable], """ - mods = [node] + self.get_all_sub_nodes(node, ast.Module) - module_cfgs = {} - for mod in mods: - bytecode = mod.gen.py_bytecode - instructions = disassemble_bytecode(bytecode) - BBs = create_BBs(instructions) - cfg = create_cfg(BBs) - module_cfgs[mod.name] = cfg - # for cfg in module_cfgs.values(): - # dot = visualize_cfg(cfg) - # print(dot) - # dot.render('cfg.gv', view=True) + from jaclang.runtimelib.machine import JacMachine if JacMachine.get().gin: - try: - JacMachine.get().gin.get_cfgs(cfgs=module_cfgs) - except Exception as e: - print(f"Can't save cfgs: {e}") + mods = [node] + self.get_all_sub_nodes(node, ast.Module) + module_cfgs = {} + for mod in mods: + bytecode = mod.gen.py_bytecode + instructions = disassemble_bytecode(bytecode) + BBs = create_BBs(instructions) + cfg = create_cfg(BBs) + module_cfgs[mod.name] = cfg + # for cfg in module_cfgs.values(): + # dot = visualize_cfg(cfg) + # print(dot) + # dot.render('cfg.gv', view=True) + if JacMachine.get().gin: + try: + JacMachine.get().gin.get_cfgs(cfgs=module_cfgs) + except Exception as e: + print(f"Can't save cfgs: {e}") # cfg, block_map, edges = extract_cfg_from_instructions(instructions) # module_cfgs[mod.name] = build_cfg_graph(cfg, block_map, edges) diff --git a/jac/jaclang/runtimelib/cfg.py b/jac/jaclang/runtimelib/cfg.py index 9c0a71c361..5b6f6661af 100644 --- a/jac/jaclang/runtimelib/cfg.py +++ b/jac/jaclang/runtimelib/cfg.py @@ -88,11 +88,16 @@ def create_BBs(instructions: List[BytecodeOp]) -> BlockMap: # print(f"Offset to Index Mapping: {offset_to_index}") def valid_offset(offset): - return offset >= 0 and offset <= max_offset + return offset in offset_to_index.keys() + def find_next_offset(offset): + offset_index = offset_to_index[offset] + return list(offset_to_index.keys())[offset_index + 1] + # return offset >= 0 and offset <= max_offset # Identify all block starts for instr in instructions: if instr.is_branch(): - next_instr_offset = instr.offset + CODEUNIT_SIZE + next_instr_offset = find_next_offset(instr.offset) + # next_instr_offset = instr.offset + CODEUNIT_SIZE if valid_offset(next_instr_offset): block_starts.add(next_instr_offset) @@ -118,13 +123,15 @@ def valid_offset(offset): # Find the corresponding end_index for offset in block_starts_ordered: if offset > start_offset: - end_index = offset_to_index[offset] + try: + end_index = offset_to_index[offset] + except Exception as e: + print(f'Error: {e}') break # Collect instructions for this block block_instrs = instructions[start_index:end_index] block_map.add_block(block_id, Block(block_id, block_instrs)) - return block_map diff --git a/jac/jaclang/runtimelib/importer.py b/jac/jaclang/runtimelib/importer.py index 2e72d6aac0..6180d890d7 100644 --- a/jac/jaclang/runtimelib/importer.py +++ b/jac/jaclang/runtimelib/importer.py @@ -73,7 +73,7 @@ def stop_tracking(self): """Stop tracking branch coverage""" sys.settrace(None) - def trace_callback(self, frame: types.FrameType, event: str, arg: Any) -> Optional[types.TraceFunction]: + def trace_callback(self, frame: types.FrameType, event: str, arg: any) -> Optional[types.TraceFunction]: """Trace function to track executed branches""" if event != 'line': return self.trace_callback @@ -397,18 +397,21 @@ def run_import( if not codeobj: raise ImportError(f"No bytecode found for {spec.full_target}") - try: - with sys_path_context(spec.caller_dir): - tracker = CFGTracker() - tracker.start_tracking() - print("here") - exec(codeobj, module.__dict__) - tracker.stop_tracking() - print(f"count={tracker.count}") - except Exception as e: - logger.error(e) - logger.error(dump_traceback(e)) - raise e + from jaclang.runtimelib.machine import JacMachine + if JacMachine.get().gin: + try: + with sys_path_context(spec.caller_dir): + tracker = CFGTracker() + tracker.start_tracking() + exec(codeobj, module.__dict__) + tracker.stop_tracking() + print(f"count={tracker.count}") + except Exception as e: + logger.error(e) + logger.error(dump_traceback(e)) + raise e + else: + exec(codeobj, module.__dict__) import_return = ImportReturn(module, unique_loaded_items, self) if spec.items: From fa41b8411cdd2dfb7dd32610b653193d3dd481d8 Mon Sep 17 00:00:00 2001 From: Jakob Louis Therkelsen Date: Sat, 16 Nov 2024 14:12:24 -0500 Subject: [PATCH 24/84] fix jump_forward? --- jac/jaclang/runtimelib/cfg.py | 70 ++++++++++++++++++++++------------- 1 file changed, 44 insertions(+), 26 deletions(-) diff --git a/jac/jaclang/runtimelib/cfg.py b/jac/jaclang/runtimelib/cfg.py index 5b6f6661af..f926f721e2 100644 --- a/jac/jaclang/runtimelib/cfg.py +++ b/jac/jaclang/runtimelib/cfg.py @@ -6,10 +6,9 @@ import dis from collections import defaultdict from typing import List, Optional, Iterator -import graphviz -from graphviz import Digraph +# import graphviz +# from graphviz import Digraph -CODEUNIT_SIZE = 2 class BytecodeOp: def __init__(self, op: int, arg: int, offset: int, argval:int, is_jump_target: bool) -> None: self.op = op @@ -17,9 +16,11 @@ def __init__(self, op: int, arg: int, offset: int, argval:int, is_jump_target: b self.offset = offset self.argval = argval self.is_jump_target= is_jump_target + #default the offset + self.__offset_size = 0 def __repr__(self): - return f"{self.offset}: f{self.op} - {self.arg} - {self.argval}" + return f"{self.offset}: {self.op} - {self.arg} - {self.argval}" def is_branch(self) -> bool: return self.op in { "JUMP_ABSOLUTE", @@ -39,6 +40,15 @@ def is_return(self) -> bool: def is_raise(self) -> bool: return self.op == "RAISE_VARARGS" + + def set_offset_size(self, size) -> None: + self.__offset_size = size + + def get_offset_size(self) -> int: + return self.__offset_size + + def get_next_instruction_offset(self) -> int: + return self.__offset_size + self.offset class Block: def __init__(self, id: int, instructions: List): @@ -67,14 +77,18 @@ def disassemble_bytecode(bytecode): code_object = marshal.loads(bytecode) instructions = [] for i, instr in enumerate(dis.get_instructions(code_object)): - instructions.append(BytecodeOp( + instructions.append(BytecodeOp( op = instr.opname, arg=instr.arg, offset=instr.offset, argval=instr.argval, is_jump_target=instr.is_jump_target )) - # print(instr) + #set offest size for calculating next instruction + #last instruction is default of 2, but shouldn't be needed + if i != 0: + instruction = instructions[i-1] + instruction.set_offset_size(instr.offset - instructions[i-1].offset) return instructions def create_BBs(instructions: List[BytecodeOp]) -> BlockMap: @@ -84,29 +98,32 @@ def create_BBs(instructions: List[BytecodeOp]) -> BlockMap: # Create offset to index mapping offset_to_index = {instr.offset: idx for idx, instr in enumerate(instructions)} - max_offset = instructions[-1].offset + CODEUNIT_SIZE + max_offset = instructions[-1].get_next_instruction_offset() # print(f"Offset to Index Mapping: {offset_to_index}") def valid_offset(offset): - return offset in offset_to_index.keys() - def find_next_offset(offset): - offset_index = offset_to_index[offset] - return list(offset_to_index.keys())[offset_index + 1] - # return offset >= 0 and offset <= max_offset + return offset >= 0 and offset <= max_offset # Identify all block starts for instr in instructions: + if instr.offset == 240: + x = 1 if instr.is_branch(): - next_instr_offset = find_next_offset(instr.offset) - # next_instr_offset = instr.offset + CODEUNIT_SIZE - if valid_offset(next_instr_offset): + next_instr_offset = instr.get_next_instruction_offset() + if next_instr_offset == 242: + x =1 + if 0 <= next_instr_offset <= max_offset: block_starts.add(next_instr_offset) if instr.is_relative_branch(): - target_offset = instr.offset + instr.argval + target_offset = instr.argval + if target_offset == 244: + x = 21 else: target_offset = instr.argval if valid_offset(target_offset): + if target_offset == 242: + x = 21 block_starts.add(target_offset) if instr.is_jump_target: @@ -116,7 +133,7 @@ def find_next_offset(offset): # print(f"Identified block starts: {block_starts_ordered}") for block_id, start_offset in enumerate(block_starts_ordered): - end_offset = block_starts_ordered[block_id + 1] if block_id + 1 < len(block_starts_ordered) else instructions[-1].offset + CODEUNIT_SIZE + end_offset = block_starts_ordered[block_id + 1] if block_id + 1 < len(block_starts_ordered) else instructions[-1].get_next_instruction_offset() start_index = offset_to_index[start_offset] end_index = num_instr @@ -175,7 +192,7 @@ def create_cfg(block_map: BlockMap) -> CFG: cfg.add_edge(block_id, target_block) # Fall-through to next block if it's a conditional branch if last_instr.op.startswith('POP_JUMP_IF'): - fall_through_offset = block.instructions[-1].offset + CODEUNIT_SIZE + fall_through_offset = block.instructions[-1].get_next_instruction_offset() fall_through_block = find_block_by_offset(block_map, fall_through_offset) if fall_through_block is not None: cfg.add_edge(block_id, fall_through_block) @@ -189,7 +206,7 @@ def create_cfg(block_map: BlockMap) -> CFG: # Handle fall-through to the next block for non-control flow instructions else: - fall_through_offset = block.instructions[-1].offset + CODEUNIT_SIZE + fall_through_offset = block.instructions[-1].get_next_instruction_offset() fall_through_block = find_block_by_offset(block_map, fall_through_offset) if fall_through_block is not None: cfg.add_edge(block_id, fall_through_block) @@ -225,15 +242,16 @@ def visualize_cfg(cfg: CFG): # Sample list of instructions for processing ##simple= -# instructions = disassemble_bytecode(b'c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x01\xf3*\x00\x00\x00\x97\x00d\x00d\x01l\x00m\x01Z\x01\x01\x00d\x00Z\x02d\x00Z\x03e\x03d\x00k\\\x00\x00r\x02d\x02Z\x02d\x03Z\x02y\x04)\x05\xe9\x00\x00\x00\x00)\x01\xda\x0bannotations\xe9\x01\x00\x00\x00\xe9\xff\xff\xff\xffN)\x04\xda\n__future__r\x02\x00\x00\x00\xda\x01a\xda\x01x\xa9\x00\xf3\x00\x00\x00\x00\xfaP/Users/jakobtherkelsen/Documents/jaseci-ginS/jac/examples/ginsScripts/simple.jac\xfa\x08r\x0b\x00\x00\x00\x01\x00\x00\x00s%\x00\x00\x00\xf0\x03\x01\x01\x01\xf5\x02\x07\x02\x03\xd8\x05\x06\x801\xd8\x05\x06\x801\xd8\x06\x07\x881\x82f\xd8\x07\x08\x80Q\xe0\x05\x07\x811r\t\x00\x00\x00') +#instructions = disassemble_bytecode(b'c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x01\xf3*\x00\x00\x00\x97\x00d\x00d\x01l\x00m\x01Z\x01\x01\x00d\x00Z\x02d\x00Z\x03e\x03d\x00k\\\x00\x00r\x02d\x02Z\x02d\x03Z\x02y\x04)\x05\xe9\x00\x00\x00\x00)\x01\xda\x0bannotations\xe9\x01\x00\x00\x00\xe9\xff\xff\xff\xffN)\x04\xda\n__future__r\x02\x00\x00\x00\xda\x01a\xda\x01x\xa9\x00\xf3\x00\x00\x00\x00\xfaP/Users/jakobtherkelsen/Documents/jaseci-ginS/jac/examples/ginsScripts/simple.jac\xfa\x08r\x0b\x00\x00\x00\x01\x00\x00\x00s%\x00\x00\x00\xf0\x03\x01\x01\x01\xf5\x02\x07\x02\x03\xd8\x05\x06\x801\xd8\x05\x06\x801\xd8\x06\x07\x881\x82f\xd8\x07\x08\x80Q\xe0\x05\x07\x811r\t\x00\x00\x00') #hot path -# instructions = disassemble_bytecode(b'c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x01\xf3T\x00\x00\x00\x97\x00d\x00d\x01l\x00m\x01Z\x01\x01\x00d\x00Z\x02d\x00Z\x03e\x02d\x02k\x02\x00\x00r\x19e\x02d\x03z\x06\x00\x00d\x00k(\x00\x00r\x03d\x04Z\x03n\x02d\x03Z\x03e\x02d\x04z\r\x00\x00Z\x02e\x02d\x02k\x02\x00\x00r\x01\x8c\x18y\x05y\x05)\x06\xe9\x00\x00\x00\x00)\x01\xda\x0bannotations\xe9\x0f\x00\x00\x00\xe9\x02\x00\x00\x00\xe9\x01\x00\x00\x00N)\x04\xda\n__future__r\x02\x00\x00\x00\xda\x01a\xda\x01b\xa9\x00\xf3\x00\x00\x00\x00\xfaR/Users/jakobtherkelsen/Documents/jaseci-ginS/jac/examples/ginsScripts/hot_path.jac\xfa\x08r\x0c\x00\x00\x00\x01\x00\x00\x00sD\x00\x00\x00\xf0\x03\x01\x01\x01\xf5\x02\x0c\x02\x03\xd8\x07\x08\x801\xd8\x07\x08\x801\xd8\t\n\x88R\x8a\x16\xd8\x08\t\x88A\x89\x05\x90\x11\x8a\n\xd8\x0b\x0c\x81q\xf0\x06\x00\x0c\r\x80q\xe0\x05\x06\x88!\x81W\x80Q\xf0\x0f\x00\n\x0b\x88R\x8d\x16r\n\x00\x00\x00') -# BBs = create_BBs(instructions) -# print(BBs) +instructions = disassemble_bytecode(b'c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x01\xf3T\x00\x00\x00\x97\x00d\x00d\x01l\x00m\x01Z\x01\x01\x00d\x00Z\x02d\x00Z\x03e\x02d\x02k\x02\x00\x00r\x19e\x02d\x03z\x06\x00\x00d\x00k(\x00\x00r\x03d\x04Z\x03n\x02d\x03Z\x03e\x02d\x04z\r\x00\x00Z\x02e\x02d\x02k\x02\x00\x00r\x01\x8c\x18y\x05y\x05)\x06\xe9\x00\x00\x00\x00)\x01\xda\x0bannotations\xe9\x0f\x00\x00\x00\xe9\x02\x00\x00\x00\xe9\x01\x00\x00\x00N)\x04\xda\n__future__r\x02\x00\x00\x00\xda\x01a\xda\x01b\xa9\x00\xf3\x00\x00\x00\x00\xfaR/Users/jakobtherkelsen/Documents/jaseci-ginS/jac/examples/ginsScripts/hot_path.jac\xfa\x08r\x0c\x00\x00\x00\x01\x00\x00\x00sD\x00\x00\x00\xf0\x03\x01\x01\x01\xf5\x02\x0c\x02\x03\xd8\x07\x08\x801\xd8\x07\x08\x801\xd8\t\n\x88R\x8a\x16\xd8\x08\t\x88A\x89\x05\x90\x11\x8a\n\xd8\x0b\x0c\x81q\xf0\x06\x00\x0c\r\x80q\xe0\x05\x06\x88!\x81W\x80Q\xf0\x0f\x00\n\x0b\x88R\x8d\x16r\n\x00\x00\x00') +#guess_game_bc = disassemble_bytecode(b'c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x01\xf3\x9e\x01\x00\x00\x97\x00d\x00Z\x00d\x01d\x02l\x01m\x02Z\x02\x01\x00d\x01d\x03l\x03m\x04Z\x05\x01\x00d\x01d\x04l\x06Z\x07d\x01d\x05l\x08m\tZ\n\x01\x00d\x01d\x06l\x0b\xad\x02\x01\x00d\x01d\x07l\x0cm\rZ\x0e\x01\x00e\x07j\x1e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00r\x05d\x01d\x04l\x10Z\x10n\x10\x02\x00e\x05d\x08e\x11d\td\nd\x04i\x00\xac\x0b\xab\x06\x00\x00\x00\x00\x00\x00\\\x01\x00\x00Z\x10\x02\x00e\nj$\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00g\x00g\x00\xac\x0c\xab\x02\x00\x00\x00\x00\x00\x00\x02\x00e\x0ed\n\xac\r\xab\x01\x00\x00\x00\x00\x00\x00\x02\x00G\x00d\x0e\x84\x00d\x0fe\nj&\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xab\x03\x00\x00\x00\x00\x00\x00\xab\x00\x00\x00\x00\x00\x00\x00\xab\x00\x00\x00\x00\x00\x00\x00Z\x14\x02\x00e\nj$\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00g\x00g\x00\xac\x0c\xab\x02\x00\x00\x00\x00\x00\x00\x02\x00e\x0ed\n\xac\r\xab\x01\x00\x00\x00\x00\x00\x00\x02\x00G\x00d\x10\x84\x00d\x11e\x14e\nj&\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xab\x04\x00\x00\x00\x00\x00\x00\xab\x00\x00\x00\x00\x00\x00\x00\xab\x00\x00\x00\x00\x00\x00\x00Z\x15\t\x00\x02\x00e\x15\xab\x00\x00\x00\x00\x00\x00\x00Z\x16e\x16j/\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xab\x00\x00\x00\x00\x00\x00\x00\x01\x00y\x04)\x12\xfa\x16A Number Guessing Game\xe9\x00\x00\x00\x00)\x01\xda\x0bannotations)\x01\xda\njac_importN)\x01\xda\nJacFeature)\x01\xda\x01*)\x01\xda\tdataclass\xda\x06random\xda\x02pyF)\x06\xda\x06target\xda\tbase_path\xda\x03lng\xda\x06absorb\xda\tmdl_alias\xda\x05items)\x02\xda\x08on_entry\xda\x07on_exit)\x01\xda\x02eqc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x01\xf3 \x00\x00\x00\x97\x00e\x00Z\x01d\x00Z\x02d\x01Z\x03d\x05d\x02\x84\x04Z\x04d\x06d\x03\x84\x04Z\x05y\x04)\x07\xda\x04Game\xe1\x1a\x01\x00\x00\nA generic Game base class.\n\nThe obj keyword is used to define the class.\nThe can keyword is used to define methods (functions) within the class.\nThe self keyword is used to refer to the current instance of the class.\nConstructors are defined using the init method with parameters.\nc\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x01\xf3 \x00\x00\x00\x97\x00|\x01|\x00_\x00\x00\x00\x00\x00\x00\x00\x00\x00d\x01|\x00_\x01\x00\x00\x00\x00\x00\x00\x00\x00y\x00)\x02NF)\x02\xda\x08attempts\xda\x03won)\x02\xda\x04selfr\x17\x00\x00\x00s\x02\x00\x00\x00 \xfaT/Users/jakobtherkelsen/Documents/jaseci-ginS/jac/examples/guess_game/guess_game1.jac\xda\x08__init__z\rGame.__init__\x0e\x00\x00\x00s\x10\x00\x00\x00\x80\x00\xd8\x19!\x88\x14\x8c\x1d\xd8\x14\x19\x88\x14\x8d\x18\xf3\x00\x00\x00\x00c\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03\x00\x00\x01\xf3\x18\x00\x00\x00\x97\x00t\x01\x00\x00\x00\x00\x00\x00\x00\x00d\x01\xab\x01\x00\x00\x00\x00\x00\x00\x82\x01)\x02N\xfa&Subclasses must implement this method.)\x01\xda\x13NotImplementedError)\x01r\x19\x00\x00\x00s\x01\x00\x00\x00 r\x1a\x00\x00\x00\xda\x04playz\tGame.play\x13\x00\x00\x00s\x12\x00\x00\x00\x80\x00\xdc\x0f"\xd8\r5\xf3\x03\x02\x10\x10\xf0\x00\x02\n\x0cr\x1c\x00\x00\x00N\xa9\x04r\x17\x00\x00\x00\xda\x03int\xda\x06return\xda\x04None\xa9\x02r#\x00\x00\x00r$\x00\x00\x00)\x06\xda\x08__name__\xda\n__module__\xda\x0c__qualname__\xda\x07__doc__r\x1b\x00\x00\x00r \x00\x00\x00\xa9\x00r\x1c\x00\x00\x00r\x1a\x00\x00\x00r\x14\x00\x00\x00r\x14\x00\x00\x00\x05\x00\x00\x00s\x11\x00\x00\x00\x84\x00\xf1\x00\x07\x02\x05\xf3\x12\x03\x06\x07\xf4\n\x04\x06\x07r\x1c\x00\x00\x00r\x14\x00\x00\x00c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x01\xf36\x00\x00\x00\x87\x00\x97\x00e\x00Z\x01d\x00Z\x02d\x01Z\x03d\x05d\x06\x88\x00f\x01d\x02\x84\rZ\x04d\x07d\x03\x84\x04Z\x05d\x08d\x04\x84\x04Z\x06\x88\x00x\x01Z\x07S\x00)\t\xda\x12GuessTheNumberGame\xfa\xae\nA number guessing game. The player must guess a number between 1 and 100.\n\nThis class inherits from Game. The super() function is used to call the parent class constructor.\nc\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x03\x00\x00\x01\xf3Z\x00\x00\x00\x95\x01\x97\x00t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x89\x02|\x00\x8d\x05\x00\x00|\x01\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00t\x05\x00\x00\x00\x00\x00\x00\x00\x00j\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00d\x01d\x02\xab\x02\x00\x00\x00\x00\x00\x00|\x00_\x04\x00\x00\x00\x00\x00\x00\x00\x00y\x00)\x03N\xe9\x01\x00\x00\x00\xe9d\x00\x00\x00)\x05\xda\x05superr\x1b\x00\x00\x00r\x08\x00\x00\x00\xda\x07randint\xda\x0ecorrect_number)\x03r\x19\x00\x00\x00r\x17\x00\x00\x00\xda\t__class__s\x03\x00\x00\x00 \x80r\x1a\x00\x00\x00r\x1b\x00\x00\x00z\x1bGuessTheNumberGame.__init__ \x00\x00\x00s \x00\x00\x00\xf8\x80\x00\xde\t\x0e\x89\x1a\x90H\xd4\t\x1d\xdc\x1f%\x9f~\x99~\xa8a\xb0\x13\xd3\x1f5\x88\x14\xd5\t\x1cr\x1c\x00\x00\x00c\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x03\x00\x00\x01\xf3\xf4\x00\x00\x00\x97\x00|\x00j\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00d\x01kD\x00\x00rQt\x03\x00\x00\x00\x00\x00\x00\x00\x00d\x02\xab\x01\x00\x00\x00\x00\x00\x00}\x01|\x01j\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xab\x00\x00\x00\x00\x00\x00\x00r\x1b|\x00j\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00t\t\x00\x00\x00\x00\x00\x00\x00\x00|\x01\xab\x01\x00\x00\x00\x00\x00\x00\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00n\x0bt\x0b\x00\x00\x00\x00\x00\x00\x00\x00d\x03\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00|\x00j\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00d\x01kD\x00\x00r\x01\x8cQ|\x00j\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00s\x0ct\x0b\x00\x00\x00\x00\x00\x00\x00\x00d\x04\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00y\x00y\x00)\x05Nr\x02\x00\x00\x00\xfa"Guess a number between 1 and 100: \xfa%That\'s not a valid number! Try again.\xfa:Sorry, you didn\'t guess the number. Better luck next time!)\x07r\x17\x00\x00\x00\xda\x05input\xda\x07isdigit\xda\rprocess_guessr"\x00\x00\x00\xda\x05printr\x18\x00\x00\x00\xa9\x02r\x19\x00\x00\x00\xda\x05guesss\x02\x00\x00\x00 r\x1a\x00\x00\x00\xfa\x04playz\x17GuessTheNumberGame.play%\x00\x00\x00sd\x00\x00\x00\x80\x00\xe0\x0f\x13\x8f}\x89}\x98q\xd2\x0f \xdc\x15\x1a\xd0\x1b?\xd3\x15@\x88U\xd8\x10\x15\x97\r\x91\r\x94\x0f\xd8\x11\x15\xd7\x11#\xd1\x11#\xa4C\xa8\x05\xa3J\xd5\x11/\xe4\x11\x16\xd0\x17>\xd4\x11?\xf0\x0b\x00\x10\x14\x8f}\x89}\x98q\xd3\x0f \xf0\x10\x00\x11\x15\x97\x08\x92\x08\xdc\r\x12\xd8\x11M\xf5\x03\x02\x0e\x0f\xf0\x03\x00\x11\x19r\x1c\x00\x00\x00c\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x03\x00\x00\x01\xf3\xfe\x00\x00\x00\x97\x00|\x01|\x00j\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00kD\x00\x00r\x0ct\x03\x00\x00\x00\x00\x00\x00\x00\x00d\x01\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00n4|\x01|\x00j\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00k\x02\x00\x00r\x0ct\x03\x00\x00\x00\x00\x00\x00\x00\x00d\x02\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00n\x19t\x03\x00\x00\x00\x00\x00\x00\x00\x00d\x03\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00d\x04|\x00_\x02\x00\x00\x00\x00\x00\x00\x00\x00d\x05|\x00_\x03\x00\x00\x00\x00\x00\x00\x00\x00|\x00x\x01j\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00d\x06z\x17\x00\x00c\x02_\x02\x00\x00\x00\x00\x00\x00\x00\x00t\x03\x00\x00\x00\x00\x00\x00\x00\x00d\x07|\x00j\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9b\x00d\x08\x9d\x03\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00y\x00)\tN\xfa\tToo high!\xfa\x08Too low!\xfa\'Congratulations! You guessed correctly.r\x02\x00\x00\x00Tr/\x00\x00\x00\xfa\tYou have \xfa\x0f attempts left.)\x04r3\x00\x00\x00r<\x00\x00\x00r\x17\x00\x00\x00r\x18\x00\x00\x00r=\x00\x00\x00s\x02\x00\x00\x00 r\x1a\x00\x00\x00\xfa\rprocess_guessz GuessTheNumberGame.process_guess6\x00\x00\x00se\x00\x00\x00\x80\x00\xd8\x0c\x11\x90D\xd7\x14\'\xd1\x14\'\xd2\x0c\'\xdc\r\x12\x90;\xd5\r\x1f\xd8\x10\x15\x98\x04\xd7\x18+\xd1\x18+\xd2\x10+\xdc\r\x12\x90:\xd5\r\x1e\xe4\r\x12\xd0\x13<\xd4\r=\xd8\x1d\x1e\x88T\x8c]\xd8\x18\x1c\x88T\x8cX\xe0\t\r\x8f\x1d\x8a\x1d\x98!\xd1\t\x1c\x8d\x1d\xdc\t\x0e\xd0\x0f9\x984\x9f=\x9a=\xd1\x0f9\xd5\t:r\x1c\x00\x00\x00)\x01\xe9\n\x00\x00\x00r!\x00\x00\x00r%\x00\x00\x00)\x04r>\x00\x00\x00r"\x00\x00\x00r#\x00\x00\x00r$\x00\x00\x00)\x08r&\x00\x00\x00r\'\x00\x00\x00r(\x00\x00\x00r)\x00\x00\x00r\x1b\x00\x00\x00r \x00\x00\x00r;\x00\x00\x00\xda\r__classcell__)\x01r4\x00\x00\x00s\x01\x00\x00\x00@r\x1a\x00\x00\x00r,\x00\x00\x00r,\x00\x00\x00\x1a\x00\x00\x00s\x17\x00\x00\x00\xf8\x84\x00\xf1\x00\x04\x02\x05\xf6\x0c\x03\x06\x07\xf3\n\x0f\x06\x07\xf7"\x0c\x06\x07r\x1c\x00\x00\x00r,\x00\x00\x00)\x18r)\x00\x00\x00\xda\n__future__r\x03\x00\x00\x00\xda\x07jaclangr\x04\x00\x00\x00\xda\x0e__jac_import__\xda\x06typing\xda\x08_jac_typ\xda\x16jaclang.plugin.featurer\x05\x00\x00\x00\xda\x04_Jac\xda\x16jaclang.plugin.builtin\xda\x0bdataclassesr\x07\x00\x00\x00\xda\x11__jac_dataclass__\xda\rTYPE_CHECKINGr\x08\x00\x00\x00\xda\x08__file__\xda\x08make_obj\xda\x03Objr\x14\x00\x00\x00r,\x00\x00\x00\xda\x04gamer \x00\x00\x00r*\x00\x00\x00r\x1c\x00\x00\x00r\x1a\x00\x00\x00\xda\x08rX\x00\x00\x00\x01\x00\x00\x00s\xaa\x00\x00\x00\xf0\x03\x01\x01\x01\xd9\x01\x1d\xf7\x00K\x01\x02\x03\xf7\x00K\x01\x02\x03\xf7\x00K\x01\x02\x03\xf7\x00K\x01\x02\x03\xf0\x00K\x01\x02\x03\xe7\x01\x12\xd7\x01\x12\xd4\x01\x12\x80s\xd7\x01\x12\xd2\x01\x12\xf1\x04\x13\x02\x03\xef&\xe9\x00\xf7\'\x13\x02\x03\xf7\x00\x13\x02\x03\xf4\x00\x13\x02\x03\xef&\xe9\x00\xf7\'\x13\x02\x03\xf4\x00\x13\x02\x03\xf1*)\x02\x03\xefR\x01\xe9\x00\xf7S\x01)\x02\x03\xf7\x00)\x02\x03\xf3\x00)\x02\x03\xf0\n\x00\x1a\x1e\xf0\x0b)\x02\x03\xefR\x01\xe9\x00\xf7S\x01)\x02\x03\xf4\x00)\x02\x03\xf0X\x01\x02\x02\x05\xf1\x08\x00\r\x1f\xd3\x0c \x80T\xd8\x05\t\x87Y\x81Y\x85[r\x1c\x00\x00\x00') +BBs = create_BBs(instructions) +print(BBs) -# cfg = create_cfg(BBs) -# print("\nControl Flow Graph (CFG):") -# print(cfg) +cfg = create_cfg(BBs) +print("\nControl Flow Graph (CFG):") +print(cfg) # # Visualize CFG # dot = visualize_cfg(cfg) From b18597e6bbb62753565791f50b8dea3b6198e7a4 Mon Sep 17 00:00:00 2001 From: Jakob Louis Therkelsen Date: Sat, 16 Nov 2024 14:21:37 -0500 Subject: [PATCH 25/84] clean up test code --- jac/jaclang/runtimelib/cfg.py | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/jac/jaclang/runtimelib/cfg.py b/jac/jaclang/runtimelib/cfg.py index f926f721e2..264c688119 100644 --- a/jac/jaclang/runtimelib/cfg.py +++ b/jac/jaclang/runtimelib/cfg.py @@ -105,25 +105,18 @@ def valid_offset(offset): return offset >= 0 and offset <= max_offset # Identify all block starts for instr in instructions: - if instr.offset == 240: - x = 1 if instr.is_branch(): next_instr_offset = instr.get_next_instruction_offset() - if next_instr_offset == 242: - x =1 if 0 <= next_instr_offset <= max_offset: block_starts.add(next_instr_offset) + #TODO: Confirm we can clean this up if instr.is_relative_branch(): target_offset = instr.argval - if target_offset == 244: - x = 21 else: target_offset = instr.argval if valid_offset(target_offset): - if target_offset == 242: - x = 21 block_starts.add(target_offset) if instr.is_jump_target: @@ -244,14 +237,14 @@ def visualize_cfg(cfg: CFG): ##simple= #instructions = disassemble_bytecode(b'c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x01\xf3*\x00\x00\x00\x97\x00d\x00d\x01l\x00m\x01Z\x01\x01\x00d\x00Z\x02d\x00Z\x03e\x03d\x00k\\\x00\x00r\x02d\x02Z\x02d\x03Z\x02y\x04)\x05\xe9\x00\x00\x00\x00)\x01\xda\x0bannotations\xe9\x01\x00\x00\x00\xe9\xff\xff\xff\xffN)\x04\xda\n__future__r\x02\x00\x00\x00\xda\x01a\xda\x01x\xa9\x00\xf3\x00\x00\x00\x00\xfaP/Users/jakobtherkelsen/Documents/jaseci-ginS/jac/examples/ginsScripts/simple.jac\xfa\x08r\x0b\x00\x00\x00\x01\x00\x00\x00s%\x00\x00\x00\xf0\x03\x01\x01\x01\xf5\x02\x07\x02\x03\xd8\x05\x06\x801\xd8\x05\x06\x801\xd8\x06\x07\x881\x82f\xd8\x07\x08\x80Q\xe0\x05\x07\x811r\t\x00\x00\x00') #hot path -instructions = disassemble_bytecode(b'c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x01\xf3T\x00\x00\x00\x97\x00d\x00d\x01l\x00m\x01Z\x01\x01\x00d\x00Z\x02d\x00Z\x03e\x02d\x02k\x02\x00\x00r\x19e\x02d\x03z\x06\x00\x00d\x00k(\x00\x00r\x03d\x04Z\x03n\x02d\x03Z\x03e\x02d\x04z\r\x00\x00Z\x02e\x02d\x02k\x02\x00\x00r\x01\x8c\x18y\x05y\x05)\x06\xe9\x00\x00\x00\x00)\x01\xda\x0bannotations\xe9\x0f\x00\x00\x00\xe9\x02\x00\x00\x00\xe9\x01\x00\x00\x00N)\x04\xda\n__future__r\x02\x00\x00\x00\xda\x01a\xda\x01b\xa9\x00\xf3\x00\x00\x00\x00\xfaR/Users/jakobtherkelsen/Documents/jaseci-ginS/jac/examples/ginsScripts/hot_path.jac\xfa\x08r\x0c\x00\x00\x00\x01\x00\x00\x00sD\x00\x00\x00\xf0\x03\x01\x01\x01\xf5\x02\x0c\x02\x03\xd8\x07\x08\x801\xd8\x07\x08\x801\xd8\t\n\x88R\x8a\x16\xd8\x08\t\x88A\x89\x05\x90\x11\x8a\n\xd8\x0b\x0c\x81q\xf0\x06\x00\x0c\r\x80q\xe0\x05\x06\x88!\x81W\x80Q\xf0\x0f\x00\n\x0b\x88R\x8d\x16r\n\x00\x00\x00') -#guess_game_bc = disassemble_bytecode(b'c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x01\xf3\x9e\x01\x00\x00\x97\x00d\x00Z\x00d\x01d\x02l\x01m\x02Z\x02\x01\x00d\x01d\x03l\x03m\x04Z\x05\x01\x00d\x01d\x04l\x06Z\x07d\x01d\x05l\x08m\tZ\n\x01\x00d\x01d\x06l\x0b\xad\x02\x01\x00d\x01d\x07l\x0cm\rZ\x0e\x01\x00e\x07j\x1e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00r\x05d\x01d\x04l\x10Z\x10n\x10\x02\x00e\x05d\x08e\x11d\td\nd\x04i\x00\xac\x0b\xab\x06\x00\x00\x00\x00\x00\x00\\\x01\x00\x00Z\x10\x02\x00e\nj$\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00g\x00g\x00\xac\x0c\xab\x02\x00\x00\x00\x00\x00\x00\x02\x00e\x0ed\n\xac\r\xab\x01\x00\x00\x00\x00\x00\x00\x02\x00G\x00d\x0e\x84\x00d\x0fe\nj&\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xab\x03\x00\x00\x00\x00\x00\x00\xab\x00\x00\x00\x00\x00\x00\x00\xab\x00\x00\x00\x00\x00\x00\x00Z\x14\x02\x00e\nj$\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00g\x00g\x00\xac\x0c\xab\x02\x00\x00\x00\x00\x00\x00\x02\x00e\x0ed\n\xac\r\xab\x01\x00\x00\x00\x00\x00\x00\x02\x00G\x00d\x10\x84\x00d\x11e\x14e\nj&\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xab\x04\x00\x00\x00\x00\x00\x00\xab\x00\x00\x00\x00\x00\x00\x00\xab\x00\x00\x00\x00\x00\x00\x00Z\x15\t\x00\x02\x00e\x15\xab\x00\x00\x00\x00\x00\x00\x00Z\x16e\x16j/\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xab\x00\x00\x00\x00\x00\x00\x00\x01\x00y\x04)\x12\xfa\x16A Number Guessing Game\xe9\x00\x00\x00\x00)\x01\xda\x0bannotations)\x01\xda\njac_importN)\x01\xda\nJacFeature)\x01\xda\x01*)\x01\xda\tdataclass\xda\x06random\xda\x02pyF)\x06\xda\x06target\xda\tbase_path\xda\x03lng\xda\x06absorb\xda\tmdl_alias\xda\x05items)\x02\xda\x08on_entry\xda\x07on_exit)\x01\xda\x02eqc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x01\xf3 \x00\x00\x00\x97\x00e\x00Z\x01d\x00Z\x02d\x01Z\x03d\x05d\x02\x84\x04Z\x04d\x06d\x03\x84\x04Z\x05y\x04)\x07\xda\x04Game\xe1\x1a\x01\x00\x00\nA generic Game base class.\n\nThe obj keyword is used to define the class.\nThe can keyword is used to define methods (functions) within the class.\nThe self keyword is used to refer to the current instance of the class.\nConstructors are defined using the init method with parameters.\nc\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x01\xf3 \x00\x00\x00\x97\x00|\x01|\x00_\x00\x00\x00\x00\x00\x00\x00\x00\x00d\x01|\x00_\x01\x00\x00\x00\x00\x00\x00\x00\x00y\x00)\x02NF)\x02\xda\x08attempts\xda\x03won)\x02\xda\x04selfr\x17\x00\x00\x00s\x02\x00\x00\x00 \xfaT/Users/jakobtherkelsen/Documents/jaseci-ginS/jac/examples/guess_game/guess_game1.jac\xda\x08__init__z\rGame.__init__\x0e\x00\x00\x00s\x10\x00\x00\x00\x80\x00\xd8\x19!\x88\x14\x8c\x1d\xd8\x14\x19\x88\x14\x8d\x18\xf3\x00\x00\x00\x00c\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03\x00\x00\x01\xf3\x18\x00\x00\x00\x97\x00t\x01\x00\x00\x00\x00\x00\x00\x00\x00d\x01\xab\x01\x00\x00\x00\x00\x00\x00\x82\x01)\x02N\xfa&Subclasses must implement this method.)\x01\xda\x13NotImplementedError)\x01r\x19\x00\x00\x00s\x01\x00\x00\x00 r\x1a\x00\x00\x00\xda\x04playz\tGame.play\x13\x00\x00\x00s\x12\x00\x00\x00\x80\x00\xdc\x0f"\xd8\r5\xf3\x03\x02\x10\x10\xf0\x00\x02\n\x0cr\x1c\x00\x00\x00N\xa9\x04r\x17\x00\x00\x00\xda\x03int\xda\x06return\xda\x04None\xa9\x02r#\x00\x00\x00r$\x00\x00\x00)\x06\xda\x08__name__\xda\n__module__\xda\x0c__qualname__\xda\x07__doc__r\x1b\x00\x00\x00r \x00\x00\x00\xa9\x00r\x1c\x00\x00\x00r\x1a\x00\x00\x00r\x14\x00\x00\x00r\x14\x00\x00\x00\x05\x00\x00\x00s\x11\x00\x00\x00\x84\x00\xf1\x00\x07\x02\x05\xf3\x12\x03\x06\x07\xf4\n\x04\x06\x07r\x1c\x00\x00\x00r\x14\x00\x00\x00c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x01\xf36\x00\x00\x00\x87\x00\x97\x00e\x00Z\x01d\x00Z\x02d\x01Z\x03d\x05d\x06\x88\x00f\x01d\x02\x84\rZ\x04d\x07d\x03\x84\x04Z\x05d\x08d\x04\x84\x04Z\x06\x88\x00x\x01Z\x07S\x00)\t\xda\x12GuessTheNumberGame\xfa\xae\nA number guessing game. The player must guess a number between 1 and 100.\n\nThis class inherits from Game. The super() function is used to call the parent class constructor.\nc\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x03\x00\x00\x01\xf3Z\x00\x00\x00\x95\x01\x97\x00t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x89\x02|\x00\x8d\x05\x00\x00|\x01\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00t\x05\x00\x00\x00\x00\x00\x00\x00\x00j\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00d\x01d\x02\xab\x02\x00\x00\x00\x00\x00\x00|\x00_\x04\x00\x00\x00\x00\x00\x00\x00\x00y\x00)\x03N\xe9\x01\x00\x00\x00\xe9d\x00\x00\x00)\x05\xda\x05superr\x1b\x00\x00\x00r\x08\x00\x00\x00\xda\x07randint\xda\x0ecorrect_number)\x03r\x19\x00\x00\x00r\x17\x00\x00\x00\xda\t__class__s\x03\x00\x00\x00 \x80r\x1a\x00\x00\x00r\x1b\x00\x00\x00z\x1bGuessTheNumberGame.__init__ \x00\x00\x00s \x00\x00\x00\xf8\x80\x00\xde\t\x0e\x89\x1a\x90H\xd4\t\x1d\xdc\x1f%\x9f~\x99~\xa8a\xb0\x13\xd3\x1f5\x88\x14\xd5\t\x1cr\x1c\x00\x00\x00c\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x03\x00\x00\x01\xf3\xf4\x00\x00\x00\x97\x00|\x00j\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00d\x01kD\x00\x00rQt\x03\x00\x00\x00\x00\x00\x00\x00\x00d\x02\xab\x01\x00\x00\x00\x00\x00\x00}\x01|\x01j\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xab\x00\x00\x00\x00\x00\x00\x00r\x1b|\x00j\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00t\t\x00\x00\x00\x00\x00\x00\x00\x00|\x01\xab\x01\x00\x00\x00\x00\x00\x00\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00n\x0bt\x0b\x00\x00\x00\x00\x00\x00\x00\x00d\x03\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00|\x00j\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00d\x01kD\x00\x00r\x01\x8cQ|\x00j\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00s\x0ct\x0b\x00\x00\x00\x00\x00\x00\x00\x00d\x04\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00y\x00y\x00)\x05Nr\x02\x00\x00\x00\xfa"Guess a number between 1 and 100: \xfa%That\'s not a valid number! Try again.\xfa:Sorry, you didn\'t guess the number. Better luck next time!)\x07r\x17\x00\x00\x00\xda\x05input\xda\x07isdigit\xda\rprocess_guessr"\x00\x00\x00\xda\x05printr\x18\x00\x00\x00\xa9\x02r\x19\x00\x00\x00\xda\x05guesss\x02\x00\x00\x00 r\x1a\x00\x00\x00\xfa\x04playz\x17GuessTheNumberGame.play%\x00\x00\x00sd\x00\x00\x00\x80\x00\xe0\x0f\x13\x8f}\x89}\x98q\xd2\x0f \xdc\x15\x1a\xd0\x1b?\xd3\x15@\x88U\xd8\x10\x15\x97\r\x91\r\x94\x0f\xd8\x11\x15\xd7\x11#\xd1\x11#\xa4C\xa8\x05\xa3J\xd5\x11/\xe4\x11\x16\xd0\x17>\xd4\x11?\xf0\x0b\x00\x10\x14\x8f}\x89}\x98q\xd3\x0f \xf0\x10\x00\x11\x15\x97\x08\x92\x08\xdc\r\x12\xd8\x11M\xf5\x03\x02\x0e\x0f\xf0\x03\x00\x11\x19r\x1c\x00\x00\x00c\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x03\x00\x00\x01\xf3\xfe\x00\x00\x00\x97\x00|\x01|\x00j\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00kD\x00\x00r\x0ct\x03\x00\x00\x00\x00\x00\x00\x00\x00d\x01\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00n4|\x01|\x00j\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00k\x02\x00\x00r\x0ct\x03\x00\x00\x00\x00\x00\x00\x00\x00d\x02\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00n\x19t\x03\x00\x00\x00\x00\x00\x00\x00\x00d\x03\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00d\x04|\x00_\x02\x00\x00\x00\x00\x00\x00\x00\x00d\x05|\x00_\x03\x00\x00\x00\x00\x00\x00\x00\x00|\x00x\x01j\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00d\x06z\x17\x00\x00c\x02_\x02\x00\x00\x00\x00\x00\x00\x00\x00t\x03\x00\x00\x00\x00\x00\x00\x00\x00d\x07|\x00j\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9b\x00d\x08\x9d\x03\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00y\x00)\tN\xfa\tToo high!\xfa\x08Too low!\xfa\'Congratulations! You guessed correctly.r\x02\x00\x00\x00Tr/\x00\x00\x00\xfa\tYou have \xfa\x0f attempts left.)\x04r3\x00\x00\x00r<\x00\x00\x00r\x17\x00\x00\x00r\x18\x00\x00\x00r=\x00\x00\x00s\x02\x00\x00\x00 r\x1a\x00\x00\x00\xfa\rprocess_guessz GuessTheNumberGame.process_guess6\x00\x00\x00se\x00\x00\x00\x80\x00\xd8\x0c\x11\x90D\xd7\x14\'\xd1\x14\'\xd2\x0c\'\xdc\r\x12\x90;\xd5\r\x1f\xd8\x10\x15\x98\x04\xd7\x18+\xd1\x18+\xd2\x10+\xdc\r\x12\x90:\xd5\r\x1e\xe4\r\x12\xd0\x13<\xd4\r=\xd8\x1d\x1e\x88T\x8c]\xd8\x18\x1c\x88T\x8cX\xe0\t\r\x8f\x1d\x8a\x1d\x98!\xd1\t\x1c\x8d\x1d\xdc\t\x0e\xd0\x0f9\x984\x9f=\x9a=\xd1\x0f9\xd5\t:r\x1c\x00\x00\x00)\x01\xe9\n\x00\x00\x00r!\x00\x00\x00r%\x00\x00\x00)\x04r>\x00\x00\x00r"\x00\x00\x00r#\x00\x00\x00r$\x00\x00\x00)\x08r&\x00\x00\x00r\'\x00\x00\x00r(\x00\x00\x00r)\x00\x00\x00r\x1b\x00\x00\x00r \x00\x00\x00r;\x00\x00\x00\xda\r__classcell__)\x01r4\x00\x00\x00s\x01\x00\x00\x00@r\x1a\x00\x00\x00r,\x00\x00\x00r,\x00\x00\x00\x1a\x00\x00\x00s\x17\x00\x00\x00\xf8\x84\x00\xf1\x00\x04\x02\x05\xf6\x0c\x03\x06\x07\xf3\n\x0f\x06\x07\xf7"\x0c\x06\x07r\x1c\x00\x00\x00r,\x00\x00\x00)\x18r)\x00\x00\x00\xda\n__future__r\x03\x00\x00\x00\xda\x07jaclangr\x04\x00\x00\x00\xda\x0e__jac_import__\xda\x06typing\xda\x08_jac_typ\xda\x16jaclang.plugin.featurer\x05\x00\x00\x00\xda\x04_Jac\xda\x16jaclang.plugin.builtin\xda\x0bdataclassesr\x07\x00\x00\x00\xda\x11__jac_dataclass__\xda\rTYPE_CHECKINGr\x08\x00\x00\x00\xda\x08__file__\xda\x08make_obj\xda\x03Objr\x14\x00\x00\x00r,\x00\x00\x00\xda\x04gamer \x00\x00\x00r*\x00\x00\x00r\x1c\x00\x00\x00r\x1a\x00\x00\x00\xda\x08rX\x00\x00\x00\x01\x00\x00\x00s\xaa\x00\x00\x00\xf0\x03\x01\x01\x01\xd9\x01\x1d\xf7\x00K\x01\x02\x03\xf7\x00K\x01\x02\x03\xf7\x00K\x01\x02\x03\xf7\x00K\x01\x02\x03\xf0\x00K\x01\x02\x03\xe7\x01\x12\xd7\x01\x12\xd4\x01\x12\x80s\xd7\x01\x12\xd2\x01\x12\xf1\x04\x13\x02\x03\xef&\xe9\x00\xf7\'\x13\x02\x03\xf7\x00\x13\x02\x03\xf4\x00\x13\x02\x03\xef&\xe9\x00\xf7\'\x13\x02\x03\xf4\x00\x13\x02\x03\xf1*)\x02\x03\xefR\x01\xe9\x00\xf7S\x01)\x02\x03\xf7\x00)\x02\x03\xf3\x00)\x02\x03\xf0\n\x00\x1a\x1e\xf0\x0b)\x02\x03\xefR\x01\xe9\x00\xf7S\x01)\x02\x03\xf4\x00)\x02\x03\xf0X\x01\x02\x02\x05\xf1\x08\x00\r\x1f\xd3\x0c \x80T\xd8\x05\t\x87Y\x81Y\x85[r\x1c\x00\x00\x00') -BBs = create_BBs(instructions) -print(BBs) - -cfg = create_cfg(BBs) -print("\nControl Flow Graph (CFG):") -print(cfg) +# instructions = disassemble_bytecode(b'c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x01\xf3T\x00\x00\x00\x97\x00d\x00d\x01l\x00m\x01Z\x01\x01\x00d\x00Z\x02d\x00Z\x03e\x02d\x02k\x02\x00\x00r\x19e\x02d\x03z\x06\x00\x00d\x00k(\x00\x00r\x03d\x04Z\x03n\x02d\x03Z\x03e\x02d\x04z\r\x00\x00Z\x02e\x02d\x02k\x02\x00\x00r\x01\x8c\x18y\x05y\x05)\x06\xe9\x00\x00\x00\x00)\x01\xda\x0bannotations\xe9\x0f\x00\x00\x00\xe9\x02\x00\x00\x00\xe9\x01\x00\x00\x00N)\x04\xda\n__future__r\x02\x00\x00\x00\xda\x01a\xda\x01b\xa9\x00\xf3\x00\x00\x00\x00\xfaR/Users/jakobtherkelsen/Documents/jaseci-ginS/jac/examples/ginsScripts/hot_path.jac\xfa\x08r\x0c\x00\x00\x00\x01\x00\x00\x00sD\x00\x00\x00\xf0\x03\x01\x01\x01\xf5\x02\x0c\x02\x03\xd8\x07\x08\x801\xd8\x07\x08\x801\xd8\t\n\x88R\x8a\x16\xd8\x08\t\x88A\x89\x05\x90\x11\x8a\n\xd8\x0b\x0c\x81q\xf0\x06\x00\x0c\r\x80q\xe0\x05\x06\x88!\x81W\x80Q\xf0\x0f\x00\n\x0b\x88R\x8d\x16r\n\x00\x00\x00') +# #guess_game_bc = disassemble_bytecode(b'c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x01\xf3\x9e\x01\x00\x00\x97\x00d\x00Z\x00d\x01d\x02l\x01m\x02Z\x02\x01\x00d\x01d\x03l\x03m\x04Z\x05\x01\x00d\x01d\x04l\x06Z\x07d\x01d\x05l\x08m\tZ\n\x01\x00d\x01d\x06l\x0b\xad\x02\x01\x00d\x01d\x07l\x0cm\rZ\x0e\x01\x00e\x07j\x1e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00r\x05d\x01d\x04l\x10Z\x10n\x10\x02\x00e\x05d\x08e\x11d\td\nd\x04i\x00\xac\x0b\xab\x06\x00\x00\x00\x00\x00\x00\\\x01\x00\x00Z\x10\x02\x00e\nj$\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00g\x00g\x00\xac\x0c\xab\x02\x00\x00\x00\x00\x00\x00\x02\x00e\x0ed\n\xac\r\xab\x01\x00\x00\x00\x00\x00\x00\x02\x00G\x00d\x0e\x84\x00d\x0fe\nj&\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xab\x03\x00\x00\x00\x00\x00\x00\xab\x00\x00\x00\x00\x00\x00\x00\xab\x00\x00\x00\x00\x00\x00\x00Z\x14\x02\x00e\nj$\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00g\x00g\x00\xac\x0c\xab\x02\x00\x00\x00\x00\x00\x00\x02\x00e\x0ed\n\xac\r\xab\x01\x00\x00\x00\x00\x00\x00\x02\x00G\x00d\x10\x84\x00d\x11e\x14e\nj&\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xab\x04\x00\x00\x00\x00\x00\x00\xab\x00\x00\x00\x00\x00\x00\x00\xab\x00\x00\x00\x00\x00\x00\x00Z\x15\t\x00\x02\x00e\x15\xab\x00\x00\x00\x00\x00\x00\x00Z\x16e\x16j/\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xab\x00\x00\x00\x00\x00\x00\x00\x01\x00y\x04)\x12\xfa\x16A Number Guessing Game\xe9\x00\x00\x00\x00)\x01\xda\x0bannotations)\x01\xda\njac_importN)\x01\xda\nJacFeature)\x01\xda\x01*)\x01\xda\tdataclass\xda\x06random\xda\x02pyF)\x06\xda\x06target\xda\tbase_path\xda\x03lng\xda\x06absorb\xda\tmdl_alias\xda\x05items)\x02\xda\x08on_entry\xda\x07on_exit)\x01\xda\x02eqc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x01\xf3 \x00\x00\x00\x97\x00e\x00Z\x01d\x00Z\x02d\x01Z\x03d\x05d\x02\x84\x04Z\x04d\x06d\x03\x84\x04Z\x05y\x04)\x07\xda\x04Game\xe1\x1a\x01\x00\x00\nA generic Game base class.\n\nThe obj keyword is used to define the class.\nThe can keyword is used to define methods (functions) within the class.\nThe self keyword is used to refer to the current instance of the class.\nConstructors are defined using the init method with parameters.\nc\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x01\xf3 \x00\x00\x00\x97\x00|\x01|\x00_\x00\x00\x00\x00\x00\x00\x00\x00\x00d\x01|\x00_\x01\x00\x00\x00\x00\x00\x00\x00\x00y\x00)\x02NF)\x02\xda\x08attempts\xda\x03won)\x02\xda\x04selfr\x17\x00\x00\x00s\x02\x00\x00\x00 \xfaT/Users/jakobtherkelsen/Documents/jaseci-ginS/jac/examples/guess_game/guess_game1.jac\xda\x08__init__z\rGame.__init__\x0e\x00\x00\x00s\x10\x00\x00\x00\x80\x00\xd8\x19!\x88\x14\x8c\x1d\xd8\x14\x19\x88\x14\x8d\x18\xf3\x00\x00\x00\x00c\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03\x00\x00\x01\xf3\x18\x00\x00\x00\x97\x00t\x01\x00\x00\x00\x00\x00\x00\x00\x00d\x01\xab\x01\x00\x00\x00\x00\x00\x00\x82\x01)\x02N\xfa&Subclasses must implement this method.)\x01\xda\x13NotImplementedError)\x01r\x19\x00\x00\x00s\x01\x00\x00\x00 r\x1a\x00\x00\x00\xda\x04playz\tGame.play\x13\x00\x00\x00s\x12\x00\x00\x00\x80\x00\xdc\x0f"\xd8\r5\xf3\x03\x02\x10\x10\xf0\x00\x02\n\x0cr\x1c\x00\x00\x00N\xa9\x04r\x17\x00\x00\x00\xda\x03int\xda\x06return\xda\x04None\xa9\x02r#\x00\x00\x00r$\x00\x00\x00)\x06\xda\x08__name__\xda\n__module__\xda\x0c__qualname__\xda\x07__doc__r\x1b\x00\x00\x00r \x00\x00\x00\xa9\x00r\x1c\x00\x00\x00r\x1a\x00\x00\x00r\x14\x00\x00\x00r\x14\x00\x00\x00\x05\x00\x00\x00s\x11\x00\x00\x00\x84\x00\xf1\x00\x07\x02\x05\xf3\x12\x03\x06\x07\xf4\n\x04\x06\x07r\x1c\x00\x00\x00r\x14\x00\x00\x00c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x01\xf36\x00\x00\x00\x87\x00\x97\x00e\x00Z\x01d\x00Z\x02d\x01Z\x03d\x05d\x06\x88\x00f\x01d\x02\x84\rZ\x04d\x07d\x03\x84\x04Z\x05d\x08d\x04\x84\x04Z\x06\x88\x00x\x01Z\x07S\x00)\t\xda\x12GuessTheNumberGame\xfa\xae\nA number guessing game. The player must guess a number between 1 and 100.\n\nThis class inherits from Game. The super() function is used to call the parent class constructor.\nc\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x03\x00\x00\x01\xf3Z\x00\x00\x00\x95\x01\x97\x00t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x89\x02|\x00\x8d\x05\x00\x00|\x01\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00t\x05\x00\x00\x00\x00\x00\x00\x00\x00j\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00d\x01d\x02\xab\x02\x00\x00\x00\x00\x00\x00|\x00_\x04\x00\x00\x00\x00\x00\x00\x00\x00y\x00)\x03N\xe9\x01\x00\x00\x00\xe9d\x00\x00\x00)\x05\xda\x05superr\x1b\x00\x00\x00r\x08\x00\x00\x00\xda\x07randint\xda\x0ecorrect_number)\x03r\x19\x00\x00\x00r\x17\x00\x00\x00\xda\t__class__s\x03\x00\x00\x00 \x80r\x1a\x00\x00\x00r\x1b\x00\x00\x00z\x1bGuessTheNumberGame.__init__ \x00\x00\x00s \x00\x00\x00\xf8\x80\x00\xde\t\x0e\x89\x1a\x90H\xd4\t\x1d\xdc\x1f%\x9f~\x99~\xa8a\xb0\x13\xd3\x1f5\x88\x14\xd5\t\x1cr\x1c\x00\x00\x00c\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x03\x00\x00\x01\xf3\xf4\x00\x00\x00\x97\x00|\x00j\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00d\x01kD\x00\x00rQt\x03\x00\x00\x00\x00\x00\x00\x00\x00d\x02\xab\x01\x00\x00\x00\x00\x00\x00}\x01|\x01j\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xab\x00\x00\x00\x00\x00\x00\x00r\x1b|\x00j\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00t\t\x00\x00\x00\x00\x00\x00\x00\x00|\x01\xab\x01\x00\x00\x00\x00\x00\x00\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00n\x0bt\x0b\x00\x00\x00\x00\x00\x00\x00\x00d\x03\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00|\x00j\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00d\x01kD\x00\x00r\x01\x8cQ|\x00j\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00s\x0ct\x0b\x00\x00\x00\x00\x00\x00\x00\x00d\x04\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00y\x00y\x00)\x05Nr\x02\x00\x00\x00\xfa"Guess a number between 1 and 100: \xfa%That\'s not a valid number! Try again.\xfa:Sorry, you didn\'t guess the number. Better luck next time!)\x07r\x17\x00\x00\x00\xda\x05input\xda\x07isdigit\xda\rprocess_guessr"\x00\x00\x00\xda\x05printr\x18\x00\x00\x00\xa9\x02r\x19\x00\x00\x00\xda\x05guesss\x02\x00\x00\x00 r\x1a\x00\x00\x00\xfa\x04playz\x17GuessTheNumberGame.play%\x00\x00\x00sd\x00\x00\x00\x80\x00\xe0\x0f\x13\x8f}\x89}\x98q\xd2\x0f \xdc\x15\x1a\xd0\x1b?\xd3\x15@\x88U\xd8\x10\x15\x97\r\x91\r\x94\x0f\xd8\x11\x15\xd7\x11#\xd1\x11#\xa4C\xa8\x05\xa3J\xd5\x11/\xe4\x11\x16\xd0\x17>\xd4\x11?\xf0\x0b\x00\x10\x14\x8f}\x89}\x98q\xd3\x0f \xf0\x10\x00\x11\x15\x97\x08\x92\x08\xdc\r\x12\xd8\x11M\xf5\x03\x02\x0e\x0f\xf0\x03\x00\x11\x19r\x1c\x00\x00\x00c\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x03\x00\x00\x01\xf3\xfe\x00\x00\x00\x97\x00|\x01|\x00j\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00kD\x00\x00r\x0ct\x03\x00\x00\x00\x00\x00\x00\x00\x00d\x01\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00n4|\x01|\x00j\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00k\x02\x00\x00r\x0ct\x03\x00\x00\x00\x00\x00\x00\x00\x00d\x02\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00n\x19t\x03\x00\x00\x00\x00\x00\x00\x00\x00d\x03\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00d\x04|\x00_\x02\x00\x00\x00\x00\x00\x00\x00\x00d\x05|\x00_\x03\x00\x00\x00\x00\x00\x00\x00\x00|\x00x\x01j\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00d\x06z\x17\x00\x00c\x02_\x02\x00\x00\x00\x00\x00\x00\x00\x00t\x03\x00\x00\x00\x00\x00\x00\x00\x00d\x07|\x00j\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9b\x00d\x08\x9d\x03\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00y\x00)\tN\xfa\tToo high!\xfa\x08Too low!\xfa\'Congratulations! You guessed correctly.r\x02\x00\x00\x00Tr/\x00\x00\x00\xfa\tYou have \xfa\x0f attempts left.)\x04r3\x00\x00\x00r<\x00\x00\x00r\x17\x00\x00\x00r\x18\x00\x00\x00r=\x00\x00\x00s\x02\x00\x00\x00 r\x1a\x00\x00\x00\xfa\rprocess_guessz GuessTheNumberGame.process_guess6\x00\x00\x00se\x00\x00\x00\x80\x00\xd8\x0c\x11\x90D\xd7\x14\'\xd1\x14\'\xd2\x0c\'\xdc\r\x12\x90;\xd5\r\x1f\xd8\x10\x15\x98\x04\xd7\x18+\xd1\x18+\xd2\x10+\xdc\r\x12\x90:\xd5\r\x1e\xe4\r\x12\xd0\x13<\xd4\r=\xd8\x1d\x1e\x88T\x8c]\xd8\x18\x1c\x88T\x8cX\xe0\t\r\x8f\x1d\x8a\x1d\x98!\xd1\t\x1c\x8d\x1d\xdc\t\x0e\xd0\x0f9\x984\x9f=\x9a=\xd1\x0f9\xd5\t:r\x1c\x00\x00\x00)\x01\xe9\n\x00\x00\x00r!\x00\x00\x00r%\x00\x00\x00)\x04r>\x00\x00\x00r"\x00\x00\x00r#\x00\x00\x00r$\x00\x00\x00)\x08r&\x00\x00\x00r\'\x00\x00\x00r(\x00\x00\x00r)\x00\x00\x00r\x1b\x00\x00\x00r \x00\x00\x00r;\x00\x00\x00\xda\r__classcell__)\x01r4\x00\x00\x00s\x01\x00\x00\x00@r\x1a\x00\x00\x00r,\x00\x00\x00r,\x00\x00\x00\x1a\x00\x00\x00s\x17\x00\x00\x00\xf8\x84\x00\xf1\x00\x04\x02\x05\xf6\x0c\x03\x06\x07\xf3\n\x0f\x06\x07\xf7"\x0c\x06\x07r\x1c\x00\x00\x00r,\x00\x00\x00)\x18r)\x00\x00\x00\xda\n__future__r\x03\x00\x00\x00\xda\x07jaclangr\x04\x00\x00\x00\xda\x0e__jac_import__\xda\x06typing\xda\x08_jac_typ\xda\x16jaclang.plugin.featurer\x05\x00\x00\x00\xda\x04_Jac\xda\x16jaclang.plugin.builtin\xda\x0bdataclassesr\x07\x00\x00\x00\xda\x11__jac_dataclass__\xda\rTYPE_CHECKINGr\x08\x00\x00\x00\xda\x08__file__\xda\x08make_obj\xda\x03Objr\x14\x00\x00\x00r,\x00\x00\x00\xda\x04gamer \x00\x00\x00r*\x00\x00\x00r\x1c\x00\x00\x00r\x1a\x00\x00\x00\xda\x08rX\x00\x00\x00\x01\x00\x00\x00s\xaa\x00\x00\x00\xf0\x03\x01\x01\x01\xd9\x01\x1d\xf7\x00K\x01\x02\x03\xf7\x00K\x01\x02\x03\xf7\x00K\x01\x02\x03\xf7\x00K\x01\x02\x03\xf0\x00K\x01\x02\x03\xe7\x01\x12\xd7\x01\x12\xd4\x01\x12\x80s\xd7\x01\x12\xd2\x01\x12\xf1\x04\x13\x02\x03\xef&\xe9\x00\xf7\'\x13\x02\x03\xf7\x00\x13\x02\x03\xf4\x00\x13\x02\x03\xef&\xe9\x00\xf7\'\x13\x02\x03\xf4\x00\x13\x02\x03\xf1*)\x02\x03\xefR\x01\xe9\x00\xf7S\x01)\x02\x03\xf7\x00)\x02\x03\xf3\x00)\x02\x03\xf0\n\x00\x1a\x1e\xf0\x0b)\x02\x03\xefR\x01\xe9\x00\xf7S\x01)\x02\x03\xf4\x00)\x02\x03\xf0X\x01\x02\x02\x05\xf1\x08\x00\r\x1f\xd3\x0c \x80T\xd8\x05\t\x87Y\x81Y\x85[r\x1c\x00\x00\x00') +# BBs = create_BBs(instructions) +# print(BBs) + +# cfg = create_cfg(BBs) +# print("\nControl Flow Graph (CFG):") +# print(cfg) # # Visualize CFG # dot = visualize_cfg(cfg) From 35b294f4ebb27f76bdefaaf7931606bffb273813 Mon Sep 17 00:00:00 2001 From: Jakob Louis Therkelsen Date: Mon, 18 Nov 2024 15:42:01 -0500 Subject: [PATCH 26/84] adding AI --- jac/examples/ginsScripts/cfg.gv | 21 ++++++++++++++++++ jac/examples/ginsScripts/cfg.gv.pdf | Bin 0 -> 12070 bytes .../compiler/passes/main/cfg_gen_pass.py | 7 +++--- jac/jaclang/runtimelib/cfg.py | 4 ++-- jac/jaclang/runtimelib/machine.py | 20 +++++++++++++---- test_ai.py | 7 ------ 6 files changed, 42 insertions(+), 17 deletions(-) create mode 100644 jac/examples/ginsScripts/cfg.gv create mode 100644 jac/examples/ginsScripts/cfg.gv.pdf delete mode 100644 test_ai.py diff --git a/jac/examples/ginsScripts/cfg.gv b/jac/examples/ginsScripts/cfg.gv new file mode 100644 index 0000000000..8054261d06 --- /dev/null +++ b/jac/examples/ginsScripts/cfg.gv @@ -0,0 +1,21 @@ +// Control Flow Graph +digraph { + bb0 [label=BB0] + bb1 [label=BB1] + bb2 [label=BB2] + bb3 [label=BB3] + bb4 [label=BB4] + bb5 [label=BB5] + bb6 [label=BB6] + bb7 [label=BB7] + bb0 -> bb7 + bb0 -> bb1 + bb1 -> bb3 + bb1 -> bb2 + bb3 -> bb4 + bb4 -> bb6 + bb4 -> bb5 + bb5 -> bb1 + bb6 -> bb7 + bb7 -> bb7 +} diff --git a/jac/examples/ginsScripts/cfg.gv.pdf b/jac/examples/ginsScripts/cfg.gv.pdf new file mode 100644 index 0000000000000000000000000000000000000000..fbb35f8d8a9002df57210532900914b3c7f3c793 GIT binary patch literal 12070 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 literal 0 HcmV?d00001 diff --git a/jac/jaclang/compiler/passes/main/cfg_gen_pass.py b/jac/jaclang/compiler/passes/main/cfg_gen_pass.py index ca305b5bb2..057537509a 100644 --- a/jac/jaclang/compiler/passes/main/cfg_gen_pass.py +++ b/jac/jaclang/compiler/passes/main/cfg_gen_pass.py @@ -37,10 +37,9 @@ def enter_module(self, node: ast.Module) -> None: BBs = create_BBs(instructions) cfg = create_cfg(BBs) module_cfgs[mod.name] = cfg - # for cfg in module_cfgs.values(): - # dot = visualize_cfg(cfg) - # print(dot) - # dot.render('cfg.gv', view=True) + for cfg in module_cfgs.values(): + dot = visualize_cfg(cfg) + dot.render('cfg.gv', view=True) if JacMachine.get().gin: try: JacMachine.get().gin.get_cfgs(cfgs=module_cfgs) diff --git a/jac/jaclang/runtimelib/cfg.py b/jac/jaclang/runtimelib/cfg.py index 264c688119..c6006bf6cf 100644 --- a/jac/jaclang/runtimelib/cfg.py +++ b/jac/jaclang/runtimelib/cfg.py @@ -6,8 +6,8 @@ import dis from collections import defaultdict from typing import List, Optional, Iterator -# import graphviz -# from graphviz import Digraph +import graphviz +from graphviz import Digraph class BytecodeOp: def __init__(self, op: int, arg: int, offset: int, argval:int, is_jump_target: bool) -> None: diff --git a/jac/jaclang/runtimelib/machine.py b/jac/jaclang/runtimelib/machine.py index fd70c33e2c..51ead66056 100644 --- a/jac/jaclang/runtimelib/machine.py +++ b/jac/jaclang/runtimelib/machine.py @@ -9,6 +9,7 @@ import sys import tempfile import types +import google.generativeai as genai from threading import Thread from contextvars import ContextVar from typing import Optional, Union @@ -335,9 +336,20 @@ def get_cfgs(self,cfgs: any): self.cfgs = cfgs def start_ghost(self): - self.__daemon_thread:Thread = Thread(target=self.worker) - self.__daemon_thread.start() + self.__ghost_thread:Thread = Thread(target=self.worker) + self.__ghost_thread.start() def worker(self): - - print(self.cfgs) \ No newline at end of file + genai.configure(api_key=os.getenv("GEN_AI_KEY")) + model = genai.GenerativeModel("gemini-1.5-flash") + response_dict = {'cfg': self.cfgs} + prompt = [] + for k,v in response_dict.items(): + prompt.append(f"here is my {k}:\n{v}") + prompt.append("\nCan you identify where the code could have an error?") + response = model.generate_content("".join(prompt)) + + print("PROMPT:\n") + print("".join(prompt)) + print("RESPONSE:\n") + print(response.text) \ No newline at end of file diff --git a/test_ai.py b/test_ai.py deleted file mode 100644 index 1e0217c1dc..0000000000 --- a/test_ai.py +++ /dev/null @@ -1,7 +0,0 @@ -import google.generativeai as genai -import os - -genai.configure(api_key="AIzaSyAU24V8wy2H7JihQvceZMiKIIBzr5Nqulc") -model = genai.GenerativeModel("gemini-1.5-flash") -response = model.generate_content("Write another") -print(response.text) \ No newline at end of file From fe4b52502be0e8fef3d63e553dc71ae5bc741940 Mon Sep 17 00:00:00 2001 From: Jakob Louis Therkelsen Date: Mon, 18 Nov 2024 16:04:12 -0500 Subject: [PATCH 27/84] include information on BB instructions --- jac/examples/ginsScripts/cfg.gv.pdf | Bin 12070 -> 12070 bytes jac/examples/ginsScripts/hot_path.jac | 4 +++- .../compiler/passes/main/cfg_gen_pass.py | 3 ++- jac/jaclang/runtimelib/cfg.py | 10 ++++++---- 4 files changed, 11 insertions(+), 6 deletions(-) diff --git a/jac/examples/ginsScripts/cfg.gv.pdf b/jac/examples/ginsScripts/cfg.gv.pdf index fbb35f8d8a9002df57210532900914b3c7f3c793..6be595fa2f8ab8b1f29bb36c61e410b5efc8aea2 100644 GIT binary patch delta 290 zcmV+-0p0$lUZ!5K@hpEaYr`-Ugm?XlTT1Prwxrlj8cc>H5K1Y8q+97AWZ?*kWhA*Y z|GttPrxZ=^GX|N!fVs*g;z-S zYfgE=7+bN5^2PHLEgvaOXOq8JcnH>U|0t}AIbyOAys1Wut@#OYX?T29qF7e<(47x* zhvKe3STppf>o~-D@)+ri&VgFdxjuTy>x^IE?V#pq7gT%ot))60wh@NRk)M<^gO$o* oarZojMd_#LE?gDiU%j31;>)zRcHsiIazXS9HJWbavji?80VWlbl>h($ delta 290 zcmV+-0p0$lUZ!5K@hpGAYlAQt#qa(V?=n^ot4Y-AiuBMH$`}K&yNw+}8f;(~N#a=l z`z2Z(Bd71j`|{r7qaYF8ASV$6&1pmnq(v506_WQ`FOk%|l{Ny9ysC@E2N(z%e2(a# zht7dUyWO}^8+{psG*}6)j0RoPa?P;1I@jB6l8m%9yuT`8*V=!yaXfuvBzH=8NA4t6 z$1Ni)qm-63PoJ~R6UiS5iD#3)Sa|T(VZY`^h8!W;2;SsH@xA`>afyGd%#jtFC3NS! z+#*}_C!>cRRTYLXPaY$k(b-eOJKF~@ahvfAoEhXi9lYu&zm<^9X&<1^9C#zG9*mF{ o>Ee0zi^5IOt-lq*zj_Dm_?K?)?feDq<-F(@JsxiCvji?80i6hs%K!iX diff --git a/jac/examples/ginsScripts/hot_path.jac b/jac/examples/ginsScripts/hot_path.jac index 29ff0eaa40..d09a7d9f6f 100644 --- a/jac/examples/ginsScripts/hot_path.jac +++ b/jac/examples/ginsScripts/hot_path.jac @@ -1,9 +1,11 @@ with entry { a = 0; b = 0; + c = 0; while a < 15 { if a % 2 == 0{ - b = 1; + c = a+b+7; + } else { b = 2; diff --git a/jac/jaclang/compiler/passes/main/cfg_gen_pass.py b/jac/jaclang/compiler/passes/main/cfg_gen_pass.py index 057537509a..1753a7e74d 100644 --- a/jac/jaclang/compiler/passes/main/cfg_gen_pass.py +++ b/jac/jaclang/compiler/passes/main/cfg_gen_pass.py @@ -34,7 +34,8 @@ def enter_module(self, node: ast.Module) -> None: for mod in mods: bytecode = mod.gen.py_bytecode instructions = disassemble_bytecode(bytecode) - BBs = create_BBs(instructions) + BBs = create_BBs(instructions) + print(BBs) cfg = create_cfg(BBs) module_cfgs[mod.name] = cfg for cfg in module_cfgs.values(): diff --git a/jac/jaclang/runtimelib/cfg.py b/jac/jaclang/runtimelib/cfg.py index c6006bf6cf..91c969ad8e 100644 --- a/jac/jaclang/runtimelib/cfg.py +++ b/jac/jaclang/runtimelib/cfg.py @@ -10,17 +10,18 @@ from graphviz import Digraph class BytecodeOp: - def __init__(self, op: int, arg: int, offset: int, argval:int, is_jump_target: bool) -> None: + def __init__(self, op: int, arg: int, offset: int, argval:int, argrepr:str, is_jump_target: bool) -> None: self.op = op self.arg = arg self.offset = offset self.argval = argval + self.argrepr = argrepr self.is_jump_target= is_jump_target #default the offset self.__offset_size = 0 def __repr__(self): - return f"{self.offset}: {self.op} - {self.arg} - {self.argval}" + return f"Instr: offset={self.offset}, Opname={self.op}, arg={self.arg}, argval={self.argval}, argrepr={self.argrepr}" def is_branch(self) -> bool: return self.op in { "JUMP_ABSOLUTE", @@ -82,7 +83,8 @@ def disassemble_bytecode(bytecode): arg=instr.arg, offset=instr.offset, argval=instr.argval, - is_jump_target=instr.is_jump_target + argrepr=instr.argrepr, + is_jump_target=instr.is_jump_target, )) #set offest size for calculating next instruction #last instruction is default of 2, but shouldn't be needed @@ -238,7 +240,7 @@ def visualize_cfg(cfg: CFG): #instructions = disassemble_bytecode(b'c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x01\xf3*\x00\x00\x00\x97\x00d\x00d\x01l\x00m\x01Z\x01\x01\x00d\x00Z\x02d\x00Z\x03e\x03d\x00k\\\x00\x00r\x02d\x02Z\x02d\x03Z\x02y\x04)\x05\xe9\x00\x00\x00\x00)\x01\xda\x0bannotations\xe9\x01\x00\x00\x00\xe9\xff\xff\xff\xffN)\x04\xda\n__future__r\x02\x00\x00\x00\xda\x01a\xda\x01x\xa9\x00\xf3\x00\x00\x00\x00\xfaP/Users/jakobtherkelsen/Documents/jaseci-ginS/jac/examples/ginsScripts/simple.jac\xfa\x08r\x0b\x00\x00\x00\x01\x00\x00\x00s%\x00\x00\x00\xf0\x03\x01\x01\x01\xf5\x02\x07\x02\x03\xd8\x05\x06\x801\xd8\x05\x06\x801\xd8\x06\x07\x881\x82f\xd8\x07\x08\x80Q\xe0\x05\x07\x811r\t\x00\x00\x00') #hot path # instructions = disassemble_bytecode(b'c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x01\xf3T\x00\x00\x00\x97\x00d\x00d\x01l\x00m\x01Z\x01\x01\x00d\x00Z\x02d\x00Z\x03e\x02d\x02k\x02\x00\x00r\x19e\x02d\x03z\x06\x00\x00d\x00k(\x00\x00r\x03d\x04Z\x03n\x02d\x03Z\x03e\x02d\x04z\r\x00\x00Z\x02e\x02d\x02k\x02\x00\x00r\x01\x8c\x18y\x05y\x05)\x06\xe9\x00\x00\x00\x00)\x01\xda\x0bannotations\xe9\x0f\x00\x00\x00\xe9\x02\x00\x00\x00\xe9\x01\x00\x00\x00N)\x04\xda\n__future__r\x02\x00\x00\x00\xda\x01a\xda\x01b\xa9\x00\xf3\x00\x00\x00\x00\xfaR/Users/jakobtherkelsen/Documents/jaseci-ginS/jac/examples/ginsScripts/hot_path.jac\xfa\x08r\x0c\x00\x00\x00\x01\x00\x00\x00sD\x00\x00\x00\xf0\x03\x01\x01\x01\xf5\x02\x0c\x02\x03\xd8\x07\x08\x801\xd8\x07\x08\x801\xd8\t\n\x88R\x8a\x16\xd8\x08\t\x88A\x89\x05\x90\x11\x8a\n\xd8\x0b\x0c\x81q\xf0\x06\x00\x0c\r\x80q\xe0\x05\x06\x88!\x81W\x80Q\xf0\x0f\x00\n\x0b\x88R\x8d\x16r\n\x00\x00\x00') -# #guess_game_bc = disassemble_bytecode(b'c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x01\xf3\x9e\x01\x00\x00\x97\x00d\x00Z\x00d\x01d\x02l\x01m\x02Z\x02\x01\x00d\x01d\x03l\x03m\x04Z\x05\x01\x00d\x01d\x04l\x06Z\x07d\x01d\x05l\x08m\tZ\n\x01\x00d\x01d\x06l\x0b\xad\x02\x01\x00d\x01d\x07l\x0cm\rZ\x0e\x01\x00e\x07j\x1e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00r\x05d\x01d\x04l\x10Z\x10n\x10\x02\x00e\x05d\x08e\x11d\td\nd\x04i\x00\xac\x0b\xab\x06\x00\x00\x00\x00\x00\x00\\\x01\x00\x00Z\x10\x02\x00e\nj$\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00g\x00g\x00\xac\x0c\xab\x02\x00\x00\x00\x00\x00\x00\x02\x00e\x0ed\n\xac\r\xab\x01\x00\x00\x00\x00\x00\x00\x02\x00G\x00d\x0e\x84\x00d\x0fe\nj&\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xab\x03\x00\x00\x00\x00\x00\x00\xab\x00\x00\x00\x00\x00\x00\x00\xab\x00\x00\x00\x00\x00\x00\x00Z\x14\x02\x00e\nj$\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00g\x00g\x00\xac\x0c\xab\x02\x00\x00\x00\x00\x00\x00\x02\x00e\x0ed\n\xac\r\xab\x01\x00\x00\x00\x00\x00\x00\x02\x00G\x00d\x10\x84\x00d\x11e\x14e\nj&\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xab\x04\x00\x00\x00\x00\x00\x00\xab\x00\x00\x00\x00\x00\x00\x00\xab\x00\x00\x00\x00\x00\x00\x00Z\x15\t\x00\x02\x00e\x15\xab\x00\x00\x00\x00\x00\x00\x00Z\x16e\x16j/\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xab\x00\x00\x00\x00\x00\x00\x00\x01\x00y\x04)\x12\xfa\x16A Number Guessing Game\xe9\x00\x00\x00\x00)\x01\xda\x0bannotations)\x01\xda\njac_importN)\x01\xda\nJacFeature)\x01\xda\x01*)\x01\xda\tdataclass\xda\x06random\xda\x02pyF)\x06\xda\x06target\xda\tbase_path\xda\x03lng\xda\x06absorb\xda\tmdl_alias\xda\x05items)\x02\xda\x08on_entry\xda\x07on_exit)\x01\xda\x02eqc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x01\xf3 \x00\x00\x00\x97\x00e\x00Z\x01d\x00Z\x02d\x01Z\x03d\x05d\x02\x84\x04Z\x04d\x06d\x03\x84\x04Z\x05y\x04)\x07\xda\x04Game\xe1\x1a\x01\x00\x00\nA generic Game base class.\n\nThe obj keyword is used to define the class.\nThe can keyword is used to define methods (functions) within the class.\nThe self keyword is used to refer to the current instance of the class.\nConstructors are defined using the init method with parameters.\nc\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x01\xf3 \x00\x00\x00\x97\x00|\x01|\x00_\x00\x00\x00\x00\x00\x00\x00\x00\x00d\x01|\x00_\x01\x00\x00\x00\x00\x00\x00\x00\x00y\x00)\x02NF)\x02\xda\x08attempts\xda\x03won)\x02\xda\x04selfr\x17\x00\x00\x00s\x02\x00\x00\x00 \xfaT/Users/jakobtherkelsen/Documents/jaseci-ginS/jac/examples/guess_game/guess_game1.jac\xda\x08__init__z\rGame.__init__\x0e\x00\x00\x00s\x10\x00\x00\x00\x80\x00\xd8\x19!\x88\x14\x8c\x1d\xd8\x14\x19\x88\x14\x8d\x18\xf3\x00\x00\x00\x00c\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03\x00\x00\x01\xf3\x18\x00\x00\x00\x97\x00t\x01\x00\x00\x00\x00\x00\x00\x00\x00d\x01\xab\x01\x00\x00\x00\x00\x00\x00\x82\x01)\x02N\xfa&Subclasses must implement this method.)\x01\xda\x13NotImplementedError)\x01r\x19\x00\x00\x00s\x01\x00\x00\x00 r\x1a\x00\x00\x00\xda\x04playz\tGame.play\x13\x00\x00\x00s\x12\x00\x00\x00\x80\x00\xdc\x0f"\xd8\r5\xf3\x03\x02\x10\x10\xf0\x00\x02\n\x0cr\x1c\x00\x00\x00N\xa9\x04r\x17\x00\x00\x00\xda\x03int\xda\x06return\xda\x04None\xa9\x02r#\x00\x00\x00r$\x00\x00\x00)\x06\xda\x08__name__\xda\n__module__\xda\x0c__qualname__\xda\x07__doc__r\x1b\x00\x00\x00r \x00\x00\x00\xa9\x00r\x1c\x00\x00\x00r\x1a\x00\x00\x00r\x14\x00\x00\x00r\x14\x00\x00\x00\x05\x00\x00\x00s\x11\x00\x00\x00\x84\x00\xf1\x00\x07\x02\x05\xf3\x12\x03\x06\x07\xf4\n\x04\x06\x07r\x1c\x00\x00\x00r\x14\x00\x00\x00c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x01\xf36\x00\x00\x00\x87\x00\x97\x00e\x00Z\x01d\x00Z\x02d\x01Z\x03d\x05d\x06\x88\x00f\x01d\x02\x84\rZ\x04d\x07d\x03\x84\x04Z\x05d\x08d\x04\x84\x04Z\x06\x88\x00x\x01Z\x07S\x00)\t\xda\x12GuessTheNumberGame\xfa\xae\nA number guessing game. The player must guess a number between 1 and 100.\n\nThis class inherits from Game. The super() function is used to call the parent class constructor.\nc\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x03\x00\x00\x01\xf3Z\x00\x00\x00\x95\x01\x97\x00t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x89\x02|\x00\x8d\x05\x00\x00|\x01\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00t\x05\x00\x00\x00\x00\x00\x00\x00\x00j\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00d\x01d\x02\xab\x02\x00\x00\x00\x00\x00\x00|\x00_\x04\x00\x00\x00\x00\x00\x00\x00\x00y\x00)\x03N\xe9\x01\x00\x00\x00\xe9d\x00\x00\x00)\x05\xda\x05superr\x1b\x00\x00\x00r\x08\x00\x00\x00\xda\x07randint\xda\x0ecorrect_number)\x03r\x19\x00\x00\x00r\x17\x00\x00\x00\xda\t__class__s\x03\x00\x00\x00 \x80r\x1a\x00\x00\x00r\x1b\x00\x00\x00z\x1bGuessTheNumberGame.__init__ \x00\x00\x00s \x00\x00\x00\xf8\x80\x00\xde\t\x0e\x89\x1a\x90H\xd4\t\x1d\xdc\x1f%\x9f~\x99~\xa8a\xb0\x13\xd3\x1f5\x88\x14\xd5\t\x1cr\x1c\x00\x00\x00c\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x03\x00\x00\x01\xf3\xf4\x00\x00\x00\x97\x00|\x00j\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00d\x01kD\x00\x00rQt\x03\x00\x00\x00\x00\x00\x00\x00\x00d\x02\xab\x01\x00\x00\x00\x00\x00\x00}\x01|\x01j\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xab\x00\x00\x00\x00\x00\x00\x00r\x1b|\x00j\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00t\t\x00\x00\x00\x00\x00\x00\x00\x00|\x01\xab\x01\x00\x00\x00\x00\x00\x00\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00n\x0bt\x0b\x00\x00\x00\x00\x00\x00\x00\x00d\x03\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00|\x00j\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00d\x01kD\x00\x00r\x01\x8cQ|\x00j\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00s\x0ct\x0b\x00\x00\x00\x00\x00\x00\x00\x00d\x04\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00y\x00y\x00)\x05Nr\x02\x00\x00\x00\xfa"Guess a number between 1 and 100: \xfa%That\'s not a valid number! Try again.\xfa:Sorry, you didn\'t guess the number. Better luck next time!)\x07r\x17\x00\x00\x00\xda\x05input\xda\x07isdigit\xda\rprocess_guessr"\x00\x00\x00\xda\x05printr\x18\x00\x00\x00\xa9\x02r\x19\x00\x00\x00\xda\x05guesss\x02\x00\x00\x00 r\x1a\x00\x00\x00\xfa\x04playz\x17GuessTheNumberGame.play%\x00\x00\x00sd\x00\x00\x00\x80\x00\xe0\x0f\x13\x8f}\x89}\x98q\xd2\x0f \xdc\x15\x1a\xd0\x1b?\xd3\x15@\x88U\xd8\x10\x15\x97\r\x91\r\x94\x0f\xd8\x11\x15\xd7\x11#\xd1\x11#\xa4C\xa8\x05\xa3J\xd5\x11/\xe4\x11\x16\xd0\x17>\xd4\x11?\xf0\x0b\x00\x10\x14\x8f}\x89}\x98q\xd3\x0f \xf0\x10\x00\x11\x15\x97\x08\x92\x08\xdc\r\x12\xd8\x11M\xf5\x03\x02\x0e\x0f\xf0\x03\x00\x11\x19r\x1c\x00\x00\x00c\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x03\x00\x00\x01\xf3\xfe\x00\x00\x00\x97\x00|\x01|\x00j\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00kD\x00\x00r\x0ct\x03\x00\x00\x00\x00\x00\x00\x00\x00d\x01\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00n4|\x01|\x00j\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00k\x02\x00\x00r\x0ct\x03\x00\x00\x00\x00\x00\x00\x00\x00d\x02\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00n\x19t\x03\x00\x00\x00\x00\x00\x00\x00\x00d\x03\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00d\x04|\x00_\x02\x00\x00\x00\x00\x00\x00\x00\x00d\x05|\x00_\x03\x00\x00\x00\x00\x00\x00\x00\x00|\x00x\x01j\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00d\x06z\x17\x00\x00c\x02_\x02\x00\x00\x00\x00\x00\x00\x00\x00t\x03\x00\x00\x00\x00\x00\x00\x00\x00d\x07|\x00j\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9b\x00d\x08\x9d\x03\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00y\x00)\tN\xfa\tToo high!\xfa\x08Too low!\xfa\'Congratulations! You guessed correctly.r\x02\x00\x00\x00Tr/\x00\x00\x00\xfa\tYou have \xfa\x0f attempts left.)\x04r3\x00\x00\x00r<\x00\x00\x00r\x17\x00\x00\x00r\x18\x00\x00\x00r=\x00\x00\x00s\x02\x00\x00\x00 r\x1a\x00\x00\x00\xfa\rprocess_guessz GuessTheNumberGame.process_guess6\x00\x00\x00se\x00\x00\x00\x80\x00\xd8\x0c\x11\x90D\xd7\x14\'\xd1\x14\'\xd2\x0c\'\xdc\r\x12\x90;\xd5\r\x1f\xd8\x10\x15\x98\x04\xd7\x18+\xd1\x18+\xd2\x10+\xdc\r\x12\x90:\xd5\r\x1e\xe4\r\x12\xd0\x13<\xd4\r=\xd8\x1d\x1e\x88T\x8c]\xd8\x18\x1c\x88T\x8cX\xe0\t\r\x8f\x1d\x8a\x1d\x98!\xd1\t\x1c\x8d\x1d\xdc\t\x0e\xd0\x0f9\x984\x9f=\x9a=\xd1\x0f9\xd5\t:r\x1c\x00\x00\x00)\x01\xe9\n\x00\x00\x00r!\x00\x00\x00r%\x00\x00\x00)\x04r>\x00\x00\x00r"\x00\x00\x00r#\x00\x00\x00r$\x00\x00\x00)\x08r&\x00\x00\x00r\'\x00\x00\x00r(\x00\x00\x00r)\x00\x00\x00r\x1b\x00\x00\x00r \x00\x00\x00r;\x00\x00\x00\xda\r__classcell__)\x01r4\x00\x00\x00s\x01\x00\x00\x00@r\x1a\x00\x00\x00r,\x00\x00\x00r,\x00\x00\x00\x1a\x00\x00\x00s\x17\x00\x00\x00\xf8\x84\x00\xf1\x00\x04\x02\x05\xf6\x0c\x03\x06\x07\xf3\n\x0f\x06\x07\xf7"\x0c\x06\x07r\x1c\x00\x00\x00r,\x00\x00\x00)\x18r)\x00\x00\x00\xda\n__future__r\x03\x00\x00\x00\xda\x07jaclangr\x04\x00\x00\x00\xda\x0e__jac_import__\xda\x06typing\xda\x08_jac_typ\xda\x16jaclang.plugin.featurer\x05\x00\x00\x00\xda\x04_Jac\xda\x16jaclang.plugin.builtin\xda\x0bdataclassesr\x07\x00\x00\x00\xda\x11__jac_dataclass__\xda\rTYPE_CHECKINGr\x08\x00\x00\x00\xda\x08__file__\xda\x08make_obj\xda\x03Objr\x14\x00\x00\x00r,\x00\x00\x00\xda\x04gamer \x00\x00\x00r*\x00\x00\x00r\x1c\x00\x00\x00r\x1a\x00\x00\x00\xda\x08rX\x00\x00\x00\x01\x00\x00\x00s\xaa\x00\x00\x00\xf0\x03\x01\x01\x01\xd9\x01\x1d\xf7\x00K\x01\x02\x03\xf7\x00K\x01\x02\x03\xf7\x00K\x01\x02\x03\xf7\x00K\x01\x02\x03\xf0\x00K\x01\x02\x03\xe7\x01\x12\xd7\x01\x12\xd4\x01\x12\x80s\xd7\x01\x12\xd2\x01\x12\xf1\x04\x13\x02\x03\xef&\xe9\x00\xf7\'\x13\x02\x03\xf7\x00\x13\x02\x03\xf4\x00\x13\x02\x03\xef&\xe9\x00\xf7\'\x13\x02\x03\xf4\x00\x13\x02\x03\xf1*)\x02\x03\xefR\x01\xe9\x00\xf7S\x01)\x02\x03\xf7\x00)\x02\x03\xf3\x00)\x02\x03\xf0\n\x00\x1a\x1e\xf0\x0b)\x02\x03\xefR\x01\xe9\x00\xf7S\x01)\x02\x03\xf4\x00)\x02\x03\xf0X\x01\x02\x02\x05\xf1\x08\x00\r\x1f\xd3\x0c \x80T\xd8\x05\t\x87Y\x81Y\x85[r\x1c\x00\x00\x00') +# # #guess_game_bc = disassemble_bytecode(b'c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x01\xf3\x9e\x01\x00\x00\x97\x00d\x00Z\x00d\x01d\x02l\x01m\x02Z\x02\x01\x00d\x01d\x03l\x03m\x04Z\x05\x01\x00d\x01d\x04l\x06Z\x07d\x01d\x05l\x08m\tZ\n\x01\x00d\x01d\x06l\x0b\xad\x02\x01\x00d\x01d\x07l\x0cm\rZ\x0e\x01\x00e\x07j\x1e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00r\x05d\x01d\x04l\x10Z\x10n\x10\x02\x00e\x05d\x08e\x11d\td\nd\x04i\x00\xac\x0b\xab\x06\x00\x00\x00\x00\x00\x00\\\x01\x00\x00Z\x10\x02\x00e\nj$\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00g\x00g\x00\xac\x0c\xab\x02\x00\x00\x00\x00\x00\x00\x02\x00e\x0ed\n\xac\r\xab\x01\x00\x00\x00\x00\x00\x00\x02\x00G\x00d\x0e\x84\x00d\x0fe\nj&\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xab\x03\x00\x00\x00\x00\x00\x00\xab\x00\x00\x00\x00\x00\x00\x00\xab\x00\x00\x00\x00\x00\x00\x00Z\x14\x02\x00e\nj$\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00g\x00g\x00\xac\x0c\xab\x02\x00\x00\x00\x00\x00\x00\x02\x00e\x0ed\n\xac\r\xab\x01\x00\x00\x00\x00\x00\x00\x02\x00G\x00d\x10\x84\x00d\x11e\x14e\nj&\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xab\x04\x00\x00\x00\x00\x00\x00\xab\x00\x00\x00\x00\x00\x00\x00\xab\x00\x00\x00\x00\x00\x00\x00Z\x15\t\x00\x02\x00e\x15\xab\x00\x00\x00\x00\x00\x00\x00Z\x16e\x16j/\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xab\x00\x00\x00\x00\x00\x00\x00\x01\x00y\x04)\x12\xfa\x16A Number Guessing Game\xe9\x00\x00\x00\x00)\x01\xda\x0bannotations)\x01\xda\njac_importN)\x01\xda\nJacFeature)\x01\xda\x01*)\x01\xda\tdataclass\xda\x06random\xda\x02pyF)\x06\xda\x06target\xda\tbase_path\xda\x03lng\xda\x06absorb\xda\tmdl_alias\xda\x05items)\x02\xda\x08on_entry\xda\x07on_exit)\x01\xda\x02eqc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x01\xf3 \x00\x00\x00\x97\x00e\x00Z\x01d\x00Z\x02d\x01Z\x03d\x05d\x02\x84\x04Z\x04d\x06d\x03\x84\x04Z\x05y\x04)\x07\xda\x04Game\xe1\x1a\x01\x00\x00\nA generic Game base class.\n\nThe obj keyword is used to define the class.\nThe can keyword is used to define methods (functions) within the class.\nThe self keyword is used to refer to the current instance of the class.\nConstructors are defined using the init method with parameters.\nc\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x01\xf3 \x00\x00\x00\x97\x00|\x01|\x00_\x00\x00\x00\x00\x00\x00\x00\x00\x00d\x01|\x00_\x01\x00\x00\x00\x00\x00\x00\x00\x00y\x00)\x02NF)\x02\xda\x08attempts\xda\x03won)\x02\xda\x04selfr\x17\x00\x00\x00s\x02\x00\x00\x00 \xfaT/Users/jakobtherkelsen/Documents/jaseci-ginS/jac/examples/guess_game/guess_game1.jac\xda\x08__init__z\rGame.__init__\x0e\x00\x00\x00s\x10\x00\x00\x00\x80\x00\xd8\x19!\x88\x14\x8c\x1d\xd8\x14\x19\x88\x14\x8d\x18\xf3\x00\x00\x00\x00c\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03\x00\x00\x01\xf3\x18\x00\x00\x00\x97\x00t\x01\x00\x00\x00\x00\x00\x00\x00\x00d\x01\xab\x01\x00\x00\x00\x00\x00\x00\x82\x01)\x02N\xfa&Subclasses must implement this method.)\x01\xda\x13NotImplementedError)\x01r\x19\x00\x00\x00s\x01\x00\x00\x00 r\x1a\x00\x00\x00\xda\x04playz\tGame.play\x13\x00\x00\x00s\x12\x00\x00\x00\x80\x00\xdc\x0f"\xd8\r5\xf3\x03\x02\x10\x10\xf0\x00\x02\n\x0cr\x1c\x00\x00\x00N\xa9\x04r\x17\x00\x00\x00\xda\x03int\xda\x06return\xda\x04None\xa9\x02r#\x00\x00\x00r$\x00\x00\x00)\x06\xda\x08__name__\xda\n__module__\xda\x0c__qualname__\xda\x07__doc__r\x1b\x00\x00\x00r \x00\x00\x00\xa9\x00r\x1c\x00\x00\x00r\x1a\x00\x00\x00r\x14\x00\x00\x00r\x14\x00\x00\x00\x05\x00\x00\x00s\x11\x00\x00\x00\x84\x00\xf1\x00\x07\x02\x05\xf3\x12\x03\x06\x07\xf4\n\x04\x06\x07r\x1c\x00\x00\x00r\x14\x00\x00\x00c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x01\xf36\x00\x00\x00\x87\x00\x97\x00e\x00Z\x01d\x00Z\x02d\x01Z\x03d\x05d\x06\x88\x00f\x01d\x02\x84\rZ\x04d\x07d\x03\x84\x04Z\x05d\x08d\x04\x84\x04Z\x06\x88\x00x\x01Z\x07S\x00)\t\xda\x12GuessTheNumberGame\xfa\xae\nA number guessing game. The player must guess a number between 1 and 100.\n\nThis class inherits from Game. The super() function is used to call the parent class constructor.\nc\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x03\x00\x00\x01\xf3Z\x00\x00\x00\x95\x01\x97\x00t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x89\x02|\x00\x8d\x05\x00\x00|\x01\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00t\x05\x00\x00\x00\x00\x00\x00\x00\x00j\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00d\x01d\x02\xab\x02\x00\x00\x00\x00\x00\x00|\x00_\x04\x00\x00\x00\x00\x00\x00\x00\x00y\x00)\x03N\xe9\x01\x00\x00\x00\xe9d\x00\x00\x00)\x05\xda\x05superr\x1b\x00\x00\x00r\x08\x00\x00\x00\xda\x07randint\xda\x0ecorrect_number)\x03r\x19\x00\x00\x00r\x17\x00\x00\x00\xda\t__class__s\x03\x00\x00\x00 \x80r\x1a\x00\x00\x00r\x1b\x00\x00\x00z\x1bGuessTheNumberGame.__init__ \x00\x00\x00s \x00\x00\x00\xf8\x80\x00\xde\t\x0e\x89\x1a\x90H\xd4\t\x1d\xdc\x1f%\x9f~\x99~\xa8a\xb0\x13\xd3\x1f5\x88\x14\xd5\t\x1cr\x1c\x00\x00\x00c\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x03\x00\x00\x01\xf3\xf4\x00\x00\x00\x97\x00|\x00j\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00d\x01kD\x00\x00rQt\x03\x00\x00\x00\x00\x00\x00\x00\x00d\x02\xab\x01\x00\x00\x00\x00\x00\x00}\x01|\x01j\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xab\x00\x00\x00\x00\x00\x00\x00r\x1b|\x00j\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00t\t\x00\x00\x00\x00\x00\x00\x00\x00|\x01\xab\x01\x00\x00\x00\x00\x00\x00\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00n\x0bt\x0b\x00\x00\x00\x00\x00\x00\x00\x00d\x03\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00|\x00j\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00d\x01kD\x00\x00r\x01\x8cQ|\x00j\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00s\x0ct\x0b\x00\x00\x00\x00\x00\x00\x00\x00d\x04\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00y\x00y\x00)\x05Nr\x02\x00\x00\x00\xfa"Guess a number between 1 and 100: \xfa%That\'s not a valid number! Try again.\xfa:Sorry, you didn\'t guess the number. Better luck next time!)\x07r\x17\x00\x00\x00\xda\x05input\xda\x07isdigit\xda\rprocess_guessr"\x00\x00\x00\xda\x05printr\x18\x00\x00\x00\xa9\x02r\x19\x00\x00\x00\xda\x05guesss\x02\x00\x00\x00 r\x1a\x00\x00\x00\xfa\x04playz\x17GuessTheNumberGame.play%\x00\x00\x00sd\x00\x00\x00\x80\x00\xe0\x0f\x13\x8f}\x89}\x98q\xd2\x0f \xdc\x15\x1a\xd0\x1b?\xd3\x15@\x88U\xd8\x10\x15\x97\r\x91\r\x94\x0f\xd8\x11\x15\xd7\x11#\xd1\x11#\xa4C\xa8\x05\xa3J\xd5\x11/\xe4\x11\x16\xd0\x17>\xd4\x11?\xf0\x0b\x00\x10\x14\x8f}\x89}\x98q\xd3\x0f \xf0\x10\x00\x11\x15\x97\x08\x92\x08\xdc\r\x12\xd8\x11M\xf5\x03\x02\x0e\x0f\xf0\x03\x00\x11\x19r\x1c\x00\x00\x00c\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x03\x00\x00\x01\xf3\xfe\x00\x00\x00\x97\x00|\x01|\x00j\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00kD\x00\x00r\x0ct\x03\x00\x00\x00\x00\x00\x00\x00\x00d\x01\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00n4|\x01|\x00j\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00k\x02\x00\x00r\x0ct\x03\x00\x00\x00\x00\x00\x00\x00\x00d\x02\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00n\x19t\x03\x00\x00\x00\x00\x00\x00\x00\x00d\x03\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00d\x04|\x00_\x02\x00\x00\x00\x00\x00\x00\x00\x00d\x05|\x00_\x03\x00\x00\x00\x00\x00\x00\x00\x00|\x00x\x01j\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00d\x06z\x17\x00\x00c\x02_\x02\x00\x00\x00\x00\x00\x00\x00\x00t\x03\x00\x00\x00\x00\x00\x00\x00\x00d\x07|\x00j\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9b\x00d\x08\x9d\x03\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00y\x00)\tN\xfa\tToo high!\xfa\x08Too low!\xfa\'Congratulations! You guessed correctly.r\x02\x00\x00\x00Tr/\x00\x00\x00\xfa\tYou have \xfa\x0f attempts left.)\x04r3\x00\x00\x00r<\x00\x00\x00r\x17\x00\x00\x00r\x18\x00\x00\x00r=\x00\x00\x00s\x02\x00\x00\x00 r\x1a\x00\x00\x00\xfa\rprocess_guessz GuessTheNumberGame.process_guess6\x00\x00\x00se\x00\x00\x00\x80\x00\xd8\x0c\x11\x90D\xd7\x14\'\xd1\x14\'\xd2\x0c\'\xdc\r\x12\x90;\xd5\r\x1f\xd8\x10\x15\x98\x04\xd7\x18+\xd1\x18+\xd2\x10+\xdc\r\x12\x90:\xd5\r\x1e\xe4\r\x12\xd0\x13<\xd4\r=\xd8\x1d\x1e\x88T\x8c]\xd8\x18\x1c\x88T\x8cX\xe0\t\r\x8f\x1d\x8a\x1d\x98!\xd1\t\x1c\x8d\x1d\xdc\t\x0e\xd0\x0f9\x984\x9f=\x9a=\xd1\x0f9\xd5\t:r\x1c\x00\x00\x00)\x01\xe9\n\x00\x00\x00r!\x00\x00\x00r%\x00\x00\x00)\x04r>\x00\x00\x00r"\x00\x00\x00r#\x00\x00\x00r$\x00\x00\x00)\x08r&\x00\x00\x00r\'\x00\x00\x00r(\x00\x00\x00r)\x00\x00\x00r\x1b\x00\x00\x00r \x00\x00\x00r;\x00\x00\x00\xda\r__classcell__)\x01r4\x00\x00\x00s\x01\x00\x00\x00@r\x1a\x00\x00\x00r,\x00\x00\x00r,\x00\x00\x00\x1a\x00\x00\x00s\x17\x00\x00\x00\xf8\x84\x00\xf1\x00\x04\x02\x05\xf6\x0c\x03\x06\x07\xf3\n\x0f\x06\x07\xf7"\x0c\x06\x07r\x1c\x00\x00\x00r,\x00\x00\x00)\x18r)\x00\x00\x00\xda\n__future__r\x03\x00\x00\x00\xda\x07jaclangr\x04\x00\x00\x00\xda\x0e__jac_import__\xda\x06typing\xda\x08_jac_typ\xda\x16jaclang.plugin.featurer\x05\x00\x00\x00\xda\x04_Jac\xda\x16jaclang.plugin.builtin\xda\x0bdataclassesr\x07\x00\x00\x00\xda\x11__jac_dataclass__\xda\rTYPE_CHECKINGr\x08\x00\x00\x00\xda\x08__file__\xda\x08make_obj\xda\x03Objr\x14\x00\x00\x00r,\x00\x00\x00\xda\x04gamer \x00\x00\x00r*\x00\x00\x00r\x1c\x00\x00\x00r\x1a\x00\x00\x00\xda\x08rX\x00\x00\x00\x01\x00\x00\x00s\xaa\x00\x00\x00\xf0\x03\x01\x01\x01\xd9\x01\x1d\xf7\x00K\x01\x02\x03\xf7\x00K\x01\x02\x03\xf7\x00K\x01\x02\x03\xf7\x00K\x01\x02\x03\xf0\x00K\x01\x02\x03\xe7\x01\x12\xd7\x01\x12\xd4\x01\x12\x80s\xd7\x01\x12\xd2\x01\x12\xf1\x04\x13\x02\x03\xef&\xe9\x00\xf7\'\x13\x02\x03\xf7\x00\x13\x02\x03\xf4\x00\x13\x02\x03\xef&\xe9\x00\xf7\'\x13\x02\x03\xf4\x00\x13\x02\x03\xf1*)\x02\x03\xefR\x01\xe9\x00\xf7S\x01)\x02\x03\xf7\x00)\x02\x03\xf3\x00)\x02\x03\xf0\n\x00\x1a\x1e\xf0\x0b)\x02\x03\xefR\x01\xe9\x00\xf7S\x01)\x02\x03\xf4\x00)\x02\x03\xf0X\x01\x02\x02\x05\xf1\x08\x00\r\x1f\xd3\x0c \x80T\xd8\x05\t\x87Y\x81Y\x85[r\x1c\x00\x00\x00') # BBs = create_BBs(instructions) # print(BBs) From abcbefc2e838239c9ab8a1a87585e4dc450bb161 Mon Sep 17 00:00:00 2001 From: Jakob Louis Therkelsen Date: Mon, 18 Nov 2024 16:12:49 -0500 Subject: [PATCH 28/84] include instructions list --- jac/examples/ginsScripts/cfg.gv.pdf | Bin 12070 -> 12070 bytes .../compiler/passes/main/cfg_gen_pass.py | 5 ++-- jac/jaclang/runtimelib/cfg.py | 8 ++++-- jac/jaclang/runtimelib/machine.py | 24 ++++++++++-------- 4 files changed, 21 insertions(+), 16 deletions(-) diff --git a/jac/examples/ginsScripts/cfg.gv.pdf b/jac/examples/ginsScripts/cfg.gv.pdf index 6be595fa2f8ab8b1f29bb36c61e410b5efc8aea2..5c6b07069a43fd5893ab5037b765c58806825de7 100644 GIT binary patch delta 290 zcmV+-0p0$lUZ!5K@hpGAYQr!PMDPBJxs=+6##-4sGt-`b1C2RImNe2!?R zht7eb&1T#<8hsh0GKi&UjRq~KTyVr!=X$$N(~&kt^w(C}g*JaplH9*BO1M^cd*Kw~ z{hBkL6H!S^;#u*+if6`>$>c8C|#^Qyi2Zl$UZ+W>v$z-wjoV5G9h oX3vvflH5K1Y8q+97AWZ?*kWhA*Y z|GttPrxZ=^GX|N!fVs*g;z-S zYfgE=7+bN5^2PHLEgvaOXOq8JcnH>U|0t}AIbyOAys1Wut@#OYX?T29qF7e<(47x* zhvKe3STppf>o~-D@)+ri&VgFdxjuTy>x^IE?V#pq7gT%ot))60wh@NRk)M<^gO$o* oarZojMd_#LE?gDiU%j31;>)zRcHsiIazXS9HJWbavji?80VWlbl>h($ diff --git a/jac/jaclang/compiler/passes/main/cfg_gen_pass.py b/jac/jaclang/compiler/passes/main/cfg_gen_pass.py index 1753a7e74d..44203c131e 100644 --- a/jac/jaclang/compiler/passes/main/cfg_gen_pass.py +++ b/jac/jaclang/compiler/passes/main/cfg_gen_pass.py @@ -34,8 +34,7 @@ def enter_module(self, node: ast.Module) -> None: for mod in mods: bytecode = mod.gen.py_bytecode instructions = disassemble_bytecode(bytecode) - BBs = create_BBs(instructions) - print(BBs) + BBs = create_BBs(instructions) cfg = create_cfg(BBs) module_cfgs[mod.name] = cfg for cfg in module_cfgs.values(): @@ -43,7 +42,7 @@ def enter_module(self, node: ast.Module) -> None: dot.render('cfg.gv', view=True) if JacMachine.get().gin: try: - JacMachine.get().gin.get_cfgs(cfgs=module_cfgs) + JacMachine.get().gin.set_cfgs(cfgs=module_cfgs) except Exception as e: print(f"Can't save cfgs: {e}") diff --git a/jac/jaclang/runtimelib/cfg.py b/jac/jaclang/runtimelib/cfg.py index 91c969ad8e..5d6d0bd2c8 100644 --- a/jac/jaclang/runtimelib/cfg.py +++ b/jac/jaclang/runtimelib/cfg.py @@ -148,9 +148,10 @@ def valid_offset(offset): class CFG: - def __init__(self): + def __init__(self, block_map:BlockMap): self.nodes = set() self.edges = {} + self.block_map = block_map def add_node(self, node_id): self.nodes.add(node_id) @@ -163,6 +164,9 @@ def add_edge(self, from_node, to_node): else: self.edges[from_node] = [to_node] + def display_instructions(self): + return repr(self.block_map) + def __repr__(self): result = [] for node in self.nodes: @@ -172,7 +176,7 @@ def __repr__(self): result.append(f' -> bb{succ}') return "\n".join(result) def create_cfg(block_map: BlockMap) -> CFG: - cfg = CFG() + cfg = CFG(block_map) for block_id, block in block_map.idx_to_block.items(): cfg.add_node(block_id) diff --git a/jac/jaclang/runtimelib/machine.py b/jac/jaclang/runtimelib/machine.py index 51ead66056..48a857db94 100644 --- a/jac/jaclang/runtimelib/machine.py +++ b/jac/jaclang/runtimelib/machine.py @@ -332,7 +332,7 @@ class ShellGhost: def __init__(self): self.cfgs = None - def get_cfgs(self,cfgs: any): + def set_cfgs(self,cfgs: any): self.cfgs = cfgs def start_ghost(self): @@ -343,13 +343,15 @@ def worker(self): genai.configure(api_key=os.getenv("GEN_AI_KEY")) model = genai.GenerativeModel("gemini-1.5-flash") response_dict = {'cfg': self.cfgs} - prompt = [] - for k,v in response_dict.items(): - prompt.append(f"here is my {k}:\n{v}") - prompt.append("\nCan you identify where the code could have an error?") - response = model.generate_content("".join(prompt)) - - print("PROMPT:\n") - print("".join(prompt)) - print("RESPONSE:\n") - print(response.text) \ No newline at end of file + # prompt = [] + # for k,v in response_dict.items(): + # prompt.append(f"here is my {k}:\n{v}") + # prompt.append("\nCan you identify where the code could have an error?") + # response = model.generate_content("".join(prompt)) + + # print("PROMPT:\n") + # print("".join(prompt)) + # print("RESPONSE:\n") + # print(response.text) + + print(self.cfgs['hot_path'].display_instructions()) \ No newline at end of file From 530f6325015ac5e793e8e130d41814acc5b101df Mon Sep 17 00:00:00 2001 From: Jakob Louis Therkelsen Date: Mon, 18 Nov 2024 16:54:19 -0500 Subject: [PATCH 29/84] fix cfg creation --- jac/jaclang/runtimelib/cfg.py | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/jac/jaclang/runtimelib/cfg.py b/jac/jaclang/runtimelib/cfg.py index 5d6d0bd2c8..5857e8d4e3 100644 --- a/jac/jaclang/runtimelib/cfg.py +++ b/jac/jaclang/runtimelib/cfg.py @@ -6,8 +6,8 @@ import dis from collections import defaultdict from typing import List, Optional, Iterator -import graphviz -from graphviz import Digraph +# import graphviz +# from graphviz import Digraph class BytecodeOp: def __init__(self, op: int, arg: int, offset: int, argval:int, argrepr:str, is_jump_target: bool) -> None: @@ -179,6 +179,8 @@ def create_cfg(block_map: BlockMap) -> CFG: cfg = CFG(block_map) for block_id, block in block_map.idx_to_block.items(): + if block_id == 7: + x = 1 cfg.add_node(block_id) last_instr = block.instructions[-1] @@ -207,7 +209,7 @@ def create_cfg(block_map: BlockMap) -> CFG: else: fall_through_offset = block.instructions[-1].get_next_instruction_offset() fall_through_block = find_block_by_offset(block_map, fall_through_offset) - if fall_through_block is not None: + if fall_through_block is not None and fall_through_offset != last_instr.offset: cfg.add_edge(block_id, fall_through_block) return cfg @@ -243,14 +245,14 @@ def visualize_cfg(cfg: CFG): ##simple= #instructions = disassemble_bytecode(b'c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x01\xf3*\x00\x00\x00\x97\x00d\x00d\x01l\x00m\x01Z\x01\x01\x00d\x00Z\x02d\x00Z\x03e\x03d\x00k\\\x00\x00r\x02d\x02Z\x02d\x03Z\x02y\x04)\x05\xe9\x00\x00\x00\x00)\x01\xda\x0bannotations\xe9\x01\x00\x00\x00\xe9\xff\xff\xff\xffN)\x04\xda\n__future__r\x02\x00\x00\x00\xda\x01a\xda\x01x\xa9\x00\xf3\x00\x00\x00\x00\xfaP/Users/jakobtherkelsen/Documents/jaseci-ginS/jac/examples/ginsScripts/simple.jac\xfa\x08r\x0b\x00\x00\x00\x01\x00\x00\x00s%\x00\x00\x00\xf0\x03\x01\x01\x01\xf5\x02\x07\x02\x03\xd8\x05\x06\x801\xd8\x05\x06\x801\xd8\x06\x07\x881\x82f\xd8\x07\x08\x80Q\xe0\x05\x07\x811r\t\x00\x00\x00') #hot path -# instructions = disassemble_bytecode(b'c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x01\xf3T\x00\x00\x00\x97\x00d\x00d\x01l\x00m\x01Z\x01\x01\x00d\x00Z\x02d\x00Z\x03e\x02d\x02k\x02\x00\x00r\x19e\x02d\x03z\x06\x00\x00d\x00k(\x00\x00r\x03d\x04Z\x03n\x02d\x03Z\x03e\x02d\x04z\r\x00\x00Z\x02e\x02d\x02k\x02\x00\x00r\x01\x8c\x18y\x05y\x05)\x06\xe9\x00\x00\x00\x00)\x01\xda\x0bannotations\xe9\x0f\x00\x00\x00\xe9\x02\x00\x00\x00\xe9\x01\x00\x00\x00N)\x04\xda\n__future__r\x02\x00\x00\x00\xda\x01a\xda\x01b\xa9\x00\xf3\x00\x00\x00\x00\xfaR/Users/jakobtherkelsen/Documents/jaseci-ginS/jac/examples/ginsScripts/hot_path.jac\xfa\x08r\x0c\x00\x00\x00\x01\x00\x00\x00sD\x00\x00\x00\xf0\x03\x01\x01\x01\xf5\x02\x0c\x02\x03\xd8\x07\x08\x801\xd8\x07\x08\x801\xd8\t\n\x88R\x8a\x16\xd8\x08\t\x88A\x89\x05\x90\x11\x8a\n\xd8\x0b\x0c\x81q\xf0\x06\x00\x0c\r\x80q\xe0\x05\x06\x88!\x81W\x80Q\xf0\x0f\x00\n\x0b\x88R\x8d\x16r\n\x00\x00\x00') +instructions = disassemble_bytecode(b'c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x01\xf3T\x00\x00\x00\x97\x00d\x00d\x01l\x00m\x01Z\x01\x01\x00d\x00Z\x02d\x00Z\x03e\x02d\x02k\x02\x00\x00r\x19e\x02d\x03z\x06\x00\x00d\x00k(\x00\x00r\x03d\x04Z\x03n\x02d\x03Z\x03e\x02d\x04z\r\x00\x00Z\x02e\x02d\x02k\x02\x00\x00r\x01\x8c\x18y\x05y\x05)\x06\xe9\x00\x00\x00\x00)\x01\xda\x0bannotations\xe9\x0f\x00\x00\x00\xe9\x02\x00\x00\x00\xe9\x01\x00\x00\x00N)\x04\xda\n__future__r\x02\x00\x00\x00\xda\x01a\xda\x01b\xa9\x00\xf3\x00\x00\x00\x00\xfaR/Users/jakobtherkelsen/Documents/jaseci-ginS/jac/examples/ginsScripts/hot_path.jac\xfa\x08r\x0c\x00\x00\x00\x01\x00\x00\x00sD\x00\x00\x00\xf0\x03\x01\x01\x01\xf5\x02\x0c\x02\x03\xd8\x07\x08\x801\xd8\x07\x08\x801\xd8\t\n\x88R\x8a\x16\xd8\x08\t\x88A\x89\x05\x90\x11\x8a\n\xd8\x0b\x0c\x81q\xf0\x06\x00\x0c\r\x80q\xe0\x05\x06\x88!\x81W\x80Q\xf0\x0f\x00\n\x0b\x88R\x8d\x16r\n\x00\x00\x00') # # #guess_game_bc = disassemble_bytecode(b'c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x01\xf3\x9e\x01\x00\x00\x97\x00d\x00Z\x00d\x01d\x02l\x01m\x02Z\x02\x01\x00d\x01d\x03l\x03m\x04Z\x05\x01\x00d\x01d\x04l\x06Z\x07d\x01d\x05l\x08m\tZ\n\x01\x00d\x01d\x06l\x0b\xad\x02\x01\x00d\x01d\x07l\x0cm\rZ\x0e\x01\x00e\x07j\x1e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00r\x05d\x01d\x04l\x10Z\x10n\x10\x02\x00e\x05d\x08e\x11d\td\nd\x04i\x00\xac\x0b\xab\x06\x00\x00\x00\x00\x00\x00\\\x01\x00\x00Z\x10\x02\x00e\nj$\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00g\x00g\x00\xac\x0c\xab\x02\x00\x00\x00\x00\x00\x00\x02\x00e\x0ed\n\xac\r\xab\x01\x00\x00\x00\x00\x00\x00\x02\x00G\x00d\x0e\x84\x00d\x0fe\nj&\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xab\x03\x00\x00\x00\x00\x00\x00\xab\x00\x00\x00\x00\x00\x00\x00\xab\x00\x00\x00\x00\x00\x00\x00Z\x14\x02\x00e\nj$\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00g\x00g\x00\xac\x0c\xab\x02\x00\x00\x00\x00\x00\x00\x02\x00e\x0ed\n\xac\r\xab\x01\x00\x00\x00\x00\x00\x00\x02\x00G\x00d\x10\x84\x00d\x11e\x14e\nj&\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xab\x04\x00\x00\x00\x00\x00\x00\xab\x00\x00\x00\x00\x00\x00\x00\xab\x00\x00\x00\x00\x00\x00\x00Z\x15\t\x00\x02\x00e\x15\xab\x00\x00\x00\x00\x00\x00\x00Z\x16e\x16j/\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xab\x00\x00\x00\x00\x00\x00\x00\x01\x00y\x04)\x12\xfa\x16A Number Guessing Game\xe9\x00\x00\x00\x00)\x01\xda\x0bannotations)\x01\xda\njac_importN)\x01\xda\nJacFeature)\x01\xda\x01*)\x01\xda\tdataclass\xda\x06random\xda\x02pyF)\x06\xda\x06target\xda\tbase_path\xda\x03lng\xda\x06absorb\xda\tmdl_alias\xda\x05items)\x02\xda\x08on_entry\xda\x07on_exit)\x01\xda\x02eqc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x01\xf3 \x00\x00\x00\x97\x00e\x00Z\x01d\x00Z\x02d\x01Z\x03d\x05d\x02\x84\x04Z\x04d\x06d\x03\x84\x04Z\x05y\x04)\x07\xda\x04Game\xe1\x1a\x01\x00\x00\nA generic Game base class.\n\nThe obj keyword is used to define the class.\nThe can keyword is used to define methods (functions) within the class.\nThe self keyword is used to refer to the current instance of the class.\nConstructors are defined using the init method with parameters.\nc\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x01\xf3 \x00\x00\x00\x97\x00|\x01|\x00_\x00\x00\x00\x00\x00\x00\x00\x00\x00d\x01|\x00_\x01\x00\x00\x00\x00\x00\x00\x00\x00y\x00)\x02NF)\x02\xda\x08attempts\xda\x03won)\x02\xda\x04selfr\x17\x00\x00\x00s\x02\x00\x00\x00 \xfaT/Users/jakobtherkelsen/Documents/jaseci-ginS/jac/examples/guess_game/guess_game1.jac\xda\x08__init__z\rGame.__init__\x0e\x00\x00\x00s\x10\x00\x00\x00\x80\x00\xd8\x19!\x88\x14\x8c\x1d\xd8\x14\x19\x88\x14\x8d\x18\xf3\x00\x00\x00\x00c\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03\x00\x00\x01\xf3\x18\x00\x00\x00\x97\x00t\x01\x00\x00\x00\x00\x00\x00\x00\x00d\x01\xab\x01\x00\x00\x00\x00\x00\x00\x82\x01)\x02N\xfa&Subclasses must implement this method.)\x01\xda\x13NotImplementedError)\x01r\x19\x00\x00\x00s\x01\x00\x00\x00 r\x1a\x00\x00\x00\xda\x04playz\tGame.play\x13\x00\x00\x00s\x12\x00\x00\x00\x80\x00\xdc\x0f"\xd8\r5\xf3\x03\x02\x10\x10\xf0\x00\x02\n\x0cr\x1c\x00\x00\x00N\xa9\x04r\x17\x00\x00\x00\xda\x03int\xda\x06return\xda\x04None\xa9\x02r#\x00\x00\x00r$\x00\x00\x00)\x06\xda\x08__name__\xda\n__module__\xda\x0c__qualname__\xda\x07__doc__r\x1b\x00\x00\x00r \x00\x00\x00\xa9\x00r\x1c\x00\x00\x00r\x1a\x00\x00\x00r\x14\x00\x00\x00r\x14\x00\x00\x00\x05\x00\x00\x00s\x11\x00\x00\x00\x84\x00\xf1\x00\x07\x02\x05\xf3\x12\x03\x06\x07\xf4\n\x04\x06\x07r\x1c\x00\x00\x00r\x14\x00\x00\x00c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x01\xf36\x00\x00\x00\x87\x00\x97\x00e\x00Z\x01d\x00Z\x02d\x01Z\x03d\x05d\x06\x88\x00f\x01d\x02\x84\rZ\x04d\x07d\x03\x84\x04Z\x05d\x08d\x04\x84\x04Z\x06\x88\x00x\x01Z\x07S\x00)\t\xda\x12GuessTheNumberGame\xfa\xae\nA number guessing game. The player must guess a number between 1 and 100.\n\nThis class inherits from Game. The super() function is used to call the parent class constructor.\nc\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x03\x00\x00\x01\xf3Z\x00\x00\x00\x95\x01\x97\x00t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x89\x02|\x00\x8d\x05\x00\x00|\x01\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00t\x05\x00\x00\x00\x00\x00\x00\x00\x00j\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00d\x01d\x02\xab\x02\x00\x00\x00\x00\x00\x00|\x00_\x04\x00\x00\x00\x00\x00\x00\x00\x00y\x00)\x03N\xe9\x01\x00\x00\x00\xe9d\x00\x00\x00)\x05\xda\x05superr\x1b\x00\x00\x00r\x08\x00\x00\x00\xda\x07randint\xda\x0ecorrect_number)\x03r\x19\x00\x00\x00r\x17\x00\x00\x00\xda\t__class__s\x03\x00\x00\x00 \x80r\x1a\x00\x00\x00r\x1b\x00\x00\x00z\x1bGuessTheNumberGame.__init__ \x00\x00\x00s \x00\x00\x00\xf8\x80\x00\xde\t\x0e\x89\x1a\x90H\xd4\t\x1d\xdc\x1f%\x9f~\x99~\xa8a\xb0\x13\xd3\x1f5\x88\x14\xd5\t\x1cr\x1c\x00\x00\x00c\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x03\x00\x00\x01\xf3\xf4\x00\x00\x00\x97\x00|\x00j\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00d\x01kD\x00\x00rQt\x03\x00\x00\x00\x00\x00\x00\x00\x00d\x02\xab\x01\x00\x00\x00\x00\x00\x00}\x01|\x01j\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xab\x00\x00\x00\x00\x00\x00\x00r\x1b|\x00j\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00t\t\x00\x00\x00\x00\x00\x00\x00\x00|\x01\xab\x01\x00\x00\x00\x00\x00\x00\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00n\x0bt\x0b\x00\x00\x00\x00\x00\x00\x00\x00d\x03\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00|\x00j\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00d\x01kD\x00\x00r\x01\x8cQ|\x00j\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00s\x0ct\x0b\x00\x00\x00\x00\x00\x00\x00\x00d\x04\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00y\x00y\x00)\x05Nr\x02\x00\x00\x00\xfa"Guess a number between 1 and 100: \xfa%That\'s not a valid number! Try again.\xfa:Sorry, you didn\'t guess the number. Better luck next time!)\x07r\x17\x00\x00\x00\xda\x05input\xda\x07isdigit\xda\rprocess_guessr"\x00\x00\x00\xda\x05printr\x18\x00\x00\x00\xa9\x02r\x19\x00\x00\x00\xda\x05guesss\x02\x00\x00\x00 r\x1a\x00\x00\x00\xfa\x04playz\x17GuessTheNumberGame.play%\x00\x00\x00sd\x00\x00\x00\x80\x00\xe0\x0f\x13\x8f}\x89}\x98q\xd2\x0f \xdc\x15\x1a\xd0\x1b?\xd3\x15@\x88U\xd8\x10\x15\x97\r\x91\r\x94\x0f\xd8\x11\x15\xd7\x11#\xd1\x11#\xa4C\xa8\x05\xa3J\xd5\x11/\xe4\x11\x16\xd0\x17>\xd4\x11?\xf0\x0b\x00\x10\x14\x8f}\x89}\x98q\xd3\x0f \xf0\x10\x00\x11\x15\x97\x08\x92\x08\xdc\r\x12\xd8\x11M\xf5\x03\x02\x0e\x0f\xf0\x03\x00\x11\x19r\x1c\x00\x00\x00c\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x03\x00\x00\x01\xf3\xfe\x00\x00\x00\x97\x00|\x01|\x00j\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00kD\x00\x00r\x0ct\x03\x00\x00\x00\x00\x00\x00\x00\x00d\x01\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00n4|\x01|\x00j\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00k\x02\x00\x00r\x0ct\x03\x00\x00\x00\x00\x00\x00\x00\x00d\x02\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00n\x19t\x03\x00\x00\x00\x00\x00\x00\x00\x00d\x03\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00d\x04|\x00_\x02\x00\x00\x00\x00\x00\x00\x00\x00d\x05|\x00_\x03\x00\x00\x00\x00\x00\x00\x00\x00|\x00x\x01j\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00d\x06z\x17\x00\x00c\x02_\x02\x00\x00\x00\x00\x00\x00\x00\x00t\x03\x00\x00\x00\x00\x00\x00\x00\x00d\x07|\x00j\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9b\x00d\x08\x9d\x03\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00y\x00)\tN\xfa\tToo high!\xfa\x08Too low!\xfa\'Congratulations! You guessed correctly.r\x02\x00\x00\x00Tr/\x00\x00\x00\xfa\tYou have \xfa\x0f attempts left.)\x04r3\x00\x00\x00r<\x00\x00\x00r\x17\x00\x00\x00r\x18\x00\x00\x00r=\x00\x00\x00s\x02\x00\x00\x00 r\x1a\x00\x00\x00\xfa\rprocess_guessz GuessTheNumberGame.process_guess6\x00\x00\x00se\x00\x00\x00\x80\x00\xd8\x0c\x11\x90D\xd7\x14\'\xd1\x14\'\xd2\x0c\'\xdc\r\x12\x90;\xd5\r\x1f\xd8\x10\x15\x98\x04\xd7\x18+\xd1\x18+\xd2\x10+\xdc\r\x12\x90:\xd5\r\x1e\xe4\r\x12\xd0\x13<\xd4\r=\xd8\x1d\x1e\x88T\x8c]\xd8\x18\x1c\x88T\x8cX\xe0\t\r\x8f\x1d\x8a\x1d\x98!\xd1\t\x1c\x8d\x1d\xdc\t\x0e\xd0\x0f9\x984\x9f=\x9a=\xd1\x0f9\xd5\t:r\x1c\x00\x00\x00)\x01\xe9\n\x00\x00\x00r!\x00\x00\x00r%\x00\x00\x00)\x04r>\x00\x00\x00r"\x00\x00\x00r#\x00\x00\x00r$\x00\x00\x00)\x08r&\x00\x00\x00r\'\x00\x00\x00r(\x00\x00\x00r)\x00\x00\x00r\x1b\x00\x00\x00r \x00\x00\x00r;\x00\x00\x00\xda\r__classcell__)\x01r4\x00\x00\x00s\x01\x00\x00\x00@r\x1a\x00\x00\x00r,\x00\x00\x00r,\x00\x00\x00\x1a\x00\x00\x00s\x17\x00\x00\x00\xf8\x84\x00\xf1\x00\x04\x02\x05\xf6\x0c\x03\x06\x07\xf3\n\x0f\x06\x07\xf7"\x0c\x06\x07r\x1c\x00\x00\x00r,\x00\x00\x00)\x18r)\x00\x00\x00\xda\n__future__r\x03\x00\x00\x00\xda\x07jaclangr\x04\x00\x00\x00\xda\x0e__jac_import__\xda\x06typing\xda\x08_jac_typ\xda\x16jaclang.plugin.featurer\x05\x00\x00\x00\xda\x04_Jac\xda\x16jaclang.plugin.builtin\xda\x0bdataclassesr\x07\x00\x00\x00\xda\x11__jac_dataclass__\xda\rTYPE_CHECKINGr\x08\x00\x00\x00\xda\x08__file__\xda\x08make_obj\xda\x03Objr\x14\x00\x00\x00r,\x00\x00\x00\xda\x04gamer \x00\x00\x00r*\x00\x00\x00r\x1c\x00\x00\x00r\x1a\x00\x00\x00\xda\x08rX\x00\x00\x00\x01\x00\x00\x00s\xaa\x00\x00\x00\xf0\x03\x01\x01\x01\xd9\x01\x1d\xf7\x00K\x01\x02\x03\xf7\x00K\x01\x02\x03\xf7\x00K\x01\x02\x03\xf7\x00K\x01\x02\x03\xf0\x00K\x01\x02\x03\xe7\x01\x12\xd7\x01\x12\xd4\x01\x12\x80s\xd7\x01\x12\xd2\x01\x12\xf1\x04\x13\x02\x03\xef&\xe9\x00\xf7\'\x13\x02\x03\xf7\x00\x13\x02\x03\xf4\x00\x13\x02\x03\xef&\xe9\x00\xf7\'\x13\x02\x03\xf4\x00\x13\x02\x03\xf1*)\x02\x03\xefR\x01\xe9\x00\xf7S\x01)\x02\x03\xf7\x00)\x02\x03\xf3\x00)\x02\x03\xf0\n\x00\x1a\x1e\xf0\x0b)\x02\x03\xefR\x01\xe9\x00\xf7S\x01)\x02\x03\xf4\x00)\x02\x03\xf0X\x01\x02\x02\x05\xf1\x08\x00\r\x1f\xd3\x0c \x80T\xd8\x05\t\x87Y\x81Y\x85[r\x1c\x00\x00\x00') -# BBs = create_BBs(instructions) -# print(BBs) +BBs = create_BBs(instructions) +print(BBs) -# cfg = create_cfg(BBs) -# print("\nControl Flow Graph (CFG):") -# print(cfg) +cfg = create_cfg(BBs) +print("\nControl Flow Graph (CFG):") +print(cfg) # # Visualize CFG # dot = visualize_cfg(cfg) From b99df753b8bb094e382b818a9122928ee6e97444 Mon Sep 17 00:00:00 2001 From: Jakob Louis Therkelsen Date: Mon, 18 Nov 2024 16:56:20 -0500 Subject: [PATCH 30/84] bug fix: check last BB for offset diff --- jac/examples/ginsScripts/cfg.gv | 1 - jac/examples/ginsScripts/cfg.gv.pdf | Bin 12070 -> 11975 bytes jac/jaclang/runtimelib/cfg.py | 18 +++++++++--------- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/jac/examples/ginsScripts/cfg.gv b/jac/examples/ginsScripts/cfg.gv index 8054261d06..0774a4c90f 100644 --- a/jac/examples/ginsScripts/cfg.gv +++ b/jac/examples/ginsScripts/cfg.gv @@ -17,5 +17,4 @@ digraph { bb4 -> bb5 bb5 -> bb1 bb6 -> bb7 - bb7 -> bb7 } diff --git a/jac/examples/ginsScripts/cfg.gv.pdf b/jac/examples/ginsScripts/cfg.gv.pdf index 5c6b07069a43fd5893ab5037b765c58806825de7..de98ee28068a00dfd3f7656a4257a2d8ff19c028 100644 GIT binary patch delta 1675 zcmV;626XwRUdLUKOn;qMJ&znW4DIzRRK~^0BB{@Ifgpf^6iKc#Tm&1~M&K)w6#4sk zq@VK(9NXa@>XwG)lhMTK3 zQVTKnZEA{}3pB5rYjoD4(_(hraP`~V%HN;-<eiYqBJ^6Llp8g zV^3KVQ(Nege3MX`<~;}M`k^QF)$0>e0C?Zi{n@ab;#JedOYY$Jr9lvT-QFxCx1rZk_IbvB(vL1GMlsOXvIn5 zH9f}NQ8Z}R66nq4-DY--?taj4nkHz8@1b%%gVuW}NMlVFsUGVbTJ0m7fCuXg;$;pj zZR>L+J({!Uw0j)d+BF}h2`Qu1sf31I3sR{dGUqW~lGEv6G8guujA1w<3Qf>&In*v# z0F3IG-hUHDH!u>_%lS;g=IchG8pF@bWWGMIu;1NVwK;BH~#&e`tb0G*=4QMt4_ zh)TynZ-o^>Yjv|tv*L|}DG{_|m5WB@({|KDtYuD@MIPo;@$fZGJP3fo0ctuo_9j9U3QXiBUypUe)p)pW!S z$UeiZ^Nw5RBW^lkxGfXKt)__^V_!$yShv0$<#NEyMiy?H*&({`!VR~;>$s&C&f3P& zAklE!-qc_>_38@{)>F3nX`ICyz(H2XoPQ-vj(+oa1LUMVn`6kG>~N`0JtnCfB%$Q| zOcSE4Z;DRayDGGif~vSoR1T`MAq)i@J1Rrrwmaf>(1zOE)Zj8ZM)y7PP;f3@M=rl` z;!w|l2X|T9z1Td~!X*gO1xr7Q7nwqVWU4%m5S}ixlP_lbV2x4JWUlc^tLz6`W z5M*%T5+88edJ6=JJ8qN?xFP%nTifP4Yg>-BF_XWhDrC!tLAH6ic(8)USKq(JbrZjhOL}2n_uS%_5vEt^cE6)e53lsD*0R6a)<5D zL$sU1PrsF_&7uHOScr&-*o0p!Dk${oE5H(2MV?B`5#!f(7x#<%47fc`jDfVhjU7S^Rv1Q-IM)AuiLH*2)A!?j zdGGO2kce);NyI=ojp!EZZ59;;(#vg7NNdq58v#h)y2j!I3vl??9vde%h#w zZbqpLVktVKK@*xM4Dr>u!S2#@qOB3bwUai{rd@xn?%x{F~TxRX-+qs zbM`{`Ga;+lGg;60#NH&3Y)pX*Ze|%ixAImwi?PdwxJ1@7$7X8uaaX?Xo zAKU)#-Q$&}R<(q^ur|R2J*S^XwO;yGOVF z3jY)8mBNWH-9Fm+3p~ns(JwgRZs?N)E+7FolO--I0yr>}4hJ2RZ!S?kPGn$UWZ(x9 ztW_W}4j@bG1Bm+%NU${k2_0<^Ybub?2m}$CKtgjrh`0tZg%LzBGwN;wis_zZU;qG6 V*9+8>{w^L0H!?K}B_%~qMhc>pC+7eF delta 1744 zcmV;>1~2)?U8Y`;OnZ4H47}@C=-3>rh@?KR28sd!dT8TYkVEkbCn(}W+e80; zhm^Ft&id6aL18?vv=S+aGo)t8NBrFp{-s*{<;nf&qP_d|C;#@h=s*4K$p3?P@9_J> zefa2Oi2ip+(f{n3N+?u)ZvJWOlp1;>&oKom&BH6T7Fz7uynlGA5>m1b6`Hf1wc+Ms zjnqQSeVdx%<^s*j<{F)~=(Lz!H(b4+NBQfMzkhI)LX449nn&KcR7*%AxhG!)ZenfZ zAD-OX$GdokrTxRB`|!j48&2b2eDm?)o%``&50vgscR>;nh`rY>66#;KO9{Uc?Ht<1 zSyQ$H+K7nTO@Bnp*=4jij(Du;#JeN3FZ&WYGM0C{*v->)X8@QJ>is~icM>EvqQ7ujesc;v}2WvM&;9X)Fjq2r^_M^b1ETArVDLemTT?IMVH0s zy6NghzT~{11^8sPqF&TW{h-xo$vFq61RIWrKWG z%?N92#ePj!SeB!K*IL3x#`11AJM8ZE6i0Z!2{SokmP>#wwpv$V23B~BXAW7fkc@n2 zR)4w*>%G&1lxp{}mbNRE8KkYacL}809RqV2&z?PyogaNKL-toRpyh~0k@it zxB=N`xOLuf>wLsbM+~=RqPW#Gabuk8h#TwCm!n(`xY@|UZ8JOU?z?cqE$}*S>4jX| zI2t4xZrht0?519Q0m7PPtDi#QK@BM$|6@j7z( zg^WWz2Oiv^QAUJwvkYKdx6+VW1+jz*6q=f?l3j#C;94zL#Za<)O9*0NR9_TC)RRL5 z5oC~Yi4VAKy#<2A9XCn`+_3!xTifP4Yg>%9F@wLRDrC!tLAH6 z`zFZB88V1oHppldNrB*L-5@jh%FUob3Jm=U%_5vEtpA~3)e53lsD*0R6a)<?!z$Xjg@wek)a*MFFI+En-K+Cj4SiL7`V) z0nRG&RAP=jer=~;4KZZNu!MHXVnt3Yg_Dwwi)mL=?vRbeigP|F`PtL2hHNRy$nY8k zpA)F+Ih)i_wk9E~^3RSm2KCzm2`EHt-z{vhRr3NgAz=wT#f7S$CCV$4uqV66o$CLe z)A#Nd_b-}@Fk+Kv1s(%5Fg3G@1qvsBYQr!PMDPBJxs=+6##-4sGt-`b1C z2RImNe2!?Rht7eb&1T#<8hsh0GKi&UjRq~KTyVr!=X$$N(~&kt^w(C}g*HuplH9*B zO1M^cd*Kw~{hBkL6H!S^;#u*+if6`>$>c8C|#^Qyi2Zl$UZ+W>v$ zz-wjoV5G9hX3vvfly zIg_sj9g`0(Q9gcPU|?k62NJ9|L1G+0mbO2TV2cG2_kn~?7l`!*NN8*T5hs9zmK=yM mg_yz!BA6NV#DHRYx(o~eXf+D2lb None: @@ -245,14 +245,14 @@ def visualize_cfg(cfg: CFG): ##simple= #instructions = disassemble_bytecode(b'c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x01\xf3*\x00\x00\x00\x97\x00d\x00d\x01l\x00m\x01Z\x01\x01\x00d\x00Z\x02d\x00Z\x03e\x03d\x00k\\\x00\x00r\x02d\x02Z\x02d\x03Z\x02y\x04)\x05\xe9\x00\x00\x00\x00)\x01\xda\x0bannotations\xe9\x01\x00\x00\x00\xe9\xff\xff\xff\xffN)\x04\xda\n__future__r\x02\x00\x00\x00\xda\x01a\xda\x01x\xa9\x00\xf3\x00\x00\x00\x00\xfaP/Users/jakobtherkelsen/Documents/jaseci-ginS/jac/examples/ginsScripts/simple.jac\xfa\x08r\x0b\x00\x00\x00\x01\x00\x00\x00s%\x00\x00\x00\xf0\x03\x01\x01\x01\xf5\x02\x07\x02\x03\xd8\x05\x06\x801\xd8\x05\x06\x801\xd8\x06\x07\x881\x82f\xd8\x07\x08\x80Q\xe0\x05\x07\x811r\t\x00\x00\x00') #hot path -instructions = disassemble_bytecode(b'c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x01\xf3T\x00\x00\x00\x97\x00d\x00d\x01l\x00m\x01Z\x01\x01\x00d\x00Z\x02d\x00Z\x03e\x02d\x02k\x02\x00\x00r\x19e\x02d\x03z\x06\x00\x00d\x00k(\x00\x00r\x03d\x04Z\x03n\x02d\x03Z\x03e\x02d\x04z\r\x00\x00Z\x02e\x02d\x02k\x02\x00\x00r\x01\x8c\x18y\x05y\x05)\x06\xe9\x00\x00\x00\x00)\x01\xda\x0bannotations\xe9\x0f\x00\x00\x00\xe9\x02\x00\x00\x00\xe9\x01\x00\x00\x00N)\x04\xda\n__future__r\x02\x00\x00\x00\xda\x01a\xda\x01b\xa9\x00\xf3\x00\x00\x00\x00\xfaR/Users/jakobtherkelsen/Documents/jaseci-ginS/jac/examples/ginsScripts/hot_path.jac\xfa\x08r\x0c\x00\x00\x00\x01\x00\x00\x00sD\x00\x00\x00\xf0\x03\x01\x01\x01\xf5\x02\x0c\x02\x03\xd8\x07\x08\x801\xd8\x07\x08\x801\xd8\t\n\x88R\x8a\x16\xd8\x08\t\x88A\x89\x05\x90\x11\x8a\n\xd8\x0b\x0c\x81q\xf0\x06\x00\x0c\r\x80q\xe0\x05\x06\x88!\x81W\x80Q\xf0\x0f\x00\n\x0b\x88R\x8d\x16r\n\x00\x00\x00') -# # #guess_game_bc = disassemble_bytecode(b'c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x01\xf3\x9e\x01\x00\x00\x97\x00d\x00Z\x00d\x01d\x02l\x01m\x02Z\x02\x01\x00d\x01d\x03l\x03m\x04Z\x05\x01\x00d\x01d\x04l\x06Z\x07d\x01d\x05l\x08m\tZ\n\x01\x00d\x01d\x06l\x0b\xad\x02\x01\x00d\x01d\x07l\x0cm\rZ\x0e\x01\x00e\x07j\x1e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00r\x05d\x01d\x04l\x10Z\x10n\x10\x02\x00e\x05d\x08e\x11d\td\nd\x04i\x00\xac\x0b\xab\x06\x00\x00\x00\x00\x00\x00\\\x01\x00\x00Z\x10\x02\x00e\nj$\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00g\x00g\x00\xac\x0c\xab\x02\x00\x00\x00\x00\x00\x00\x02\x00e\x0ed\n\xac\r\xab\x01\x00\x00\x00\x00\x00\x00\x02\x00G\x00d\x0e\x84\x00d\x0fe\nj&\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xab\x03\x00\x00\x00\x00\x00\x00\xab\x00\x00\x00\x00\x00\x00\x00\xab\x00\x00\x00\x00\x00\x00\x00Z\x14\x02\x00e\nj$\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00g\x00g\x00\xac\x0c\xab\x02\x00\x00\x00\x00\x00\x00\x02\x00e\x0ed\n\xac\r\xab\x01\x00\x00\x00\x00\x00\x00\x02\x00G\x00d\x10\x84\x00d\x11e\x14e\nj&\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xab\x04\x00\x00\x00\x00\x00\x00\xab\x00\x00\x00\x00\x00\x00\x00\xab\x00\x00\x00\x00\x00\x00\x00Z\x15\t\x00\x02\x00e\x15\xab\x00\x00\x00\x00\x00\x00\x00Z\x16e\x16j/\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xab\x00\x00\x00\x00\x00\x00\x00\x01\x00y\x04)\x12\xfa\x16A Number Guessing Game\xe9\x00\x00\x00\x00)\x01\xda\x0bannotations)\x01\xda\njac_importN)\x01\xda\nJacFeature)\x01\xda\x01*)\x01\xda\tdataclass\xda\x06random\xda\x02pyF)\x06\xda\x06target\xda\tbase_path\xda\x03lng\xda\x06absorb\xda\tmdl_alias\xda\x05items)\x02\xda\x08on_entry\xda\x07on_exit)\x01\xda\x02eqc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x01\xf3 \x00\x00\x00\x97\x00e\x00Z\x01d\x00Z\x02d\x01Z\x03d\x05d\x02\x84\x04Z\x04d\x06d\x03\x84\x04Z\x05y\x04)\x07\xda\x04Game\xe1\x1a\x01\x00\x00\nA generic Game base class.\n\nThe obj keyword is used to define the class.\nThe can keyword is used to define methods (functions) within the class.\nThe self keyword is used to refer to the current instance of the class.\nConstructors are defined using the init method with parameters.\nc\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x01\xf3 \x00\x00\x00\x97\x00|\x01|\x00_\x00\x00\x00\x00\x00\x00\x00\x00\x00d\x01|\x00_\x01\x00\x00\x00\x00\x00\x00\x00\x00y\x00)\x02NF)\x02\xda\x08attempts\xda\x03won)\x02\xda\x04selfr\x17\x00\x00\x00s\x02\x00\x00\x00 \xfaT/Users/jakobtherkelsen/Documents/jaseci-ginS/jac/examples/guess_game/guess_game1.jac\xda\x08__init__z\rGame.__init__\x0e\x00\x00\x00s\x10\x00\x00\x00\x80\x00\xd8\x19!\x88\x14\x8c\x1d\xd8\x14\x19\x88\x14\x8d\x18\xf3\x00\x00\x00\x00c\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03\x00\x00\x01\xf3\x18\x00\x00\x00\x97\x00t\x01\x00\x00\x00\x00\x00\x00\x00\x00d\x01\xab\x01\x00\x00\x00\x00\x00\x00\x82\x01)\x02N\xfa&Subclasses must implement this method.)\x01\xda\x13NotImplementedError)\x01r\x19\x00\x00\x00s\x01\x00\x00\x00 r\x1a\x00\x00\x00\xda\x04playz\tGame.play\x13\x00\x00\x00s\x12\x00\x00\x00\x80\x00\xdc\x0f"\xd8\r5\xf3\x03\x02\x10\x10\xf0\x00\x02\n\x0cr\x1c\x00\x00\x00N\xa9\x04r\x17\x00\x00\x00\xda\x03int\xda\x06return\xda\x04None\xa9\x02r#\x00\x00\x00r$\x00\x00\x00)\x06\xda\x08__name__\xda\n__module__\xda\x0c__qualname__\xda\x07__doc__r\x1b\x00\x00\x00r \x00\x00\x00\xa9\x00r\x1c\x00\x00\x00r\x1a\x00\x00\x00r\x14\x00\x00\x00r\x14\x00\x00\x00\x05\x00\x00\x00s\x11\x00\x00\x00\x84\x00\xf1\x00\x07\x02\x05\xf3\x12\x03\x06\x07\xf4\n\x04\x06\x07r\x1c\x00\x00\x00r\x14\x00\x00\x00c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x01\xf36\x00\x00\x00\x87\x00\x97\x00e\x00Z\x01d\x00Z\x02d\x01Z\x03d\x05d\x06\x88\x00f\x01d\x02\x84\rZ\x04d\x07d\x03\x84\x04Z\x05d\x08d\x04\x84\x04Z\x06\x88\x00x\x01Z\x07S\x00)\t\xda\x12GuessTheNumberGame\xfa\xae\nA number guessing game. The player must guess a number between 1 and 100.\n\nThis class inherits from Game. The super() function is used to call the parent class constructor.\nc\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x03\x00\x00\x01\xf3Z\x00\x00\x00\x95\x01\x97\x00t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x89\x02|\x00\x8d\x05\x00\x00|\x01\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00t\x05\x00\x00\x00\x00\x00\x00\x00\x00j\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00d\x01d\x02\xab\x02\x00\x00\x00\x00\x00\x00|\x00_\x04\x00\x00\x00\x00\x00\x00\x00\x00y\x00)\x03N\xe9\x01\x00\x00\x00\xe9d\x00\x00\x00)\x05\xda\x05superr\x1b\x00\x00\x00r\x08\x00\x00\x00\xda\x07randint\xda\x0ecorrect_number)\x03r\x19\x00\x00\x00r\x17\x00\x00\x00\xda\t__class__s\x03\x00\x00\x00 \x80r\x1a\x00\x00\x00r\x1b\x00\x00\x00z\x1bGuessTheNumberGame.__init__ \x00\x00\x00s \x00\x00\x00\xf8\x80\x00\xde\t\x0e\x89\x1a\x90H\xd4\t\x1d\xdc\x1f%\x9f~\x99~\xa8a\xb0\x13\xd3\x1f5\x88\x14\xd5\t\x1cr\x1c\x00\x00\x00c\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x03\x00\x00\x01\xf3\xf4\x00\x00\x00\x97\x00|\x00j\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00d\x01kD\x00\x00rQt\x03\x00\x00\x00\x00\x00\x00\x00\x00d\x02\xab\x01\x00\x00\x00\x00\x00\x00}\x01|\x01j\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xab\x00\x00\x00\x00\x00\x00\x00r\x1b|\x00j\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00t\t\x00\x00\x00\x00\x00\x00\x00\x00|\x01\xab\x01\x00\x00\x00\x00\x00\x00\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00n\x0bt\x0b\x00\x00\x00\x00\x00\x00\x00\x00d\x03\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00|\x00j\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00d\x01kD\x00\x00r\x01\x8cQ|\x00j\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00s\x0ct\x0b\x00\x00\x00\x00\x00\x00\x00\x00d\x04\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00y\x00y\x00)\x05Nr\x02\x00\x00\x00\xfa"Guess a number between 1 and 100: \xfa%That\'s not a valid number! Try again.\xfa:Sorry, you didn\'t guess the number. Better luck next time!)\x07r\x17\x00\x00\x00\xda\x05input\xda\x07isdigit\xda\rprocess_guessr"\x00\x00\x00\xda\x05printr\x18\x00\x00\x00\xa9\x02r\x19\x00\x00\x00\xda\x05guesss\x02\x00\x00\x00 r\x1a\x00\x00\x00\xfa\x04playz\x17GuessTheNumberGame.play%\x00\x00\x00sd\x00\x00\x00\x80\x00\xe0\x0f\x13\x8f}\x89}\x98q\xd2\x0f \xdc\x15\x1a\xd0\x1b?\xd3\x15@\x88U\xd8\x10\x15\x97\r\x91\r\x94\x0f\xd8\x11\x15\xd7\x11#\xd1\x11#\xa4C\xa8\x05\xa3J\xd5\x11/\xe4\x11\x16\xd0\x17>\xd4\x11?\xf0\x0b\x00\x10\x14\x8f}\x89}\x98q\xd3\x0f \xf0\x10\x00\x11\x15\x97\x08\x92\x08\xdc\r\x12\xd8\x11M\xf5\x03\x02\x0e\x0f\xf0\x03\x00\x11\x19r\x1c\x00\x00\x00c\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x03\x00\x00\x01\xf3\xfe\x00\x00\x00\x97\x00|\x01|\x00j\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00kD\x00\x00r\x0ct\x03\x00\x00\x00\x00\x00\x00\x00\x00d\x01\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00n4|\x01|\x00j\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00k\x02\x00\x00r\x0ct\x03\x00\x00\x00\x00\x00\x00\x00\x00d\x02\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00n\x19t\x03\x00\x00\x00\x00\x00\x00\x00\x00d\x03\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00d\x04|\x00_\x02\x00\x00\x00\x00\x00\x00\x00\x00d\x05|\x00_\x03\x00\x00\x00\x00\x00\x00\x00\x00|\x00x\x01j\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00d\x06z\x17\x00\x00c\x02_\x02\x00\x00\x00\x00\x00\x00\x00\x00t\x03\x00\x00\x00\x00\x00\x00\x00\x00d\x07|\x00j\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9b\x00d\x08\x9d\x03\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00y\x00)\tN\xfa\tToo high!\xfa\x08Too low!\xfa\'Congratulations! You guessed correctly.r\x02\x00\x00\x00Tr/\x00\x00\x00\xfa\tYou have \xfa\x0f attempts left.)\x04r3\x00\x00\x00r<\x00\x00\x00r\x17\x00\x00\x00r\x18\x00\x00\x00r=\x00\x00\x00s\x02\x00\x00\x00 r\x1a\x00\x00\x00\xfa\rprocess_guessz GuessTheNumberGame.process_guess6\x00\x00\x00se\x00\x00\x00\x80\x00\xd8\x0c\x11\x90D\xd7\x14\'\xd1\x14\'\xd2\x0c\'\xdc\r\x12\x90;\xd5\r\x1f\xd8\x10\x15\x98\x04\xd7\x18+\xd1\x18+\xd2\x10+\xdc\r\x12\x90:\xd5\r\x1e\xe4\r\x12\xd0\x13<\xd4\r=\xd8\x1d\x1e\x88T\x8c]\xd8\x18\x1c\x88T\x8cX\xe0\t\r\x8f\x1d\x8a\x1d\x98!\xd1\t\x1c\x8d\x1d\xdc\t\x0e\xd0\x0f9\x984\x9f=\x9a=\xd1\x0f9\xd5\t:r\x1c\x00\x00\x00)\x01\xe9\n\x00\x00\x00r!\x00\x00\x00r%\x00\x00\x00)\x04r>\x00\x00\x00r"\x00\x00\x00r#\x00\x00\x00r$\x00\x00\x00)\x08r&\x00\x00\x00r\'\x00\x00\x00r(\x00\x00\x00r)\x00\x00\x00r\x1b\x00\x00\x00r \x00\x00\x00r;\x00\x00\x00\xda\r__classcell__)\x01r4\x00\x00\x00s\x01\x00\x00\x00@r\x1a\x00\x00\x00r,\x00\x00\x00r,\x00\x00\x00\x1a\x00\x00\x00s\x17\x00\x00\x00\xf8\x84\x00\xf1\x00\x04\x02\x05\xf6\x0c\x03\x06\x07\xf3\n\x0f\x06\x07\xf7"\x0c\x06\x07r\x1c\x00\x00\x00r,\x00\x00\x00)\x18r)\x00\x00\x00\xda\n__future__r\x03\x00\x00\x00\xda\x07jaclangr\x04\x00\x00\x00\xda\x0e__jac_import__\xda\x06typing\xda\x08_jac_typ\xda\x16jaclang.plugin.featurer\x05\x00\x00\x00\xda\x04_Jac\xda\x16jaclang.plugin.builtin\xda\x0bdataclassesr\x07\x00\x00\x00\xda\x11__jac_dataclass__\xda\rTYPE_CHECKINGr\x08\x00\x00\x00\xda\x08__file__\xda\x08make_obj\xda\x03Objr\x14\x00\x00\x00r,\x00\x00\x00\xda\x04gamer \x00\x00\x00r*\x00\x00\x00r\x1c\x00\x00\x00r\x1a\x00\x00\x00\xda\x08rX\x00\x00\x00\x01\x00\x00\x00s\xaa\x00\x00\x00\xf0\x03\x01\x01\x01\xd9\x01\x1d\xf7\x00K\x01\x02\x03\xf7\x00K\x01\x02\x03\xf7\x00K\x01\x02\x03\xf7\x00K\x01\x02\x03\xf0\x00K\x01\x02\x03\xe7\x01\x12\xd7\x01\x12\xd4\x01\x12\x80s\xd7\x01\x12\xd2\x01\x12\xf1\x04\x13\x02\x03\xef&\xe9\x00\xf7\'\x13\x02\x03\xf7\x00\x13\x02\x03\xf4\x00\x13\x02\x03\xef&\xe9\x00\xf7\'\x13\x02\x03\xf4\x00\x13\x02\x03\xf1*)\x02\x03\xefR\x01\xe9\x00\xf7S\x01)\x02\x03\xf7\x00)\x02\x03\xf3\x00)\x02\x03\xf0\n\x00\x1a\x1e\xf0\x0b)\x02\x03\xefR\x01\xe9\x00\xf7S\x01)\x02\x03\xf4\x00)\x02\x03\xf0X\x01\x02\x02\x05\xf1\x08\x00\r\x1f\xd3\x0c \x80T\xd8\x05\t\x87Y\x81Y\x85[r\x1c\x00\x00\x00') -BBs = create_BBs(instructions) -print(BBs) +# instructions = disassemble_bytecode(b'c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x01\xf3T\x00\x00\x00\x97\x00d\x00d\x01l\x00m\x01Z\x01\x01\x00d\x00Z\x02d\x00Z\x03e\x02d\x02k\x02\x00\x00r\x19e\x02d\x03z\x06\x00\x00d\x00k(\x00\x00r\x03d\x04Z\x03n\x02d\x03Z\x03e\x02d\x04z\r\x00\x00Z\x02e\x02d\x02k\x02\x00\x00r\x01\x8c\x18y\x05y\x05)\x06\xe9\x00\x00\x00\x00)\x01\xda\x0bannotations\xe9\x0f\x00\x00\x00\xe9\x02\x00\x00\x00\xe9\x01\x00\x00\x00N)\x04\xda\n__future__r\x02\x00\x00\x00\xda\x01a\xda\x01b\xa9\x00\xf3\x00\x00\x00\x00\xfaR/Users/jakobtherkelsen/Documents/jaseci-ginS/jac/examples/ginsScripts/hot_path.jac\xfa\x08r\x0c\x00\x00\x00\x01\x00\x00\x00sD\x00\x00\x00\xf0\x03\x01\x01\x01\xf5\x02\x0c\x02\x03\xd8\x07\x08\x801\xd8\x07\x08\x801\xd8\t\n\x88R\x8a\x16\xd8\x08\t\x88A\x89\x05\x90\x11\x8a\n\xd8\x0b\x0c\x81q\xf0\x06\x00\x0c\r\x80q\xe0\x05\x06\x88!\x81W\x80Q\xf0\x0f\x00\n\x0b\x88R\x8d\x16r\n\x00\x00\x00') +# # # #guess_game_bc = disassemble_bytecode(b'c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x01\xf3\x9e\x01\x00\x00\x97\x00d\x00Z\x00d\x01d\x02l\x01m\x02Z\x02\x01\x00d\x01d\x03l\x03m\x04Z\x05\x01\x00d\x01d\x04l\x06Z\x07d\x01d\x05l\x08m\tZ\n\x01\x00d\x01d\x06l\x0b\xad\x02\x01\x00d\x01d\x07l\x0cm\rZ\x0e\x01\x00e\x07j\x1e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00r\x05d\x01d\x04l\x10Z\x10n\x10\x02\x00e\x05d\x08e\x11d\td\nd\x04i\x00\xac\x0b\xab\x06\x00\x00\x00\x00\x00\x00\\\x01\x00\x00Z\x10\x02\x00e\nj$\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00g\x00g\x00\xac\x0c\xab\x02\x00\x00\x00\x00\x00\x00\x02\x00e\x0ed\n\xac\r\xab\x01\x00\x00\x00\x00\x00\x00\x02\x00G\x00d\x0e\x84\x00d\x0fe\nj&\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xab\x03\x00\x00\x00\x00\x00\x00\xab\x00\x00\x00\x00\x00\x00\x00\xab\x00\x00\x00\x00\x00\x00\x00Z\x14\x02\x00e\nj$\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00g\x00g\x00\xac\x0c\xab\x02\x00\x00\x00\x00\x00\x00\x02\x00e\x0ed\n\xac\r\xab\x01\x00\x00\x00\x00\x00\x00\x02\x00G\x00d\x10\x84\x00d\x11e\x14e\nj&\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xab\x04\x00\x00\x00\x00\x00\x00\xab\x00\x00\x00\x00\x00\x00\x00\xab\x00\x00\x00\x00\x00\x00\x00Z\x15\t\x00\x02\x00e\x15\xab\x00\x00\x00\x00\x00\x00\x00Z\x16e\x16j/\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xab\x00\x00\x00\x00\x00\x00\x00\x01\x00y\x04)\x12\xfa\x16A Number Guessing Game\xe9\x00\x00\x00\x00)\x01\xda\x0bannotations)\x01\xda\njac_importN)\x01\xda\nJacFeature)\x01\xda\x01*)\x01\xda\tdataclass\xda\x06random\xda\x02pyF)\x06\xda\x06target\xda\tbase_path\xda\x03lng\xda\x06absorb\xda\tmdl_alias\xda\x05items)\x02\xda\x08on_entry\xda\x07on_exit)\x01\xda\x02eqc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x01\xf3 \x00\x00\x00\x97\x00e\x00Z\x01d\x00Z\x02d\x01Z\x03d\x05d\x02\x84\x04Z\x04d\x06d\x03\x84\x04Z\x05y\x04)\x07\xda\x04Game\xe1\x1a\x01\x00\x00\nA generic Game base class.\n\nThe obj keyword is used to define the class.\nThe can keyword is used to define methods (functions) within the class.\nThe self keyword is used to refer to the current instance of the class.\nConstructors are defined using the init method with parameters.\nc\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x01\xf3 \x00\x00\x00\x97\x00|\x01|\x00_\x00\x00\x00\x00\x00\x00\x00\x00\x00d\x01|\x00_\x01\x00\x00\x00\x00\x00\x00\x00\x00y\x00)\x02NF)\x02\xda\x08attempts\xda\x03won)\x02\xda\x04selfr\x17\x00\x00\x00s\x02\x00\x00\x00 \xfaT/Users/jakobtherkelsen/Documents/jaseci-ginS/jac/examples/guess_game/guess_game1.jac\xda\x08__init__z\rGame.__init__\x0e\x00\x00\x00s\x10\x00\x00\x00\x80\x00\xd8\x19!\x88\x14\x8c\x1d\xd8\x14\x19\x88\x14\x8d\x18\xf3\x00\x00\x00\x00c\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03\x00\x00\x01\xf3\x18\x00\x00\x00\x97\x00t\x01\x00\x00\x00\x00\x00\x00\x00\x00d\x01\xab\x01\x00\x00\x00\x00\x00\x00\x82\x01)\x02N\xfa&Subclasses must implement this method.)\x01\xda\x13NotImplementedError)\x01r\x19\x00\x00\x00s\x01\x00\x00\x00 r\x1a\x00\x00\x00\xda\x04playz\tGame.play\x13\x00\x00\x00s\x12\x00\x00\x00\x80\x00\xdc\x0f"\xd8\r5\xf3\x03\x02\x10\x10\xf0\x00\x02\n\x0cr\x1c\x00\x00\x00N\xa9\x04r\x17\x00\x00\x00\xda\x03int\xda\x06return\xda\x04None\xa9\x02r#\x00\x00\x00r$\x00\x00\x00)\x06\xda\x08__name__\xda\n__module__\xda\x0c__qualname__\xda\x07__doc__r\x1b\x00\x00\x00r \x00\x00\x00\xa9\x00r\x1c\x00\x00\x00r\x1a\x00\x00\x00r\x14\x00\x00\x00r\x14\x00\x00\x00\x05\x00\x00\x00s\x11\x00\x00\x00\x84\x00\xf1\x00\x07\x02\x05\xf3\x12\x03\x06\x07\xf4\n\x04\x06\x07r\x1c\x00\x00\x00r\x14\x00\x00\x00c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x01\xf36\x00\x00\x00\x87\x00\x97\x00e\x00Z\x01d\x00Z\x02d\x01Z\x03d\x05d\x06\x88\x00f\x01d\x02\x84\rZ\x04d\x07d\x03\x84\x04Z\x05d\x08d\x04\x84\x04Z\x06\x88\x00x\x01Z\x07S\x00)\t\xda\x12GuessTheNumberGame\xfa\xae\nA number guessing game. The player must guess a number between 1 and 100.\n\nThis class inherits from Game. The super() function is used to call the parent class constructor.\nc\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x03\x00\x00\x01\xf3Z\x00\x00\x00\x95\x01\x97\x00t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x89\x02|\x00\x8d\x05\x00\x00|\x01\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00t\x05\x00\x00\x00\x00\x00\x00\x00\x00j\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00d\x01d\x02\xab\x02\x00\x00\x00\x00\x00\x00|\x00_\x04\x00\x00\x00\x00\x00\x00\x00\x00y\x00)\x03N\xe9\x01\x00\x00\x00\xe9d\x00\x00\x00)\x05\xda\x05superr\x1b\x00\x00\x00r\x08\x00\x00\x00\xda\x07randint\xda\x0ecorrect_number)\x03r\x19\x00\x00\x00r\x17\x00\x00\x00\xda\t__class__s\x03\x00\x00\x00 \x80r\x1a\x00\x00\x00r\x1b\x00\x00\x00z\x1bGuessTheNumberGame.__init__ \x00\x00\x00s \x00\x00\x00\xf8\x80\x00\xde\t\x0e\x89\x1a\x90H\xd4\t\x1d\xdc\x1f%\x9f~\x99~\xa8a\xb0\x13\xd3\x1f5\x88\x14\xd5\t\x1cr\x1c\x00\x00\x00c\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x03\x00\x00\x01\xf3\xf4\x00\x00\x00\x97\x00|\x00j\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00d\x01kD\x00\x00rQt\x03\x00\x00\x00\x00\x00\x00\x00\x00d\x02\xab\x01\x00\x00\x00\x00\x00\x00}\x01|\x01j\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xab\x00\x00\x00\x00\x00\x00\x00r\x1b|\x00j\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00t\t\x00\x00\x00\x00\x00\x00\x00\x00|\x01\xab\x01\x00\x00\x00\x00\x00\x00\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00n\x0bt\x0b\x00\x00\x00\x00\x00\x00\x00\x00d\x03\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00|\x00j\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00d\x01kD\x00\x00r\x01\x8cQ|\x00j\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00s\x0ct\x0b\x00\x00\x00\x00\x00\x00\x00\x00d\x04\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00y\x00y\x00)\x05Nr\x02\x00\x00\x00\xfa"Guess a number between 1 and 100: \xfa%That\'s not a valid number! Try again.\xfa:Sorry, you didn\'t guess the number. Better luck next time!)\x07r\x17\x00\x00\x00\xda\x05input\xda\x07isdigit\xda\rprocess_guessr"\x00\x00\x00\xda\x05printr\x18\x00\x00\x00\xa9\x02r\x19\x00\x00\x00\xda\x05guesss\x02\x00\x00\x00 r\x1a\x00\x00\x00\xfa\x04playz\x17GuessTheNumberGame.play%\x00\x00\x00sd\x00\x00\x00\x80\x00\xe0\x0f\x13\x8f}\x89}\x98q\xd2\x0f \xdc\x15\x1a\xd0\x1b?\xd3\x15@\x88U\xd8\x10\x15\x97\r\x91\r\x94\x0f\xd8\x11\x15\xd7\x11#\xd1\x11#\xa4C\xa8\x05\xa3J\xd5\x11/\xe4\x11\x16\xd0\x17>\xd4\x11?\xf0\x0b\x00\x10\x14\x8f}\x89}\x98q\xd3\x0f \xf0\x10\x00\x11\x15\x97\x08\x92\x08\xdc\r\x12\xd8\x11M\xf5\x03\x02\x0e\x0f\xf0\x03\x00\x11\x19r\x1c\x00\x00\x00c\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x03\x00\x00\x01\xf3\xfe\x00\x00\x00\x97\x00|\x01|\x00j\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00kD\x00\x00r\x0ct\x03\x00\x00\x00\x00\x00\x00\x00\x00d\x01\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00n4|\x01|\x00j\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00k\x02\x00\x00r\x0ct\x03\x00\x00\x00\x00\x00\x00\x00\x00d\x02\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00n\x19t\x03\x00\x00\x00\x00\x00\x00\x00\x00d\x03\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00d\x04|\x00_\x02\x00\x00\x00\x00\x00\x00\x00\x00d\x05|\x00_\x03\x00\x00\x00\x00\x00\x00\x00\x00|\x00x\x01j\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00d\x06z\x17\x00\x00c\x02_\x02\x00\x00\x00\x00\x00\x00\x00\x00t\x03\x00\x00\x00\x00\x00\x00\x00\x00d\x07|\x00j\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9b\x00d\x08\x9d\x03\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00y\x00)\tN\xfa\tToo high!\xfa\x08Too low!\xfa\'Congratulations! You guessed correctly.r\x02\x00\x00\x00Tr/\x00\x00\x00\xfa\tYou have \xfa\x0f attempts left.)\x04r3\x00\x00\x00r<\x00\x00\x00r\x17\x00\x00\x00r\x18\x00\x00\x00r=\x00\x00\x00s\x02\x00\x00\x00 r\x1a\x00\x00\x00\xfa\rprocess_guessz GuessTheNumberGame.process_guess6\x00\x00\x00se\x00\x00\x00\x80\x00\xd8\x0c\x11\x90D\xd7\x14\'\xd1\x14\'\xd2\x0c\'\xdc\r\x12\x90;\xd5\r\x1f\xd8\x10\x15\x98\x04\xd7\x18+\xd1\x18+\xd2\x10+\xdc\r\x12\x90:\xd5\r\x1e\xe4\r\x12\xd0\x13<\xd4\r=\xd8\x1d\x1e\x88T\x8c]\xd8\x18\x1c\x88T\x8cX\xe0\t\r\x8f\x1d\x8a\x1d\x98!\xd1\t\x1c\x8d\x1d\xdc\t\x0e\xd0\x0f9\x984\x9f=\x9a=\xd1\x0f9\xd5\t:r\x1c\x00\x00\x00)\x01\xe9\n\x00\x00\x00r!\x00\x00\x00r%\x00\x00\x00)\x04r>\x00\x00\x00r"\x00\x00\x00r#\x00\x00\x00r$\x00\x00\x00)\x08r&\x00\x00\x00r\'\x00\x00\x00r(\x00\x00\x00r)\x00\x00\x00r\x1b\x00\x00\x00r \x00\x00\x00r;\x00\x00\x00\xda\r__classcell__)\x01r4\x00\x00\x00s\x01\x00\x00\x00@r\x1a\x00\x00\x00r,\x00\x00\x00r,\x00\x00\x00\x1a\x00\x00\x00s\x17\x00\x00\x00\xf8\x84\x00\xf1\x00\x04\x02\x05\xf6\x0c\x03\x06\x07\xf3\n\x0f\x06\x07\xf7"\x0c\x06\x07r\x1c\x00\x00\x00r,\x00\x00\x00)\x18r)\x00\x00\x00\xda\n__future__r\x03\x00\x00\x00\xda\x07jaclangr\x04\x00\x00\x00\xda\x0e__jac_import__\xda\x06typing\xda\x08_jac_typ\xda\x16jaclang.plugin.featurer\x05\x00\x00\x00\xda\x04_Jac\xda\x16jaclang.plugin.builtin\xda\x0bdataclassesr\x07\x00\x00\x00\xda\x11__jac_dataclass__\xda\rTYPE_CHECKINGr\x08\x00\x00\x00\xda\x08__file__\xda\x08make_obj\xda\x03Objr\x14\x00\x00\x00r,\x00\x00\x00\xda\x04gamer \x00\x00\x00r*\x00\x00\x00r\x1c\x00\x00\x00r\x1a\x00\x00\x00\xda\x08rX\x00\x00\x00\x01\x00\x00\x00s\xaa\x00\x00\x00\xf0\x03\x01\x01\x01\xd9\x01\x1d\xf7\x00K\x01\x02\x03\xf7\x00K\x01\x02\x03\xf7\x00K\x01\x02\x03\xf7\x00K\x01\x02\x03\xf0\x00K\x01\x02\x03\xe7\x01\x12\xd7\x01\x12\xd4\x01\x12\x80s\xd7\x01\x12\xd2\x01\x12\xf1\x04\x13\x02\x03\xef&\xe9\x00\xf7\'\x13\x02\x03\xf7\x00\x13\x02\x03\xf4\x00\x13\x02\x03\xef&\xe9\x00\xf7\'\x13\x02\x03\xf4\x00\x13\x02\x03\xf1*)\x02\x03\xefR\x01\xe9\x00\xf7S\x01)\x02\x03\xf7\x00)\x02\x03\xf3\x00)\x02\x03\xf0\n\x00\x1a\x1e\xf0\x0b)\x02\x03\xefR\x01\xe9\x00\xf7S\x01)\x02\x03\xf4\x00)\x02\x03\xf0X\x01\x02\x02\x05\xf1\x08\x00\r\x1f\xd3\x0c \x80T\xd8\x05\t\x87Y\x81Y\x85[r\x1c\x00\x00\x00') +# BBs = create_BBs(instructions) +# print(BBs) -cfg = create_cfg(BBs) -print("\nControl Flow Graph (CFG):") -print(cfg) +# cfg = create_cfg(BBs) +# print("\nControl Flow Graph (CFG):") +# print(cfg) # # Visualize CFG # dot = visualize_cfg(cfg) From af4ac616075ef7b71dfe89f31285a2cff936044d Mon Sep 17 00:00:00 2001 From: Jakob Louis Therkelsen Date: Mon, 18 Nov 2024 17:01:25 -0500 Subject: [PATCH 31/84] bug fix: stop last BB from self referencing on edge --- jac/jaclang/runtimelib/cfg.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/jac/jaclang/runtimelib/cfg.py b/jac/jaclang/runtimelib/cfg.py index 264c688119..5c210bd417 100644 --- a/jac/jaclang/runtimelib/cfg.py +++ b/jac/jaclang/runtimelib/cfg.py @@ -6,8 +6,8 @@ import dis from collections import defaultdict from typing import List, Optional, Iterator -# import graphviz -# from graphviz import Digraph +import graphviz +from graphviz import Digraph class BytecodeOp: def __init__(self, op: int, arg: int, offset: int, argval:int, is_jump_target: bool) -> None: @@ -201,7 +201,7 @@ def create_cfg(block_map: BlockMap) -> CFG: else: fall_through_offset = block.instructions[-1].get_next_instruction_offset() fall_through_block = find_block_by_offset(block_map, fall_through_offset) - if fall_through_block is not None: + if fall_through_block is not None and fall_through_offset != last_instr.offset: cfg.add_edge(block_id, fall_through_block) return cfg From 0d602f347427130cd8ecff6c0378c088344f1493 Mon Sep 17 00:00:00 2001 From: Jakob Louis Therkelsen Date: Wed, 20 Nov 2024 14:36:42 -0500 Subject: [PATCH 32/84] comment out for testing --- jac/jaclang/runtimelib/machine.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/jac/jaclang/runtimelib/machine.py b/jac/jaclang/runtimelib/machine.py index 48a857db94..dfdbb6431e 100644 --- a/jac/jaclang/runtimelib/machine.py +++ b/jac/jaclang/runtimelib/machine.py @@ -340,9 +340,11 @@ def start_ghost(self): self.__ghost_thread.start() def worker(self): - genai.configure(api_key=os.getenv("GEN_AI_KEY")) - model = genai.GenerativeModel("gemini-1.5-flash") - response_dict = {'cfg': self.cfgs} + #this is temporary while developing + print(self.cfgs) + # genai.configure(api_key=os.getenv("GEN_AI_KEY")) + # model = genai.GenerativeModel("gemini-1.5-flash") + # response_dict = {'cfg': self.cfgs} # prompt = [] # for k,v in response_dict.items(): # prompt.append(f"here is my {k}:\n{v}") @@ -354,4 +356,4 @@ def worker(self): # print("RESPONSE:\n") # print(response.text) - print(self.cfgs['hot_path'].display_instructions()) \ No newline at end of file + # print(self.cfgs['hot_path'].display_instructions()) \ No newline at end of file From c3b74df44421eceb4571bfcee0f1ec2de17f66fb Mon Sep 17 00:00:00 2001 From: Jakob Louis Therkelsen Date: Wed, 20 Nov 2024 17:12:14 -0500 Subject: [PATCH 33/84] show changes without AI prompt --- jac/examples/ginsScripts/cfg.gv.pdf | Bin 11975 -> 11974 bytes jac/jaclang/compiler/passes/cfg.py | 27 +++++++++++++++++++-------- jac/jaclang/runtimelib/machine.py | 18 +++++++++--------- 3 files changed, 28 insertions(+), 17 deletions(-) diff --git a/jac/examples/ginsScripts/cfg.gv.pdf b/jac/examples/ginsScripts/cfg.gv.pdf index de98ee28068a00dfd3f7656a4257a2d8ff19c028..76d0b2e4985600548187a8b839c5c218c5c9a933 100644 GIT binary patch delta 308 zcmV-40n7f!UB+Fooh*N*hiQ^(Ek$~$LK$NqZEs_T5Q7zlktB}wzh9!&F>?BTyf5!P zJ_-`hEiw`?(2NE&$0kpMqCj%J4-!euTWJCS$y?VLe1L)AjL!*`YV0j&a5zjGwN}k2 zq(&%srxj>ScQHeFvvx51B$;Td`EcumiIr}nX#Pe^ZadXi+)96h)t(WSQpyO;SeB9( zl06d=Ehc}l@Z_xhe$BP?IefASyvwHJNA=_468G3HLz-{b(7knXgLKuOv>FE#g&+Jp zdrWje7e_Vk&EUPneZjA=dX&plI#ngVJ0Z`fqlYfD=VxiusD(7xtezLQDC`{FxGVgt zS8~h0RQqV>F7OB_=S06L%5K_|q%9x;HL>7HR=002Cwxw*)MM{Jqy2u`sEuw$ zsSIK%I-@}onkNkL)w#j$(sZJ&5yQ2UHqoYCt?u6#C0wWbN;rRoxY{woGD>MqH=J|! zLijTwtJ&l)7M{Fy*sq0AAxB6yfp^t(;-G(gT;d&5fz7p1#LxBd$M z>XpKYFWo-c`3ovM%6ZW*IN@&S3T19&b98cLVQmU!Ze(v_Y6>wpATS_rVrmK?ARsa~ iIFrOJ&I|*J>7Hd^002 Dict[int, int]: + """Calculate the size of each instruction""" + sizes = {} + for i, inst in enumerate(instructions): + if i + 1 < len(instructions): + sizes[inst.offset] = instructions[i + 1].offset - inst.offset + else: + # Last instruction, assume size 1 for simplicity + sizes[inst.offset] = 1 + return sizes + def build_cfg(self, code: types.CodeType) -> Dict[int, CFGNode]: """Build CFG from bytecode""" if code in self.cfg_cache: @@ -30,6 +40,7 @@ def build_cfg(self, code: types.CodeType) -> Dict[int, CFGNode]: # Get bytecode instructions instructions = list(dis.get_instructions(code)) + instruction_sizes = self.instruction_sizes(instructions) # Find basic block boundaries leaders = {0} # First instruction is always a leader @@ -66,15 +77,15 @@ def build_cfg(self, code: types.CodeType) -> Dict[int, CFGNode]: elif last_inst.opname in {'POP_JUMP_IF_TRUE', 'POP_JUMP_IF_FALSE', 'JUMP_IF_TRUE_OR_POP', 'JUMP_IF_FALSE_OR_POP'}: block.next.append(blocks[last_inst.argval]) # Branch target - if offset + last_inst.size < instructions[-1].offset: + if offset + instruction_sizes[offset] < instructions[-1].offset: # Find next instruction's block - next_offset = offset + last_inst.size + next_offset = offset + instruction_sizes[offset] while next_offset not in blocks: next_offset += 1 block.next.append(blocks[next_offset]) # Fall-through - elif offset + last_inst.size < instructions[-1].offset: + elif offset + instruction_sizes[offset] < instructions[-1].offset: # Sequential flow - next_offset = offset + last_inst.size + next_offset = offset + instruction_sizes[offset] while next_offset not in blocks: next_offset += 1 block.next.append(blocks[next_offset]) @@ -82,7 +93,7 @@ def build_cfg(self, code: types.CodeType) -> Dict[int, CFGNode]: self.cfg_cache[code] = blocks return blocks - def trace_callback(self, frame: types.FrameType, event: str, arg: Any) -> Optional[types.TraceFunction]: + def trace_callback(self, frame: types.FrameType, event: str, arg: any): """Trace function to track executed branches""" if event != 'line': return self.trace_callback @@ -98,7 +109,7 @@ def trace_callback(self, frame: types.FrameType, event: str, arg: Any) -> Option # Find the block containing this offset current_block = None for block in blocks.values(): - if block.offset <= current_offset <= block.offset + sum(inst.size for inst in block.instructions): + if block.offset <= current_offset < block.offset + sum(self.instruction_sizes(block.instructions).values()): current_block = block break @@ -201,4 +212,4 @@ def example_function(x: int) -> int: print(tracker.get_coverage_report(example_function.__code__)) # Visualize the CFG -tracker.visualize_cfg(example_function.__code__, 'example_cfg') +tracker.visualize_cfg(example_function.__code__, 'example_cfg') \ No newline at end of file diff --git a/jac/jaclang/runtimelib/machine.py b/jac/jaclang/runtimelib/machine.py index dfdbb6431e..d887dc3dc1 100644 --- a/jac/jaclang/runtimelib/machine.py +++ b/jac/jaclang/runtimelib/machine.py @@ -344,16 +344,16 @@ def worker(self): print(self.cfgs) # genai.configure(api_key=os.getenv("GEN_AI_KEY")) # model = genai.GenerativeModel("gemini-1.5-flash") - # response_dict = {'cfg': self.cfgs} - # prompt = [] - # for k,v in response_dict.items(): - # prompt.append(f"here is my {k}:\n{v}") - # prompt.append("\nCan you identify where the code could have an error?") + response_dict = {'cfg': self.cfgs} + prompt = [] + for k,v in response_dict.items(): + prompt.append(f"here is my {k}:\n{v}") + prompt.append("\nCan you identify where the code could have an error?") # response = model.generate_content("".join(prompt)) - # print("PROMPT:\n") - # print("".join(prompt)) - # print("RESPONSE:\n") + print("PROMPT:\n") + print("".join(prompt)) + print("RESPONSE:\n") # print(response.text) - # print(self.cfgs['hot_path'].display_instructions()) \ No newline at end of file + print(self.cfgs['hot_path'].display_instructions()) \ No newline at end of file From ee87a76de2c44a2d2bdfa56ebcd93d7f8446403e Mon Sep 17 00:00:00 2001 From: clin155 Date: Thu, 21 Nov 2024 10:50:49 -0500 Subject: [PATCH 34/84] Add variable tracking --- jac/.gitignore | 2 + jac/example.jac | 31 +++++++ jac/jaclang/runtimelib/importer.py | 58 +------------ jac/jaclang/runtimelib/machine.py | 133 ++++++++++++++++++++++++++++- 4 files changed, 168 insertions(+), 56 deletions(-) create mode 100644 jac/example.jac diff --git a/jac/.gitignore b/jac/.gitignore index eb22397c53..e8314c413b 100644 --- a/jac/.gitignore +++ b/jac/.gitignore @@ -55,3 +55,5 @@ out.txt # Jaclang session files *.session + +env/* \ No newline at end of file diff --git a/jac/example.jac b/jac/example.jac new file mode 100644 index 0000000000..9ba602876e --- /dev/null +++ b/jac/example.jac @@ -0,0 +1,31 @@ +# with entry { +# can foo() { +# x:int = 0; +# y:int = 3; +# z:int = x + y; + +# for i in range(z) { +# x = 4; +# y = y + x; +# } +# print(y); +# } +# print("hello"); +# foo(); +# } +with entry { + x:int = 0; + y:int = 3; + z:int = x + y; + + for i in range(1000000) { + x = 4 * i + y * (z); + if x % 2 { + y = y + x; + z = x + y; + } + } + z = x/0; + print(y); + print("hello"); +} diff --git a/jac/jaclang/runtimelib/importer.py b/jac/jaclang/runtimelib/importer.py index 6180d890d7..5ab2c87d43 100644 --- a/jac/jaclang/runtimelib/importer.py +++ b/jac/jaclang/runtimelib/importer.py @@ -63,56 +63,6 @@ def get_caller_dir(self) -> str: chomp_target = chomp_target[1:] return path.join(caller_dir, self.dir_path) -class CFGTracker: - def __init__(self): - self.count = 0 - def start_tracking(self): - """Start tracking branch coverage""" - sys.settrace(self.trace_callback) - def stop_tracking(self): - """Stop tracking branch coverage""" - sys.settrace(None) - - def trace_callback(self, frame: types.FrameType, event: str, arg: any) -> Optional[types.TraceFunction]: - """Trace function to track executed branches""" - if event != 'line': - return self.trace_callback - code = frame.f_code - print(f"{frame.f_lineno}") - # print(f"Function Name: {code.co_name}") - # print(f"Filename: {code.co_filename}") - # print(f"First Line Number: {code.co_firstlineno}") - # print(f"Argument Count: {code.co_argcount}") - # print(f"Constants: {code.co_consts}") - # print(f"Local Variables: {code.co_varnames}") - self.count += 1 - - # if event != 'line': - # return self.trace_callback - - # code = frame.f_code - # if code not in self.cfg_cache: - # self.build_cfg(code) - - # # Find current basic block - # blocks = self.cfg_cache[code] - # current_offset = frame.f_lasti - - # # Find the block containing this offset - # current_block = None - # for block in blocks.values(): - # if block.offset <= current_offset <= block.offset + sum(inst.size for inst in block.instructions): - # current_block = block - # break - - # if current_block: - # current_block.hits += 1 - # # Record taken branches - # for next_block in current_block.next: - # self.coverage_data[code].add( - # (current_block.offset, next_block.offset)) - - # return self.trace_callback class ImportReturn: """Import Return Object.""" @@ -401,14 +351,14 @@ def run_import( if JacMachine.get().gin: try: with sys_path_context(spec.caller_dir): - tracker = CFGTracker() - tracker.start_tracking() + JacMachine.get().gin.tracker.start_tracking() exec(codeobj, module.__dict__) - tracker.stop_tracking() - print(f"count={tracker.count}") + JacMachine.get().gin.tracker.stop_tracking() + JacMachine.get().gin.set_finished(None) except Exception as e: logger.error(e) logger.error(dump_traceback(e)) + JacMachine.get().gin.set_finished(e) raise e else: exec(codeobj, module.__dict__) diff --git a/jac/jaclang/runtimelib/machine.py b/jac/jaclang/runtimelib/machine.py index dfdbb6431e..8637513a12 100644 --- a/jac/jaclang/runtimelib/machine.py +++ b/jac/jaclang/runtimelib/machine.py @@ -5,12 +5,13 @@ import inspect import marshal import os +import copy import time import sys import tempfile import types import google.generativeai as genai -from threading import Thread +import threading from contextvars import ContextVar from typing import Optional, Union @@ -60,6 +61,7 @@ def attach_program(self, jac_program: "JacProgram") -> None: def attach_gin(self, jac_gin: "ShellGhost") -> None: """Attach a JacProgram to the machine.""" self.gin = jac_gin + def get_mod_bundle(self) -> Optional[Module]: """Retrieve the mod_bundle from the attached JacProgram.""" @@ -328,20 +330,147 @@ def get_bytecode( return None +class CFGTracker: + def __init__(self): + self.variable_values = {} + self.variable_values_lock = threading.Lock() + def start_tracking(self): + """Start tracking branch coverage""" + sys.settrace(self.trace_callback) + def stop_tracking(self): + """Stop tracking branch coverage""" + sys.settrace(None) + + def get_variable_values(self): + self.variable_values_lock.acquire() + cpy = copy.deepcopy(self.variable_values) + self.variable_values_lock.release() + + return cpy + + def trace_callback(self, frame: types.FrameType, event: str, arg: any) -> Optional[types.TraceFunction]: + """Trace function to track executed branches""" + if event != 'line': + return self.trace_callback + + code = frame.f_code + + if ".jac" not in code.co_filename: + return self.trace_callback + + self.variable_values_lock.acquire() + if code.co_name not in self.variable_values: + self.variable_values[code.co_name] = {} + # self.variable_values[code.co_name][frame.f_lineno] = {} + if '__annotations__' in frame.f_locals: + for var_name in frame.f_locals['__annotations__']: + self.variable_values[code.co_name][var_name] = frame.f_locals[var_name] + self.variable_values_lock.release() + # print(f"{frame.f_lineno}") + # print(f"Function Name: {code.co_name}") + # print(f"Filename: {code.co_filename}") + # print(f"First Line Number: {code.co_firstlineno}") + # print(f"Argument Count: {code.co_argcount}") + # print(f"Constants: {code.co_consts}") + # print(f"Local Variables: {code.co_varnames}") + + # if event != 'line': + # return self.trace_callback + + # code = frame.f_code + # if code not in self.cfg_cache: + # self.build_cfg(code) + + # # Find current basic block + # blocks = self.cfg_cache[code] + # current_offset = frame.f_lasti + + # # Find the block containing this offset + # current_block = None + # for block in blocks.values(): + # if block.offset <= current_offset <= block.offset + sum(inst.size for inst in block.instructions): + # current_block = block + # break + + # if current_block: + # current_block.hits += 1 + # # Record taken branches + # for next_block in current_block.next: + # self.coverage_data[code].add( + # (current_block.offset, next_block.offset)) + + return self.trace_callback + class ShellGhost: def __init__(self): self.cfgs = None + self.cfg_cv = threading.Condition() + self.tracker = CFGTracker() + + self.finished_exception_lock = threading.Lock() + self.exception = None + self.finished = False def set_cfgs(self,cfgs: any): + self.cfg_cv.acquire() self.cfgs = cfgs + self.cfg_cv.notify() + self.cfg_cv.release() def start_ghost(self): - self.__ghost_thread:Thread = Thread(target=self.worker) + self.__ghost_thread = threading.Thread(target=self.worker) self.__ghost_thread.start() + def set_finished(self, exception: Exception = None): + self.finished_exception_lock.acquire() + self.exception = exception + self.finished = True + self.finished_exception_lock.release() + def worker(self): #this is temporary while developing + + # get static cfgs + self.cfg_cv.acquire() + while (self.cfgs == None): + self.cfg_cv.wait() print(self.cfgs) + for module_name, cfg in self.cfgs.items(): + print(f"Name: {module_name}", cfg.display_instructions()) + self.cfg_cv.release() + + self.finished_exception_lock.acquire() + while (not self.finished): + print("Getting Current Variable Values") + curr_variables = self.tracker.get_variable_values() + if len(curr_variables.keys()) == 0: + print("no variables yet") + for func_name, dic in curr_variables.items(): + print(func_name) + + for lin_no ,v in dic.items(): + print("line: ", lin_no) + print(v) + + # check the variable values ever 3 seconds + self.finished_exception_lock.release() + time.sleep(0.5) + self.finished_exception_lock.acquire() + + self.finished_exception_lock.release() + print("Getting Current Variable Values") + for func_name, dic in self.tracker.get_variable_values().items(): + print("name:", func_name) + + for lin_no ,v in dic.items(): + print("line: ", lin_no) + print(v) + # there should be no other thread trying to access finished/exception + + if self.exception: + print("Exception occured:", self.exception) + + # genai.configure(api_key=os.getenv("GEN_AI_KEY")) # model = genai.GenerativeModel("gemini-1.5-flash") # response_dict = {'cfg': self.cfgs} From e3307fc69d0ddc02af945509cd92502f39366e94 Mon Sep 17 00:00:00 2001 From: clin155 Date: Thu, 21 Nov 2024 11:32:37 -0500 Subject: [PATCH 35/84] Added cfg support for loops --- jac/example.jac | 41 ++++++++++++++++------------------- jac/jaclang/runtimelib/cfg.py | 20 +++++++++++++++-- 2 files changed, 37 insertions(+), 24 deletions(-) diff --git a/jac/example.jac b/jac/example.jac index 9ba602876e..d46972d309 100644 --- a/jac/example.jac +++ b/jac/example.jac @@ -1,31 +1,28 @@ -# with entry { -# can foo() { -# x:int = 0; -# y:int = 3; -# z:int = x + y; - -# for i in range(z) { -# x = 4; -# y = y + x; -# } -# print(y); -# } -# print("hello"); -# foo(); -# } with entry { x:int = 0; y:int = 3; z:int = x + y; - for i in range(1000000) { - x = 4 * i + y * (z); - if x % 2 { - y = y + x; - z = x + y; - } + for i in range(z) { + x = 4; + y = y + x; } - z = x/0; print(y); print("hello"); } +# with entry { +# x:int = 0; +# y:int = 3; +# z:int = x + y; +# i = 0; +# while (i < 1000000) { +# x = 4 * i + y * (z); +# if x % 2 { +# y = y + x; +# z = x + y; +# } +# } +# z = x/0; +# print(y); +# print("hello"); +# } diff --git a/jac/jaclang/runtimelib/cfg.py b/jac/jaclang/runtimelib/cfg.py index 1578102142..f3a06f8ed8 100644 --- a/jac/jaclang/runtimelib/cfg.py +++ b/jac/jaclang/runtimelib/cfg.py @@ -107,8 +107,9 @@ def valid_offset(offset): return offset >= 0 and offset <= max_offset # Identify all block starts for instr in instructions: - if instr.is_branch(): + if instr.is_branch() or instr.op == "FOR_ITER": next_instr_offset = instr.get_next_instruction_offset() + if 0 <= next_instr_offset <= max_offset: block_starts.add(next_instr_offset) @@ -200,11 +201,26 @@ def create_cfg(block_map: BlockMap) -> CFG: # Handle unconditional jumps (e.g., JUMP_FORWARD, JUMP_ABSOLUTE) elif last_instr.op.startswith("JUMP"): - target_offset = last_instr.argval if not last_instr.is_relative_branch() else (last_instr.offset + last_instr.argval) + if last_instr.op == "JUMP_BACKWARD": + target_offset = last_instr.argval if not last_instr.is_relative_branch() else (last_instr.offset - last_instr.argval) + else: + target_offset = last_instr.argval if not last_instr.is_relative_branch() else (last_instr.offset + last_instr.argval) target_block = find_block_by_offset(block_map, target_offset) if target_block is not None: cfg.add_edge(block_id, target_block) + elif last_instr.op == "FOR_ITER": + # Edge to loop body + loop_body_offset = last_instr.get_next_instruction_offset() + loop_body_block = find_block_by_offset(block_map, loop_body_offset) + if loop_body_block is not None: + cfg.add_edge(block_id, loop_body_block) + # Edge to END_FOR or loop exit + end_for_offset = last_instr.argval + end_for_block = find_block_by_offset(block_map, end_for_offset) + if end_for_block is not None: + cfg.add_edge(block_id, end_for_block) + # Handle fall-through to the next block for non-control flow instructions else: fall_through_offset = block.instructions[-1].get_next_instruction_offset() From f8baa22c3c510a19aa5510863e8b9554c6926e47 Mon Sep 17 00:00:00 2001 From: clin155 Date: Thu, 21 Nov 2024 16:35:34 -0500 Subject: [PATCH 36/84] add live variable tracking --- jac/example.jac | 7 +- jac/jaclang/runtimelib/cfg.py | 21 +++-- jac/jaclang/runtimelib/machine.py | 132 +++++++++++++++++++++--------- 3 files changed, 113 insertions(+), 47 deletions(-) diff --git a/jac/example.jac b/jac/example.jac index d46972d309..06b00b021e 100644 --- a/jac/example.jac +++ b/jac/example.jac @@ -3,9 +3,11 @@ with entry { y:int = 3; z:int = x + y; - for i in range(z) { + i:int = 0; + while (i < 3) { x = 4; y = y + x; + i += 1; } print(y); print("hello"); @@ -14,8 +16,7 @@ with entry { # x:int = 0; # y:int = 3; # z:int = x + y; -# i = 0; -# while (i < 1000000) { +# for i in range(100000) { # x = 4 * i + y * (z); # if x % 2 { # y = y + x; diff --git a/jac/jaclang/runtimelib/cfg.py b/jac/jaclang/runtimelib/cfg.py index f3a06f8ed8..908ecd605e 100644 --- a/jac/jaclang/runtimelib/cfg.py +++ b/jac/jaclang/runtimelib/cfg.py @@ -10,18 +10,19 @@ from graphviz import Digraph class BytecodeOp: - def __init__(self, op: int, arg: int, offset: int, argval:int, argrepr:str, is_jump_target: bool) -> None: + def __init__(self, op: int, arg: int, offset: int, argval:int, argrepr:str, is_jump_target: bool, starts_line: int = None) -> None: self.op = op self.arg = arg self.offset = offset self.argval = argval self.argrepr = argrepr self.is_jump_target= is_jump_target + self.starts_line = starts_line #default the offset self.__offset_size = 0 def __repr__(self): - return f"Instr: offset={self.offset}, Opname={self.op}, arg={self.arg}, argval={self.argval}, argrepr={self.argrepr}" + return f"Instr: offset={self.offset}, Opname={self.op}, arg={self.arg}, argval={self.argval}, argrepr={self.argrepr}, starts_line={self.starts_line}" def is_branch(self) -> bool: return self.op in { "JUMP_ABSOLUTE", @@ -55,6 +56,12 @@ class Block: def __init__(self, id: int, instructions: List): self.id: int = id self.instructions = instructions + self.exec_count = 0 + self.line_nos = set([instr.starts_line for instr in self.instructions if instr.starts_line != None]) + + print(id, self.line_nos) + + def __repr__(self): instructions = "\n".join([str(instr) for instr in self.instructions]) return f"bb{self.id}:\n{instructions}" @@ -85,6 +92,7 @@ def disassemble_bytecode(bytecode): argval=instr.argval, argrepr=instr.argrepr, is_jump_target=instr.is_jump_target, + starts_line=instr.starts_line, )) #set offest size for calculating next instruction #last instruction is default of 2, but shouldn't be needed @@ -152,6 +160,7 @@ class CFG: def __init__(self, block_map:BlockMap): self.nodes = set() self.edges = {} + self.edge_counts = {} self.block_map = block_map def add_node(self, node_id): @@ -163,7 +172,9 @@ def add_edge(self, from_node, to_node): if from_node in self.edges: self.edges[from_node].append(to_node) else: - self.edges[from_node] = [to_node] + self.edges[from_node] = to_node + + self.edge_counts[(from_node, to_node)] = 0 def display_instructions(self): return repr(self.block_map) @@ -171,10 +182,10 @@ def display_instructions(self): def __repr__(self): result = [] for node in self.nodes: - result.append(f'Node bb{node}:') + result.append(f'Node bb{node} (exec count={self.block_map.idx_to_block[node].exec_count}):') if node in self.edges and self.edges[node]: for succ in self.edges[node]: - result.append(f' -> bb{succ}') + result.append(f' -> bb{succ} (edge edec count={self.edge_counts[(node, succ)]})') return "\n".join(result) def create_cfg(block_map: BlockMap) -> CFG: cfg = CFG(block_map) diff --git a/jac/jaclang/runtimelib/machine.py b/jac/jaclang/runtimelib/machine.py index 8637513a12..74373fcd63 100644 --- a/jac/jaclang/runtimelib/machine.py +++ b/jac/jaclang/runtimelib/machine.py @@ -10,8 +10,10 @@ import sys import tempfile import types +import dis import google.generativeai as genai import threading +from collections import deque from contextvars import ContextVar from typing import Optional, Union @@ -332,21 +334,25 @@ def get_bytecode( class CFGTracker: def __init__(self): - self.variable_values = {} - self.variable_values_lock = threading.Lock() + self.executed_inst_list = deque() + self.inst_lock = threading.Lock() + def start_tracking(self): """Start tracking branch coverage""" sys.settrace(self.trace_callback) def stop_tracking(self): """Stop tracking branch coverage""" sys.settrace(None) - - def get_variable_values(self): - self.variable_values_lock.acquire() - cpy = copy.deepcopy(self.variable_values) - self.variable_values_lock.release() + + def get_exec_inst(self): + ret = [] + + self.inst_lock.acquire() + while len(self.executed_inst_list) > 0: + ret.append(self.executed_inst_list.popleft()) + self.inst_lock.release() - return cpy + return ret def trace_callback(self, frame: types.FrameType, event: str, arg: any) -> Optional[types.TraceFunction]: """Trace function to track executed branches""" @@ -357,15 +363,28 @@ def trace_callback(self, frame: types.FrameType, event: str, arg: any) -> Option if ".jac" not in code.co_filename: return self.trace_callback - - self.variable_values_lock.acquire() - if code.co_name not in self.variable_values: - self.variable_values[code.co_name] = {} - # self.variable_values[code.co_name][frame.f_lineno] = {} + + #edge case to handle executing code not within a function + filename = os.path.basename(code.co_filename) + module = code.co_name if code.co_name != "" else os.path.splitext(filename)[0] + + # bytecode = dis.Bytecode(code) + # for instr in bytecode: + # if instr.starts_line: + # print(f" Offset: {instr.offset}, Op: {instr.opname}, Line: {instr.starts_line}") + # pass + variable_dict = {} if '__annotations__' in frame.f_locals: for var_name in frame.f_locals['__annotations__']: - self.variable_values[code.co_name][var_name] = frame.f_locals[var_name] - self.variable_values_lock.release() + variable_dict[var_name] = frame.f_locals[var_name] + + self.inst_lock.acquire() + self.executed_inst_list.append((module, frame.f_lineno, variable_dict)) + self.inst_lock.release() + + # self.variable_values[code.co_name][frame.f_lineno] = {} + + # print(f"{frame.f_lineno}") # print(f"Function Name: {code.co_name}") # print(f"Filename: {code.co_filename}") @@ -411,7 +430,7 @@ def __init__(self): self.exception = None self.finished = False - def set_cfgs(self,cfgs: any): + def set_cfgs(self, cfgs): self.cfg_cv.acquire() self.cfgs = cfgs self.cfg_cv.notify() @@ -436,40 +455,75 @@ def worker(self): self.cfg_cv.wait() print(self.cfgs) for module_name, cfg in self.cfgs.items(): - print(f"Name: {module_name}", cfg.display_instructions()) + print(f"Name: {module_name}\n{cfg.display_instructions()}") self.cfg_cv.release() - self.finished_exception_lock.acquire() - while (not self.finished): - print("Getting Current Variable Values") - curr_variables = self.tracker.get_variable_values() - if len(curr_variables.keys()) == 0: - print("no variables yet") - for func_name, dic in curr_variables.items(): - print(func_name) + # Once cv has been notifie, self.cfgs is no longer accessed across threads + + current_executing_bb = [0] + + def update_cfg(): + exec_inst_list = self.tracker.get_exec_inst() + + for module, inst, variables in exec_inst_list: + cfg = self.cfgs[module] - for lin_no ,v in dic.items(): - print("line: ", lin_no) - print(v) + if inst not in cfg.block_map.idx_to_block[current_executing_bb[0]].line_nos: + for next in cfg.edges[current_executing_bb[0]]: + if inst in cfg.block_map.idx_to_block[next].line_nos: + cfg.edge_counts[(current_executing_bb[0], next)] += 1 + cfg.block_map.idx_to_block[next].exec_count += 1 + + current_executing_bb[0] = next + break + + print("current local variable values:" f"Inst #{inst}", variables) + + # assert(inst in cfg.block_map.idx_to_block[current_executing_bb[0]].line_nos) + # cfg.block_map.idx_to_block[current_executing_bb[0]].start_inst_variables_map[inst] = variables - # check the variable values ever 3 seconds + self.finished_exception_lock.acquire() + while (not self.finished): self.finished_exception_lock.release() - time.sleep(0.5) + + update_cfg() + + time.sleep(1) self.finished_exception_lock.acquire() + + update_cfg() + print(self.cfgs) + # for module_name, cfg in self.cfgs.items(): + # print(f"Name: {module_name}\n{cfg.display_instructions()}") - self.finished_exception_lock.release() - print("Getting Current Variable Values") - for func_name, dic in self.tracker.get_variable_values().items(): - print("name:", func_name) + + + # for func_name, dic in curr_variables.items(): + # print(func_name)module + + # for lin_no ,v in dic.items(): + # print("line: ", lin_no) + # print(v) + + # # check the variable values ever 3 seconds + # self.finished_exception_lock.release() + # time.sleep(0.5) + # self.finished_exception_lock.acquire() + + # self.finished_exception_lock.release() + # print("Getting Current Variable Values") + # for func_name, dic in self.tracker.get_variable_values().items(): + # print("name:", func_name) - for lin_no ,v in dic.items(): - print("line: ", lin_no) - print(v) - # there should be no other thread trying to access finished/exception + # for lin_no ,v in dic.items(): + # print("line: ", lin_no) + # print(v) + # # there should be no other thread trying to access finished/exception if self.exception: print("Exception occured:", self.exception) - + self.finished_exception_lock.release() + # genai.configure(api_key=os.getenv("GEN_AI_KEY")) # model = genai.GenerativeModel("gemini-1.5-flash") From 8ce63eb4cbef71f912b3737cef1595ce1ef77b3a Mon Sep 17 00:00:00 2001 From: clin155 Date: Thu, 21 Nov 2024 16:50:51 -0500 Subject: [PATCH 37/84] v --- jac/cfg.gv | 11 +++++++++++ jac/cfg.gv.pdf | Bin 0 -> 10188 bytes jac/example.jac | 5 ++--- jac/jaclang/runtimelib/cfg.py | 2 +- 4 files changed, 14 insertions(+), 4 deletions(-) create mode 100644 jac/cfg.gv create mode 100644 jac/cfg.gv.pdf diff --git a/jac/cfg.gv b/jac/cfg.gv new file mode 100644 index 0000000000..e77210720a --- /dev/null +++ b/jac/cfg.gv @@ -0,0 +1,11 @@ +// Control Flow Graph +digraph { + bb0 [label=BB0] + bb1 [label=BB1] + bb2 [label=BB2] + bb3 [label=BB3] + bb0 -> bb1 + bb1 -> bb2 + bb1 -> bb3 + bb2 -> bb1 +} diff --git a/jac/cfg.gv.pdf b/jac/cfg.gv.pdf new file mode 100644 index 0000000000000000000000000000000000000000..4b15c403042eafcf705f327daa16170acdf3be40 GIT binary patch literal 10188 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 literal 0 HcmV?d00001 diff --git a/jac/example.jac b/jac/example.jac index 06b00b021e..8c6348fde9 100644 --- a/jac/example.jac +++ b/jac/example.jac @@ -3,12 +3,11 @@ with entry { y:int = 3; z:int = x + y; - i:int = 0; - while (i < 3) { + for i in range(z) { x = 4; y = y + x; - i += 1; } + print(y/0); print(y); print("hello"); } diff --git a/jac/jaclang/runtimelib/cfg.py b/jac/jaclang/runtimelib/cfg.py index 908ecd605e..9735abc5cd 100644 --- a/jac/jaclang/runtimelib/cfg.py +++ b/jac/jaclang/runtimelib/cfg.py @@ -185,7 +185,7 @@ def __repr__(self): result.append(f'Node bb{node} (exec count={self.block_map.idx_to_block[node].exec_count}):') if node in self.edges and self.edges[node]: for succ in self.edges[node]: - result.append(f' -> bb{succ} (edge edec count={self.edge_counts[(node, succ)]})') + result.append(f' -> bb{succ} (edge exec count={self.edge_counts[(node, succ)]})') return "\n".join(result) def create_cfg(block_map: BlockMap) -> CFG: cfg = CFG(block_map) From 7aad35cf43a4848fdeddedd383a61540b603a0dd Mon Sep 17 00:00:00 2001 From: Jona Grodecki Date: Thu, 21 Nov 2024 19:07:53 -0500 Subject: [PATCH 38/84] fixed the line number variable for python 3.13 and added to LLM prompt --- jac/jaclang/runtimelib/cfg.py | 12 +++++++----- jac/jaclang/runtimelib/machine.py | 23 ++++++++++++++++------- 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/jac/jaclang/runtimelib/cfg.py b/jac/jaclang/runtimelib/cfg.py index 9735abc5cd..932bf7fcc8 100644 --- a/jac/jaclang/runtimelib/cfg.py +++ b/jac/jaclang/runtimelib/cfg.py @@ -10,19 +10,20 @@ from graphviz import Digraph class BytecodeOp: - def __init__(self, op: int, arg: int, offset: int, argval:int, argrepr:str, is_jump_target: bool, starts_line: int = None) -> None: + def __init__(self, op: int, arg: int, offset: int, argval:int, argrepr:str, is_jump_target: bool, line_number: int = None) -> None: self.op = op self.arg = arg self.offset = offset self.argval = argval self.argrepr = argrepr self.is_jump_target= is_jump_target - self.starts_line = starts_line + #self.starts_line = starts_line + self.line_number = line_number #default the offset self.__offset_size = 0 def __repr__(self): - return f"Instr: offset={self.offset}, Opname={self.op}, arg={self.arg}, argval={self.argval}, argrepr={self.argrepr}, starts_line={self.starts_line}" + return f"Instr: offset={self.offset}, Opname={self.op}, arg={self.arg}, argval={self.argval}, argrepr={self.argrepr}, line_number={self.line_number}" def is_branch(self) -> bool: return self.op in { "JUMP_ABSOLUTE", @@ -57,7 +58,7 @@ def __init__(self, id: int, instructions: List): self.id: int = id self.instructions = instructions self.exec_count = 0 - self.line_nos = set([instr.starts_line for instr in self.instructions if instr.starts_line != None]) + self.line_nos = set([instr.offset for instr in self.instructions if instr.offset != None]) print(id, self.line_nos) @@ -92,7 +93,8 @@ def disassemble_bytecode(bytecode): argval=instr.argval, argrepr=instr.argrepr, is_jump_target=instr.is_jump_target, - starts_line=instr.starts_line, + #starts_line=instr.starts_line, + line_number=instr.line_number, )) #set offest size for calculating next instruction #last instruction is default of 2, but shouldn't be needed diff --git a/jac/jaclang/runtimelib/machine.py b/jac/jaclang/runtimelib/machine.py index 74373fcd63..7314a3ad9c 100644 --- a/jac/jaclang/runtimelib/machine.py +++ b/jac/jaclang/runtimelib/machine.py @@ -456,7 +456,10 @@ def worker(self): print(self.cfgs) for module_name, cfg in self.cfgs.items(): print(f"Name: {module_name}\n{cfg.display_instructions()}") + pass self.cfg_cv.release() + + variables_by_line = [] # Once cv has been notifie, self.cfgs is no longer accessed across threads @@ -468,6 +471,10 @@ def update_cfg(): for module, inst, variables in exec_inst_list: cfg = self.cfgs[module] + + inst_line_no_list = [] + for instruction in cfg.block_map.idx_to_block[current_executing_bb[0]].instructions: + pass if inst not in cfg.block_map.idx_to_block[current_executing_bb[0]].line_nos: for next in cfg.edges[current_executing_bb[0]]: if inst in cfg.block_map.idx_to_block[next].line_nos: @@ -478,6 +485,8 @@ def update_cfg(): break print("current local variable values:" f"Inst #{inst}", variables) + variables_by_line.append((inst, variables)) + # assert(inst in cfg.block_map.idx_to_block[current_executing_bb[0]].line_nos) # cfg.block_map.idx_to_block[current_executing_bb[0]].start_inst_variables_map[inst] = variables @@ -519,19 +528,19 @@ def update_cfg(): # print("line: ", lin_no) # print(v) # # there should be no other thread trying to access finished/exception - + if self.exception: print("Exception occured:", self.exception) self.finished_exception_lock.release() - + # genai.configure(api_key=os.getenv("GEN_AI_KEY")) # model = genai.GenerativeModel("gemini-1.5-flash") - # response_dict = {'cfg': self.cfgs} - # prompt = [] - # for k,v in response_dict.items(): - # prompt.append(f"here is my {k}:\n{v}") - # prompt.append("\nCan you identify where the code could have an error?") + response_dict = {'cfg': self.cfgs, 'instructions': self.cfgs[module_name].display_instructions(), 'list of local variables at sequential line numbers': variables_by_line} + prompt = [] + for k,v in response_dict.items(): + prompt.append(f"here is my {k}:\n{v}") + prompt.append("\nCan you identify where the code could have an error?") # response = model.generate_content("".join(prompt)) # print("PROMPT:\n") From 294da36ecd8c24176b1a1c8ca0a027b5032826a0 Mon Sep 17 00:00:00 2001 From: Jakob Louis Therkelsen Date: Fri, 22 Nov 2024 09:22:25 -0500 Subject: [PATCH 39/84] clean up cfg file --- jac/jaclang/runtimelib/cfg.py | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/jac/jaclang/runtimelib/cfg.py b/jac/jaclang/runtimelib/cfg.py index 932bf7fcc8..aad2550ecd 100644 --- a/jac/jaclang/runtimelib/cfg.py +++ b/jac/jaclang/runtimelib/cfg.py @@ -93,7 +93,6 @@ def disassemble_bytecode(bytecode): argval=instr.argval, argrepr=instr.argrepr, is_jump_target=instr.is_jump_target, - #starts_line=instr.starts_line, line_number=instr.line_number, )) #set offest size for calculating next instruction @@ -249,17 +248,6 @@ def find_block_by_offset(block_map: BlockMap, offset: int) -> int: return block_id return None -# def disassemble_bytecode(bytecode): -# code_object = marshal.loads(bytecode) -# instructions = list(dis.get_instructions(code_object)) -# print(f"Disassembled bytecode for {code_object.co_name}:") -# print( -# "\n".join( -# [f"{instr.offset}: {instr.opname} {instr.argval}" for instr in instructions] -# ) -# ) -# return instructions - # Function to visualize CFG using Graphviz def visualize_cfg(cfg: CFG): dot = Digraph(comment="Control Flow Graph") From 807f114b2ae2cf3c766ad804c15d4d8a48c597d9 Mon Sep 17 00:00:00 2001 From: Jona Grodecki Date: Fri, 22 Nov 2024 10:54:39 -0500 Subject: [PATCH 40/84] small changes updating line nos to actually map to line numbers of program --- jac/examples/ginsScripts/hot_path.jac | 8 ++++---- jac/jaclang/runtimelib/cfg.py | 3 ++- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/jac/examples/ginsScripts/hot_path.jac b/jac/examples/ginsScripts/hot_path.jac index d09a7d9f6f..9105e6bcd0 100644 --- a/jac/examples/ginsScripts/hot_path.jac +++ b/jac/examples/ginsScripts/hot_path.jac @@ -1,14 +1,14 @@ with entry { - a = 0; - b = 0; - c = 0; + a:int = 0; + b:int = 0; + c:int = 0; while a < 15 { if a % 2 == 0{ c = a+b+7; } else { - b = 2; + b = 2 + c; } a += 1; } diff --git a/jac/jaclang/runtimelib/cfg.py b/jac/jaclang/runtimelib/cfg.py index aad2550ecd..fb10abc94c 100644 --- a/jac/jaclang/runtimelib/cfg.py +++ b/jac/jaclang/runtimelib/cfg.py @@ -58,7 +58,8 @@ def __init__(self, id: int, instructions: List): self.id: int = id self.instructions = instructions self.exec_count = 0 - self.line_nos = set([instr.offset for instr in self.instructions if instr.offset != None]) + # Potentially use offset instead + self.line_nos = set([instr.line_number for instr in self.instructions if instr.line_number != None]) print(id, self.line_nos) From 9d72e84c8234253ba3303e2c5ec39582b3af495b Mon Sep 17 00:00:00 2001 From: Jakob Louis Therkelsen Date: Fri, 22 Nov 2024 11:23:41 -0500 Subject: [PATCH 41/84] fix jump forward not connecting in BB --- jac/jaclang/runtimelib/cfg.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/jac/jaclang/runtimelib/cfg.py b/jac/jaclang/runtimelib/cfg.py index fb10abc94c..c862ab5810 100644 --- a/jac/jaclang/runtimelib/cfg.py +++ b/jac/jaclang/runtimelib/cfg.py @@ -35,8 +35,7 @@ def is_branch(self) -> bool: } def is_relative_branch(self) -> bool: return self.op in { - "FOR_ITER", - "JUMP_FORWARD", + "FOR_ITER" } def is_return(self) -> bool: return self.op == "RETURN_VALUE" From 909b72a02b369798efe9576d30306374c983db96 Mon Sep 17 00:00:00 2001 From: clin155 Date: Fri, 22 Nov 2024 17:39:02 -0500 Subject: [PATCH 42/84] moved to 3.13 --- jac/cfg.gv.pdf | Bin 10188 -> 10188 bytes jac/error | 10 + jac/example.jac | 9 +- jac/jaclang/runtimelib/cfg.py | 16 +- jac/jaclang/runtimelib/machine.py | 34 +- jac/out | 836 ++++++++++++++++++++++++++++++ jac/test.py | 28 + 7 files changed, 915 insertions(+), 18 deletions(-) create mode 100644 jac/error create mode 100644 jac/out create mode 100644 jac/test.py diff --git a/jac/cfg.gv.pdf b/jac/cfg.gv.pdf index 4b15c403042eafcf705f327daa16170acdf3be40..2ec4b958ddeb9649563528666a13eecfaacf32b1 100644 GIT binary patch delta 256 zcmV+b0ssEYPs~rSrX>p#buEkRVHK8A3bK>2B^!UZgMtzUSRla?vN9)C1?l^3l#sT( zmzDrP`l>n$AHaaZ89rxJ>uGR+rLRktj%hgDcgDTtG?B^!TOKu!q*%#q+8cKeK!C8Y1SQ9|1A zURnYG>8t82d;kLqEqu#lbzxx z{o`NbQvVqGD(Dt^a9(a9+w^CnrxD6BG@)NSX1bz_r-l!93|`{4;ummcl51CaRV}}j zknQ;tpwAq5E3KZ4kQR2E=fw{Sw?w!83jfxtxZ_{Czi;O+a9_@gegPudZqAcoArrH` GCJzD5vwK|t diff --git a/jac/error b/jac/error new file mode 100644 index 0000000000..606fdf3984 --- /dev/null +++ b/jac/error @@ -0,0 +1,10 @@ +ERROR - division by zero +ERROR - Error: division by zero + 13 | # i += 1; + 14 | } + 15 | print(y/0); + | ^^^ + 16 | print(y); + 17 | print("hello"); + at /Users/christopherlin/Desktop/Classes/jaseci-ginS/jac/example.jac:15 +division by zero diff --git a/jac/example.jac b/jac/example.jac index 8c6348fde9..57d65fcdbd 100644 --- a/jac/example.jac +++ b/jac/example.jac @@ -2,10 +2,15 @@ with entry { x:int = 0; y:int = 3; z:int = x + y; - - for i in range(z) { + # i:int = 0; + + for i in range(0) { + # if i % 2 { + # print("d"); + # } x = 4; y = y + x; + # i += 1; } print(y/0); print(y); diff --git a/jac/jaclang/runtimelib/cfg.py b/jac/jaclang/runtimelib/cfg.py index c862ab5810..6b26a0861d 100644 --- a/jac/jaclang/runtimelib/cfg.py +++ b/jac/jaclang/runtimelib/cfg.py @@ -10,20 +10,20 @@ from graphviz import Digraph class BytecodeOp: - def __init__(self, op: int, arg: int, offset: int, argval:int, argrepr:str, is_jump_target: bool, line_number: int = None) -> None: + def __init__(self, op: int, arg: int, offset: int, argval:int, argrepr:str, is_jump_target: bool, starts_line: int = None) -> None: self.op = op self.arg = arg self.offset = offset self.argval = argval self.argrepr = argrepr self.is_jump_target= is_jump_target - #self.starts_line = starts_line - self.line_number = line_number + self.starts_line = starts_line + # self.line_number = line_number #default the offset self.__offset_size = 0 def __repr__(self): - return f"Instr: offset={self.offset}, Opname={self.op}, arg={self.arg}, argval={self.argval}, argrepr={self.argrepr}, line_number={self.line_number}" + return f"Instr: offset={self.offset}, Opname={self.op}, arg={self.arg}, argval={self.argval}, argrepr={self.argrepr}, starts_line={self.starts_line}" def is_branch(self) -> bool: return self.op in { "JUMP_ABSOLUTE", @@ -34,9 +34,7 @@ def is_branch(self) -> bool: "JUMP_IF_FALSE_OR_POP", } def is_relative_branch(self) -> bool: - return self.op in { - "FOR_ITER" - } + return False def is_return(self) -> bool: return self.op == "RETURN_VALUE" @@ -58,7 +56,7 @@ def __init__(self, id: int, instructions: List): self.instructions = instructions self.exec_count = 0 # Potentially use offset instead - self.line_nos = set([instr.line_number for instr in self.instructions if instr.line_number != None]) + self.line_nos = set([instr.starts_line for instr in self.instructions if instr.starts_line != None]) print(id, self.line_nos) @@ -93,7 +91,7 @@ def disassemble_bytecode(bytecode): argval=instr.argval, argrepr=instr.argrepr, is_jump_target=instr.is_jump_target, - line_number=instr.line_number, + starts_line=instr.starts_line, )) #set offest size for calculating next instruction #last instruction is default of 2, but shouldn't be needed diff --git a/jac/jaclang/runtimelib/machine.py b/jac/jaclang/runtimelib/machine.py index 7314a3ad9c..1c18dd63fe 100644 --- a/jac/jaclang/runtimelib/machine.py +++ b/jac/jaclang/runtimelib/machine.py @@ -339,6 +339,8 @@ def __init__(self): def start_tracking(self): """Start tracking branch coverage""" + frame = sys._getframe() + frame.f_trace_opcodes = True sys.settrace(self.trace_callback) def stop_tracking(self): """Stop tracking branch coverage""" @@ -355,15 +357,33 @@ def get_exec_inst(self): return ret def trace_callback(self, frame: types.FrameType, event: str, arg: any) -> Optional[types.TraceFunction]: - """Trace function to track executed branches""" - if event != 'line': + # if event == "call": + frame.f_trace_opcodes = True + # frame.f_trace_lines = False + # def tracefunc(frame, event, arg): + # if event == 'call': + # frame.f_trace_opcodes = True + # elif event == 'opcode': + # if frame.f_code.co_code[frame.f_lasti] == dis.opmap['MAKE_FUNCTION']: + # makefunctiontracefunc(frame) + # return tracefunc + + """Trace function to track executed branches""" + + if ".jac" not in code.co_filename: return self.trace_callback + if event == 'opcode': + print(frame.f_lasti) + + if event != 'line': + return self.trace_callback code = frame.f_code - if ".jac" not in code.co_filename: - return self.trace_callback + + # print(frame.f_lineno, frame.f_lasti) + #edge case to handle executing code not within a function filename = os.path.basename(code.co_filename) module = code.co_name if code.co_name != "" else os.path.splitext(filename)[0] @@ -453,7 +473,7 @@ def worker(self): self.cfg_cv.acquire() while (self.cfgs == None): self.cfg_cv.wait() - print(self.cfgs) + # print(self.cfgs) for module_name, cfg in self.cfgs.items(): print(f"Name: {module_name}\n{cfg.display_instructions()}") pass @@ -484,7 +504,7 @@ def update_cfg(): current_executing_bb[0] = next break - print("current local variable values:" f"Inst #{inst}", variables) + # print("current local variable values:" f"Inst #{inst}", variables) variables_by_line.append((inst, variables)) @@ -501,7 +521,7 @@ def update_cfg(): self.finished_exception_lock.acquire() update_cfg() - print(self.cfgs) + # print(self.cfgs) # for module_name, cfg in self.cfgs.items(): # print(f"Name: {module_name}\n{cfg.display_instructions()}") diff --git a/jac/out b/jac/out new file mode 100644 index 0000000000..7fb92e2f17 --- /dev/null +++ b/jac/out @@ -0,0 +1,836 @@ +0 {False, True} +1 {False} +2 {False, True} +3 {False, True} +Name: example +bb0: +Instr: offset=0, Opname=RESUME, arg=0, argval=0, argrepr=, starts_line=True +Instr: offset=2, Opname=SETUP_ANNOTATIONS, arg=None, argval=None, argrepr=, starts_line=True +Instr: offset=4, Opname=LOAD_CONST, arg=0, argval=0, argrepr=0, starts_line=False +Instr: offset=6, Opname=LOAD_CONST, arg=1, argval=('annotations',), argrepr=('annotations',), starts_line=False +Instr: offset=8, Opname=IMPORT_NAME, arg=0, argval=__future__, argrepr=__future__, starts_line=False +Instr: offset=10, Opname=IMPORT_FROM, arg=1, argval=annotations, argrepr=annotations, starts_line=False +Instr: offset=12, Opname=STORE_NAME, arg=1, argval=annotations, argrepr=annotations, starts_line=False +Instr: offset=14, Opname=POP_TOP, arg=None, argval=None, argrepr=, starts_line=False +Instr: offset=16, Opname=LOAD_CONST, arg=0, argval=0, argrepr=0, starts_line=True +Instr: offset=18, Opname=STORE_NAME, arg=2, argval=x, argrepr=x, starts_line=False +Instr: offset=20, Opname=LOAD_CONST, arg=2, argval=int, argrepr='int', starts_line=False +Instr: offset=22, Opname=LOAD_NAME, arg=3, argval=__annotations__, argrepr=__annotations__, starts_line=False +Instr: offset=24, Opname=LOAD_CONST, arg=3, argval=x, argrepr='x', starts_line=False +Instr: offset=26, Opname=STORE_SUBSCR, arg=None, argval=None, argrepr=, starts_line=False +Instr: offset=30, Opname=LOAD_CONST, arg=4, argval=3, argrepr=3, starts_line=True +Instr: offset=32, Opname=STORE_NAME, arg=4, argval=y, argrepr=y, starts_line=False +Instr: offset=34, Opname=LOAD_CONST, arg=2, argval=int, argrepr='int', starts_line=False +Instr: offset=36, Opname=LOAD_NAME, arg=3, argval=__annotations__, argrepr=__annotations__, starts_line=False +Instr: offset=38, Opname=LOAD_CONST, arg=5, argval=y, argrepr='y', starts_line=False +Instr: offset=40, Opname=STORE_SUBSCR, arg=None, argval=None, argrepr=, starts_line=False +Instr: offset=44, Opname=LOAD_NAME, arg=2, argval=x, argrepr=x, starts_line=True +Instr: offset=46, Opname=LOAD_NAME, arg=4, argval=y, argrepr=y, starts_line=False +Instr: offset=48, Opname=BINARY_OP, arg=0, argval=0, argrepr=+, starts_line=False +Instr: offset=52, Opname=STORE_NAME, arg=5, argval=z, argrepr=z, starts_line=False +Instr: offset=54, Opname=LOAD_CONST, arg=2, argval=int, argrepr='int', starts_line=False +Instr: offset=56, Opname=LOAD_NAME, arg=3, argval=__annotations__, argrepr=__annotations__, starts_line=False +Instr: offset=58, Opname=LOAD_CONST, arg=6, argval=z, argrepr='z', starts_line=False +Instr: offset=60, Opname=STORE_SUBSCR, arg=None, argval=None, argrepr=, starts_line=False +Instr: offset=64, Opname=LOAD_NAME, arg=6, argval=range, argrepr=range, starts_line=True +Instr: offset=66, Opname=PUSH_NULL, arg=None, argval=None, argrepr=, starts_line=False +Instr: offset=68, Opname=LOAD_CONST, arg=0, argval=0, argrepr=0, starts_line=False +Instr: offset=70, Opname=CALL, arg=1, argval=1, argrepr=, starts_line=False +Instr: offset=78, Opname=GET_ITER, arg=None, argval=None, argrepr=, starts_line=False +bb1: +Instr: offset=80, Opname=FOR_ITER, arg=10, argval=104, argrepr=to L2, starts_line=False +bb2: +Instr: offset=84, Opname=STORE_NAME, arg=7, argval=i, argrepr=i, starts_line=False +Instr: offset=86, Opname=LOAD_CONST, arg=7, argval=4, argrepr=4, starts_line=True +Instr: offset=88, Opname=STORE_NAME, arg=2, argval=x, argrepr=x, starts_line=False +Instr: offset=90, Opname=LOAD_NAME, arg=4, argval=y, argrepr=y, starts_line=True +Instr: offset=92, Opname=LOAD_NAME, arg=2, argval=x, argrepr=x, starts_line=False +Instr: offset=94, Opname=BINARY_OP, arg=0, argval=0, argrepr=+, starts_line=False +Instr: offset=98, Opname=STORE_NAME, arg=4, argval=y, argrepr=y, starts_line=False +Instr: offset=100, Opname=JUMP_BACKWARD, arg=12, argval=80, argrepr=to L1, starts_line=False +bb3: +Instr: offset=104, Opname=END_FOR, arg=None, argval=None, argrepr=, starts_line=True +Instr: offset=106, Opname=POP_TOP, arg=None, argval=None, argrepr=, starts_line=False +Instr: offset=108, Opname=LOAD_NAME, arg=8, argval=print, argrepr=print, starts_line=True +Instr: offset=110, Opname=PUSH_NULL, arg=None, argval=None, argrepr=, starts_line=False +Instr: offset=112, Opname=LOAD_NAME, arg=4, argval=y, argrepr=y, starts_line=False +Instr: offset=114, Opname=LOAD_CONST, arg=0, argval=0, argrepr=0, starts_line=False +Instr: offset=116, Opname=BINARY_OP, arg=11, argval=11, argrepr=/, starts_line=False +Instr: offset=120, Opname=CALL, arg=1, argval=1, argrepr=, starts_line=False +Instr: offset=128, Opname=POP_TOP, arg=None, argval=None, argrepr=, starts_line=False +Instr: offset=130, Opname=LOAD_NAME, arg=8, argval=print, argrepr=print, starts_line=True +Instr: offset=132, Opname=PUSH_NULL, arg=None, argval=None, argrepr=, starts_line=False +Instr: offset=134, Opname=LOAD_NAME, arg=4, argval=y, argrepr=y, starts_line=False +Instr: offset=136, Opname=CALL, arg=1, argval=1, argrepr=, starts_line=False +Instr: offset=144, Opname=POP_TOP, arg=None, argval=None, argrepr=, starts_line=False +Instr: offset=146, Opname=LOAD_NAME, arg=8, argval=print, argrepr=print, starts_line=True +Instr: offset=148, Opname=PUSH_NULL, arg=None, argval=None, argrepr=, starts_line=False +Instr: offset=150, Opname=LOAD_CONST, arg=8, argval=hello, argrepr='hello', starts_line=False +Instr: offset=152, Opname=CALL, arg=1, argval=1, argrepr=, starts_line=False +Instr: offset=160, Opname=POP_TOP, arg=None, argval=None, argrepr=, starts_line=False +Instr: offset=162, Opname=RETURN_CONST, arg=9, argval=None, argrepr=None, starts_line=False +2 +4 +6 +8 +10 +12 +14 +16 +18 +20 +22 +24 +26 +30 +32 +34 +36 +38 +40 +44 +46 +48 +52 +54 +56 +58 +60 +64 +66 +68 +70 +78 +80 +108 +110 +112 +114 +116 +2 +4 +76 +78 +96 +98 +100 +120 +140 +142 +210 +212 +214 +222 +226 +236 +256 +276 +278 +286 +288 +292 +294 +296 +298 +300 +270 +272 +282 +284 +314 +324 +326 +466 +476 +478 +482 +484 +486 +488 +494 +496 +506 +508 +510 +512 +514 +2 +4 +24 +34 +2 +4 +24 +32 +38 +40 +42 +62 +64 +70 +72 +82 +84 +88 +90 +100 +102 +104 +106 +126 +2 +4 +24 +146 +148 +152 +190 +192 +212 +2 +4 +6 +8 +16 +20 +22 +42 +50 +78 +80 +100 +102 +104 +112 +116 +20 +22 +42 +50 +54 +56 +76 +220 +224 +226 +228 +248 +250 +254 +256 +258 +260 +268 +270 +306 +308 +310 +312 +42 +50 +54 +56 +76 +78 +88 +90 +92 +94 +96 +98 +2 +4 +6 +16 +24 +28 +30 +32 +52 +54 +2 +12 +2 +12 +32 +34 +36 +44 +20 +22 +24 +30 +32 +34 +38 +42 +44 +64 +66 +68 +74 +76 +78 +88 +90 +2 +12 +32 +52 +54 +74 +94 +2 +12 +32 +34 +36 +44 +102 +104 +106 +116 +120 +122 +130 +168 +98 +106 +120 +122 +124 +128 +132 +42 +44 +64 +66 +68 +74 +76 +78 +88 +90 +2 +12 +32 +52 +54 +74 +94 +2 +12 +32 +34 +36 +44 +102 +104 +106 +116 +120 +122 +130 +168 +98 +106 +120 +122 +124 +128 +132 +42 +44 +64 +66 +68 +74 +76 +78 +88 +90 +2 +12 +32 +52 +54 +74 +94 +2 +12 +32 +34 +36 +44 +102 +104 +106 +116 +120 +122 +130 +134 +136 +138 +140 +144 +146 +154 +168 +98 +106 +110 +112 +114 +118 +120 +122 +124 +128 +136 +138 +158 +160 +162 +164 +166 +174 +372 +374 +394 +396 +416 +418 +438 +440 +442 +62 +66 +68 +70 +82 +84 +92 +270 +272 +292 +294 +314 +316 +318 +320 +322 +324 +2 +12 +14 +16 +18 +20 +22 +2 +12 +32 +34 +42 +44 +46 +56 +58 +68 +70 +78 +230 +232 +242 +252 +254 +2 +12 +32 +34 +42 +44 +46 +50 +52 +262 +264 +274 +276 +286 +288 +298 +300 +310 +330 +350 +352 +2 +12 +32 +34 +36 +44 +46 +56 +58 +2 +12 +14 +24 +32 +40 +46 +66 +68 +70 +90 +92 +100 +102 +106 +108 +110 +112 +114 +360 +362 +372 +382 +402 +422 +424 +444 +2 +12 +32 +34 +36 +44 +46 +56 +58 +68 +76 +84 +98 +100 +102 +104 +106 +116 +136 +138 +140 +142 +144 +2 +4 +24 +26 +34 +36 +38 +46 +106 +108 +128 +130 +138 +140 +142 +146 +150 +152 +154 +158 +160 +162 +166 +170 +172 +174 +176 +180 +182 +184 +188 +192 +194 +196 +198 +200 +202 +204 +206 +208 +152 +452 +454 +458 +460 +470 +472 +482 +484 +486 +496 +498 +508 +510 +520 +522 +532 +534 +536 +540 +542 +552 +554 +556 +560 +562 +566 +568 +572 +574 +584 +586 +606 +608 +612 +686 +688 +698 +702 +704 +708 +710 +720 +730 +738 +742 +752 +772 +774 +782 +784 +794 +804 +824 +826 +2 +4 +14 +24 +32 +36 +834 +2 +4 +24 +32 +50 +52 +72 +854 +856 +866 +896 +906 +914 +934 +936 +938 +948 +958 +978 +998 +1000 +1008 +1010 +1012 +1080 +1090 +1098 +1102 +1112 +1122 +1124 +1132 +1140 +1144 +1154 +1174 +1176 +1184 +1186 +1196 +1212 +1214 +1216 +1226 +1236 +1244 +1248 +1258 +1278 +1298 +1300 +1308 +1310 +1312 +1320 +1324 +1326 +1328 +1348 +1516 +1518 +1528 +1530 +1534 +1536 +1538 +30 +32 +34 +160 +162 +332 +334 +336 +356 +358 +2 +4 +24 +32 +38 +40 +60 +62 +2 +4 +24 +26 +194 +196 +70 +72 +74 +82 +88 +98 +100 +110 +118 +126 +130 +132 +134 +136 +156 +158 +2 +4 +6 +8 +10 +12 +20 +24 +26 +46 +48 +162 +164 +184 +192 +202 +204 +224 +226 +228 +236 +240 +24 +26 +46 +48 +52 +54 +56 +58 +62 +64 +66 +86 +88 +108 +112 +120 +122 +142 +144 +2 +4 +24 +26 +2 +4 +24 +26 +194 +196 +34 +36 +46 +48 +58 +66 +74 +78 +80 +82 +84 +92 +96 +98 +118 +120 +122 +124 +144 +146 +2 +4 +6 +26 +28 +2 +4 +24 +32 +36 +38 +58 +60 +74 +76 +96 +98 +2 +4 +24 +2 +12 +14 +34 +42 +44 +46 +66 +74 +106 \ No newline at end of file diff --git a/jac/test.py b/jac/test.py new file mode 100644 index 0000000000..d16c65fbaf --- /dev/null +++ b/jac/test.py @@ -0,0 +1,28 @@ +import sys +import time + +def g(): + a = 0 + for _ in range(100000): + a += 1 + return a + +def f(): + for _ in range(10): + g() + +events = 0 + +def trace(frame, event, arg): + frame.f_trace_opcodes = True + if event == 'opcode': + print(frame.) + return trace + + +sys.settrace(trace) +start = time.time() +f() +print(time.time() - start) +sys.settrace(None) +print(events) \ No newline at end of file From 7822e246c6930a64f472b081c17efb5b84e5934d Mon Sep 17 00:00:00 2001 From: clin155 Date: Fri, 22 Nov 2024 17:50:31 -0500 Subject: [PATCH 43/84] g --- jac/cfg.gv.pdf | Bin 10188 -> 10187 bytes jac/jaclang/runtimelib/machine.py | 7 +- jac/out | 897 +++--------------------------- 3 files changed, 69 insertions(+), 835 deletions(-) diff --git a/jac/cfg.gv.pdf b/jac/cfg.gv.pdf index 2ec4b958ddeb9649563528666a13eecfaacf32b1..807cb2eb9612a8e652845409a5f1774496a91492 100644 GIT binary patch delta 286 zcmV+(0pb44Ps>lRrX>rL)wL|LhgDcgDTtG?B^-Z;oDv3@Bf$c8MMlaJ()ZgaA#Hds zEdhY^Rdp6VfB}UTK4(fq#c$_C1qq|8+1Cij$Xut%Y69&=MxzQfdbf&%G<5dZp zXw%2>@{N()DLvHONr>tLqbx&Y42zs%{zUUfO5@e!FBUv_>oDJNBSVgmYzA+#Q~acV zd|X}XA46Yzx`iH`ms`j-{n_Yggt81x=ogQfuIS>a;e#E6m$p#buEkRVHK8A3bK>2B^-Z)f)WN;Ai)x{GAC69>HBSzkhZ*+ zmHfq#aF{1rqq|8+1Cij$Xut%Y69&=MxzX;^bf&%G<5dZp zXw%2>@{N()DLpjYNr;*~qbx^c49l#<;)xcIl*X&cUo3d=)?vQoMur?A*$m!fr}$C- z__$uwKZd?`bPGK=FSn3y`jgSq2vrrD&@Ub{UD3r;!v{MCFL7J(3pg{$wX40Vk>5(l z^XV9%&m8z!T0I#dEo7VL#SaR%M7RD5|JJLy<6pYJZ|5&?U(Snu0V3mW&XZvw6O+6q z4FNcl$|lV;?E#9ZU1nea0BceVPYPvjWOH Optional[types.TraceFunction]: - # if event == "call": - frame.f_trace_opcodes = True + if event == "call": + frame.f_trace_opcodes = True # frame.f_trace_lines = False # def tracefunc(frame, event, arg): # if event == 'call': @@ -369,7 +369,7 @@ def trace_callback(self, frame: types.FrameType, event: str, arg: any) -> Option # return tracefunc """Trace function to track executed branches""" - + code = frame.f_code if ".jac" not in code.co_filename: return self.trace_callback @@ -378,7 +378,6 @@ def trace_callback(self, frame: types.FrameType, event: str, arg: any) -> Option if event != 'line': return self.trace_callback - code = frame.f_code diff --git a/jac/out b/jac/out index 7fb92e2f17..8de678030e 100644 --- a/jac/out +++ b/jac/out @@ -1,836 +1,71 @@ -0 {False, True} -1 {False} -2 {False, True} -3 {False, True} +0 {0, 1, 2, 3, 4, 7} +1 set() +2 {11, 12} +3 {16, 17, 15, 7} Name: example bb0: -Instr: offset=0, Opname=RESUME, arg=0, argval=0, argrepr=, starts_line=True -Instr: offset=2, Opname=SETUP_ANNOTATIONS, arg=None, argval=None, argrepr=, starts_line=True -Instr: offset=4, Opname=LOAD_CONST, arg=0, argval=0, argrepr=0, starts_line=False -Instr: offset=6, Opname=LOAD_CONST, arg=1, argval=('annotations',), argrepr=('annotations',), starts_line=False -Instr: offset=8, Opname=IMPORT_NAME, arg=0, argval=__future__, argrepr=__future__, starts_line=False -Instr: offset=10, Opname=IMPORT_FROM, arg=1, argval=annotations, argrepr=annotations, starts_line=False -Instr: offset=12, Opname=STORE_NAME, arg=1, argval=annotations, argrepr=annotations, starts_line=False -Instr: offset=14, Opname=POP_TOP, arg=None, argval=None, argrepr=, starts_line=False -Instr: offset=16, Opname=LOAD_CONST, arg=0, argval=0, argrepr=0, starts_line=True -Instr: offset=18, Opname=STORE_NAME, arg=2, argval=x, argrepr=x, starts_line=False -Instr: offset=20, Opname=LOAD_CONST, arg=2, argval=int, argrepr='int', starts_line=False -Instr: offset=22, Opname=LOAD_NAME, arg=3, argval=__annotations__, argrepr=__annotations__, starts_line=False -Instr: offset=24, Opname=LOAD_CONST, arg=3, argval=x, argrepr='x', starts_line=False -Instr: offset=26, Opname=STORE_SUBSCR, arg=None, argval=None, argrepr=, starts_line=False -Instr: offset=30, Opname=LOAD_CONST, arg=4, argval=3, argrepr=3, starts_line=True -Instr: offset=32, Opname=STORE_NAME, arg=4, argval=y, argrepr=y, starts_line=False -Instr: offset=34, Opname=LOAD_CONST, arg=2, argval=int, argrepr='int', starts_line=False -Instr: offset=36, Opname=LOAD_NAME, arg=3, argval=__annotations__, argrepr=__annotations__, starts_line=False -Instr: offset=38, Opname=LOAD_CONST, arg=5, argval=y, argrepr='y', starts_line=False -Instr: offset=40, Opname=STORE_SUBSCR, arg=None, argval=None, argrepr=, starts_line=False -Instr: offset=44, Opname=LOAD_NAME, arg=2, argval=x, argrepr=x, starts_line=True -Instr: offset=46, Opname=LOAD_NAME, arg=4, argval=y, argrepr=y, starts_line=False -Instr: offset=48, Opname=BINARY_OP, arg=0, argval=0, argrepr=+, starts_line=False -Instr: offset=52, Opname=STORE_NAME, arg=5, argval=z, argrepr=z, starts_line=False -Instr: offset=54, Opname=LOAD_CONST, arg=2, argval=int, argrepr='int', starts_line=False -Instr: offset=56, Opname=LOAD_NAME, arg=3, argval=__annotations__, argrepr=__annotations__, starts_line=False -Instr: offset=58, Opname=LOAD_CONST, arg=6, argval=z, argrepr='z', starts_line=False -Instr: offset=60, Opname=STORE_SUBSCR, arg=None, argval=None, argrepr=, starts_line=False -Instr: offset=64, Opname=LOAD_NAME, arg=6, argval=range, argrepr=range, starts_line=True -Instr: offset=66, Opname=PUSH_NULL, arg=None, argval=None, argrepr=, starts_line=False -Instr: offset=68, Opname=LOAD_CONST, arg=0, argval=0, argrepr=0, starts_line=False -Instr: offset=70, Opname=CALL, arg=1, argval=1, argrepr=, starts_line=False -Instr: offset=78, Opname=GET_ITER, arg=None, argval=None, argrepr=, starts_line=False +Instr: offset=0, Opname=RESUME, arg=0, argval=0, argrepr=, starts_line=0 +Instr: offset=2, Opname=SETUP_ANNOTATIONS, arg=None, argval=None, argrepr=, starts_line=1 +Instr: offset=4, Opname=LOAD_CONST, arg=0, argval=0, argrepr=0, starts_line=None +Instr: offset=6, Opname=LOAD_CONST, arg=1, argval=('annotations',), argrepr=('annotations',), starts_line=None +Instr: offset=8, Opname=IMPORT_NAME, arg=0, argval=__future__, argrepr=__future__, starts_line=None +Instr: offset=10, Opname=IMPORT_FROM, arg=1, argval=annotations, argrepr=annotations, starts_line=None +Instr: offset=12, Opname=STORE_NAME, arg=1, argval=annotations, argrepr=annotations, starts_line=None +Instr: offset=14, Opname=POP_TOP, arg=None, argval=None, argrepr=, starts_line=None +Instr: offset=16, Opname=LOAD_CONST, arg=0, argval=0, argrepr=0, starts_line=2 +Instr: offset=18, Opname=STORE_NAME, arg=2, argval=x, argrepr=x, starts_line=None +Instr: offset=20, Opname=LOAD_CONST, arg=2, argval=int, argrepr='int', starts_line=None +Instr: offset=22, Opname=LOAD_NAME, arg=3, argval=__annotations__, argrepr=__annotations__, starts_line=None +Instr: offset=24, Opname=LOAD_CONST, arg=3, argval=x, argrepr='x', starts_line=None +Instr: offset=26, Opname=STORE_SUBSCR, arg=None, argval=None, argrepr=, starts_line=None +Instr: offset=30, Opname=LOAD_CONST, arg=4, argval=3, argrepr=3, starts_line=3 +Instr: offset=32, Opname=STORE_NAME, arg=4, argval=y, argrepr=y, starts_line=None +Instr: offset=34, Opname=LOAD_CONST, arg=2, argval=int, argrepr='int', starts_line=None +Instr: offset=36, Opname=LOAD_NAME, arg=3, argval=__annotations__, argrepr=__annotations__, starts_line=None +Instr: offset=38, Opname=LOAD_CONST, arg=5, argval=y, argrepr='y', starts_line=None +Instr: offset=40, Opname=STORE_SUBSCR, arg=None, argval=None, argrepr=, starts_line=None +Instr: offset=44, Opname=LOAD_NAME, arg=2, argval=x, argrepr=x, starts_line=4 +Instr: offset=46, Opname=LOAD_NAME, arg=4, argval=y, argrepr=y, starts_line=None +Instr: offset=48, Opname=BINARY_OP, arg=0, argval=0, argrepr=+, starts_line=None +Instr: offset=52, Opname=STORE_NAME, arg=5, argval=z, argrepr=z, starts_line=None +Instr: offset=54, Opname=LOAD_CONST, arg=2, argval=int, argrepr='int', starts_line=None +Instr: offset=56, Opname=LOAD_NAME, arg=3, argval=__annotations__, argrepr=__annotations__, starts_line=None +Instr: offset=58, Opname=LOAD_CONST, arg=6, argval=z, argrepr='z', starts_line=None +Instr: offset=60, Opname=STORE_SUBSCR, arg=None, argval=None, argrepr=, starts_line=None +Instr: offset=64, Opname=PUSH_NULL, arg=None, argval=None, argrepr=, starts_line=7 +Instr: offset=66, Opname=LOAD_NAME, arg=6, argval=range, argrepr=range, starts_line=None +Instr: offset=68, Opname=LOAD_CONST, arg=0, argval=0, argrepr=0, starts_line=None +Instr: offset=70, Opname=CALL, arg=1, argval=1, argrepr=, starts_line=None +Instr: offset=78, Opname=GET_ITER, arg=None, argval=None, argrepr=, starts_line=None bb1: -Instr: offset=80, Opname=FOR_ITER, arg=10, argval=104, argrepr=to L2, starts_line=False +Instr: offset=80, Opname=FOR_ITER, arg=9, argval=102, argrepr=to 102, starts_line=None bb2: -Instr: offset=84, Opname=STORE_NAME, arg=7, argval=i, argrepr=i, starts_line=False -Instr: offset=86, Opname=LOAD_CONST, arg=7, argval=4, argrepr=4, starts_line=True -Instr: offset=88, Opname=STORE_NAME, arg=2, argval=x, argrepr=x, starts_line=False -Instr: offset=90, Opname=LOAD_NAME, arg=4, argval=y, argrepr=y, starts_line=True -Instr: offset=92, Opname=LOAD_NAME, arg=2, argval=x, argrepr=x, starts_line=False -Instr: offset=94, Opname=BINARY_OP, arg=0, argval=0, argrepr=+, starts_line=False -Instr: offset=98, Opname=STORE_NAME, arg=4, argval=y, argrepr=y, starts_line=False -Instr: offset=100, Opname=JUMP_BACKWARD, arg=12, argval=80, argrepr=to L1, starts_line=False +Instr: offset=84, Opname=STORE_NAME, arg=7, argval=i, argrepr=i, starts_line=None +Instr: offset=86, Opname=LOAD_CONST, arg=7, argval=4, argrepr=4, starts_line=11 +Instr: offset=88, Opname=STORE_NAME, arg=2, argval=x, argrepr=x, starts_line=None +Instr: offset=90, Opname=LOAD_NAME, arg=4, argval=y, argrepr=y, starts_line=12 +Instr: offset=92, Opname=LOAD_NAME, arg=2, argval=x, argrepr=x, starts_line=None +Instr: offset=94, Opname=BINARY_OP, arg=0, argval=0, argrepr=+, starts_line=None +Instr: offset=98, Opname=STORE_NAME, arg=4, argval=y, argrepr=y, starts_line=None +Instr: offset=100, Opname=JUMP_BACKWARD, arg=11, argval=80, argrepr=to 80, starts_line=None bb3: -Instr: offset=104, Opname=END_FOR, arg=None, argval=None, argrepr=, starts_line=True -Instr: offset=106, Opname=POP_TOP, arg=None, argval=None, argrepr=, starts_line=False -Instr: offset=108, Opname=LOAD_NAME, arg=8, argval=print, argrepr=print, starts_line=True -Instr: offset=110, Opname=PUSH_NULL, arg=None, argval=None, argrepr=, starts_line=False -Instr: offset=112, Opname=LOAD_NAME, arg=4, argval=y, argrepr=y, starts_line=False -Instr: offset=114, Opname=LOAD_CONST, arg=0, argval=0, argrepr=0, starts_line=False -Instr: offset=116, Opname=BINARY_OP, arg=11, argval=11, argrepr=/, starts_line=False -Instr: offset=120, Opname=CALL, arg=1, argval=1, argrepr=, starts_line=False -Instr: offset=128, Opname=POP_TOP, arg=None, argval=None, argrepr=, starts_line=False -Instr: offset=130, Opname=LOAD_NAME, arg=8, argval=print, argrepr=print, starts_line=True -Instr: offset=132, Opname=PUSH_NULL, arg=None, argval=None, argrepr=, starts_line=False -Instr: offset=134, Opname=LOAD_NAME, arg=4, argval=y, argrepr=y, starts_line=False -Instr: offset=136, Opname=CALL, arg=1, argval=1, argrepr=, starts_line=False -Instr: offset=144, Opname=POP_TOP, arg=None, argval=None, argrepr=, starts_line=False -Instr: offset=146, Opname=LOAD_NAME, arg=8, argval=print, argrepr=print, starts_line=True -Instr: offset=148, Opname=PUSH_NULL, arg=None, argval=None, argrepr=, starts_line=False -Instr: offset=150, Opname=LOAD_CONST, arg=8, argval=hello, argrepr='hello', starts_line=False -Instr: offset=152, Opname=CALL, arg=1, argval=1, argrepr=, starts_line=False -Instr: offset=160, Opname=POP_TOP, arg=None, argval=None, argrepr=, starts_line=False -Instr: offset=162, Opname=RETURN_CONST, arg=9, argval=None, argrepr=None, starts_line=False -2 -4 -6 -8 -10 -12 -14 -16 -18 -20 -22 -24 -26 -30 -32 -34 -36 -38 -40 -44 -46 -48 -52 -54 -56 -58 -60 -64 -66 -68 -70 -78 -80 -108 -110 -112 -114 -116 -2 -4 -76 -78 -96 -98 -100 -120 -140 -142 -210 -212 -214 -222 -226 -236 -256 -276 -278 -286 -288 -292 -294 -296 -298 -300 -270 -272 -282 -284 -314 -324 -326 -466 -476 -478 -482 -484 -486 -488 -494 -496 -506 -508 -510 -512 -514 -2 -4 -24 -34 -2 -4 -24 -32 -38 -40 -42 -62 -64 -70 -72 -82 -84 -88 -90 -100 -102 -104 -106 -126 -2 -4 -24 -146 -148 -152 -190 -192 -212 -2 -4 -6 -8 -16 -20 -22 -42 -50 -78 -80 -100 -102 -104 -112 -116 -20 -22 -42 -50 -54 -56 -76 -220 -224 -226 -228 -248 -250 -254 -256 -258 -260 -268 -270 -306 -308 -310 -312 -42 -50 -54 -56 -76 -78 -88 -90 -92 -94 -96 -98 -2 -4 -6 -16 -24 -28 -30 -32 -52 -54 -2 -12 -2 -12 -32 -34 -36 -44 -20 -22 -24 -30 -32 -34 -38 -42 -44 -64 -66 -68 -74 -76 -78 -88 -90 -2 -12 -32 -52 -54 -74 -94 -2 -12 -32 -34 -36 -44 -102 -104 -106 -116 -120 -122 -130 -168 -98 -106 -120 -122 -124 -128 -132 -42 -44 -64 -66 -68 -74 -76 -78 -88 -90 -2 -12 -32 -52 -54 -74 -94 -2 -12 -32 -34 -36 -44 -102 -104 -106 -116 -120 -122 -130 -168 -98 -106 -120 -122 -124 -128 -132 -42 -44 -64 -66 -68 -74 -76 -78 -88 -90 -2 -12 -32 -52 -54 -74 -94 -2 -12 -32 -34 -36 -44 -102 -104 -106 -116 -120 -122 -130 -134 -136 -138 -140 -144 -146 -154 -168 -98 -106 -110 -112 -114 -118 -120 -122 -124 -128 -136 -138 -158 -160 -162 -164 -166 -174 -372 -374 -394 -396 -416 -418 -438 -440 -442 -62 -66 -68 -70 -82 -84 -92 -270 -272 -292 -294 -314 -316 -318 -320 -322 -324 -2 -12 -14 -16 -18 -20 -22 -2 -12 -32 -34 -42 -44 -46 -56 -58 -68 -70 -78 -230 -232 -242 -252 -254 -2 -12 -32 -34 -42 -44 -46 -50 -52 -262 -264 -274 -276 -286 -288 -298 -300 -310 -330 -350 -352 -2 -12 -32 -34 -36 -44 -46 -56 -58 -2 -12 -14 -24 -32 -40 -46 -66 -68 -70 -90 -92 -100 -102 -106 -108 -110 -112 -114 -360 -362 -372 -382 -402 -422 -424 -444 -2 -12 -32 -34 -36 -44 -46 -56 -58 -68 -76 -84 -98 -100 -102 -104 -106 -116 -136 -138 -140 -142 -144 -2 -4 -24 -26 -34 -36 -38 -46 -106 -108 -128 -130 -138 -140 -142 -146 -150 -152 -154 -158 -160 -162 -166 -170 -172 -174 -176 -180 -182 -184 -188 -192 -194 -196 -198 -200 -202 -204 -206 -208 -152 -452 -454 -458 -460 -470 -472 -482 -484 -486 -496 -498 -508 -510 -520 -522 -532 -534 -536 -540 -542 -552 -554 -556 -560 -562 -566 -568 -572 -574 -584 -586 -606 -608 -612 -686 -688 -698 -702 -704 -708 -710 -720 -730 -738 -742 -752 -772 -774 -782 -784 -794 -804 -824 -826 -2 -4 -14 -24 -32 -36 -834 -2 -4 -24 -32 -50 -52 -72 -854 -856 -866 -896 -906 -914 -934 -936 -938 -948 -958 -978 -998 -1000 -1008 -1010 -1012 -1080 -1090 -1098 -1102 -1112 -1122 -1124 -1132 -1140 -1144 -1154 -1174 -1176 -1184 -1186 -1196 -1212 -1214 -1216 -1226 -1236 -1244 -1248 -1258 -1278 -1298 -1300 -1308 -1310 -1312 -1320 -1324 -1326 -1328 -1348 -1516 -1518 -1528 -1530 -1534 -1536 -1538 -30 -32 -34 -160 -162 -332 -334 -336 -356 -358 -2 -4 -24 -32 -38 -40 -60 -62 -2 -4 -24 -26 -194 -196 -70 -72 -74 -82 -88 -98 -100 -110 -118 -126 -130 -132 -134 -136 -156 -158 -2 -4 -6 -8 -10 -12 -20 -24 -26 -46 -48 -162 -164 -184 -192 -202 -204 -224 -226 -228 -236 -240 -24 -26 -46 -48 -52 -54 -56 -58 -62 -64 -66 -86 -88 -108 -112 -120 -122 -142 -144 -2 -4 -24 -26 -2 -4 -24 -26 -194 -196 -34 -36 -46 -48 -58 -66 -74 -78 -80 -82 -84 -92 -96 -98 -118 -120 -122 -124 -144 -146 -2 -4 -6 -26 -28 -2 -4 -24 -32 -36 -38 -58 -60 -74 -76 -96 -98 -2 -4 -24 -2 -12 -14 -34 -42 -44 -46 -66 -74 -106 \ No newline at end of file +Instr: offset=102, Opname=END_FOR, arg=None, argval=None, argrepr=, starts_line=7 +Instr: offset=104, Opname=PUSH_NULL, arg=None, argval=None, argrepr=, starts_line=15 +Instr: offset=106, Opname=LOAD_NAME, arg=8, argval=print, argrepr=print, starts_line=None +Instr: offset=108, Opname=LOAD_NAME, arg=4, argval=y, argrepr=y, starts_line=None +Instr: offset=110, Opname=LOAD_CONST, arg=0, argval=0, argrepr=0, starts_line=None +Instr: offset=112, Opname=BINARY_OP, arg=11, argval=11, argrepr=/, starts_line=None +Instr: offset=116, Opname=CALL, arg=1, argval=1, argrepr=, starts_line=None +Instr: offset=124, Opname=POP_TOP, arg=None, argval=None, argrepr=, starts_line=None +Instr: offset=126, Opname=PUSH_NULL, arg=None, argval=None, argrepr=, starts_line=16 +Instr: offset=128, Opname=LOAD_NAME, arg=8, argval=print, argrepr=print, starts_line=None +Instr: offset=130, Opname=LOAD_NAME, arg=4, argval=y, argrepr=y, starts_line=None +Instr: offset=132, Opname=CALL, arg=1, argval=1, argrepr=, starts_line=None +Instr: offset=140, Opname=POP_TOP, arg=None, argval=None, argrepr=, starts_line=None +Instr: offset=142, Opname=PUSH_NULL, arg=None, argval=None, argrepr=, starts_line=17 +Instr: offset=144, Opname=LOAD_NAME, arg=8, argval=print, argrepr=print, starts_line=None +Instr: offset=146, Opname=LOAD_CONST, arg=8, argval=hello, argrepr='hello', starts_line=None +Instr: offset=148, Opname=CALL, arg=1, argval=1, argrepr=, starts_line=None +Instr: offset=156, Opname=POP_TOP, arg=None, argval=None, argrepr=, starts_line=None +Instr: offset=158, Opname=RETURN_CONST, arg=9, argval=None, argrepr=None, starts_line=None +Exception occured: division by zero From bf7d84b490cc2e7fd828d39b4f1e1fa3e570c70c Mon Sep 17 00:00:00 2001 From: clin155 Date: Fri, 22 Nov 2024 17:50:41 -0500 Subject: [PATCH 44/84] remove out --- jac/out | 71 --------------------------------------------------------- 1 file changed, 71 deletions(-) delete mode 100644 jac/out diff --git a/jac/out b/jac/out deleted file mode 100644 index 8de678030e..0000000000 --- a/jac/out +++ /dev/null @@ -1,71 +0,0 @@ -0 {0, 1, 2, 3, 4, 7} -1 set() -2 {11, 12} -3 {16, 17, 15, 7} -Name: example -bb0: -Instr: offset=0, Opname=RESUME, arg=0, argval=0, argrepr=, starts_line=0 -Instr: offset=2, Opname=SETUP_ANNOTATIONS, arg=None, argval=None, argrepr=, starts_line=1 -Instr: offset=4, Opname=LOAD_CONST, arg=0, argval=0, argrepr=0, starts_line=None -Instr: offset=6, Opname=LOAD_CONST, arg=1, argval=('annotations',), argrepr=('annotations',), starts_line=None -Instr: offset=8, Opname=IMPORT_NAME, arg=0, argval=__future__, argrepr=__future__, starts_line=None -Instr: offset=10, Opname=IMPORT_FROM, arg=1, argval=annotations, argrepr=annotations, starts_line=None -Instr: offset=12, Opname=STORE_NAME, arg=1, argval=annotations, argrepr=annotations, starts_line=None -Instr: offset=14, Opname=POP_TOP, arg=None, argval=None, argrepr=, starts_line=None -Instr: offset=16, Opname=LOAD_CONST, arg=0, argval=0, argrepr=0, starts_line=2 -Instr: offset=18, Opname=STORE_NAME, arg=2, argval=x, argrepr=x, starts_line=None -Instr: offset=20, Opname=LOAD_CONST, arg=2, argval=int, argrepr='int', starts_line=None -Instr: offset=22, Opname=LOAD_NAME, arg=3, argval=__annotations__, argrepr=__annotations__, starts_line=None -Instr: offset=24, Opname=LOAD_CONST, arg=3, argval=x, argrepr='x', starts_line=None -Instr: offset=26, Opname=STORE_SUBSCR, arg=None, argval=None, argrepr=, starts_line=None -Instr: offset=30, Opname=LOAD_CONST, arg=4, argval=3, argrepr=3, starts_line=3 -Instr: offset=32, Opname=STORE_NAME, arg=4, argval=y, argrepr=y, starts_line=None -Instr: offset=34, Opname=LOAD_CONST, arg=2, argval=int, argrepr='int', starts_line=None -Instr: offset=36, Opname=LOAD_NAME, arg=3, argval=__annotations__, argrepr=__annotations__, starts_line=None -Instr: offset=38, Opname=LOAD_CONST, arg=5, argval=y, argrepr='y', starts_line=None -Instr: offset=40, Opname=STORE_SUBSCR, arg=None, argval=None, argrepr=, starts_line=None -Instr: offset=44, Opname=LOAD_NAME, arg=2, argval=x, argrepr=x, starts_line=4 -Instr: offset=46, Opname=LOAD_NAME, arg=4, argval=y, argrepr=y, starts_line=None -Instr: offset=48, Opname=BINARY_OP, arg=0, argval=0, argrepr=+, starts_line=None -Instr: offset=52, Opname=STORE_NAME, arg=5, argval=z, argrepr=z, starts_line=None -Instr: offset=54, Opname=LOAD_CONST, arg=2, argval=int, argrepr='int', starts_line=None -Instr: offset=56, Opname=LOAD_NAME, arg=3, argval=__annotations__, argrepr=__annotations__, starts_line=None -Instr: offset=58, Opname=LOAD_CONST, arg=6, argval=z, argrepr='z', starts_line=None -Instr: offset=60, Opname=STORE_SUBSCR, arg=None, argval=None, argrepr=, starts_line=None -Instr: offset=64, Opname=PUSH_NULL, arg=None, argval=None, argrepr=, starts_line=7 -Instr: offset=66, Opname=LOAD_NAME, arg=6, argval=range, argrepr=range, starts_line=None -Instr: offset=68, Opname=LOAD_CONST, arg=0, argval=0, argrepr=0, starts_line=None -Instr: offset=70, Opname=CALL, arg=1, argval=1, argrepr=, starts_line=None -Instr: offset=78, Opname=GET_ITER, arg=None, argval=None, argrepr=, starts_line=None -bb1: -Instr: offset=80, Opname=FOR_ITER, arg=9, argval=102, argrepr=to 102, starts_line=None -bb2: -Instr: offset=84, Opname=STORE_NAME, arg=7, argval=i, argrepr=i, starts_line=None -Instr: offset=86, Opname=LOAD_CONST, arg=7, argval=4, argrepr=4, starts_line=11 -Instr: offset=88, Opname=STORE_NAME, arg=2, argval=x, argrepr=x, starts_line=None -Instr: offset=90, Opname=LOAD_NAME, arg=4, argval=y, argrepr=y, starts_line=12 -Instr: offset=92, Opname=LOAD_NAME, arg=2, argval=x, argrepr=x, starts_line=None -Instr: offset=94, Opname=BINARY_OP, arg=0, argval=0, argrepr=+, starts_line=None -Instr: offset=98, Opname=STORE_NAME, arg=4, argval=y, argrepr=y, starts_line=None -Instr: offset=100, Opname=JUMP_BACKWARD, arg=11, argval=80, argrepr=to 80, starts_line=None -bb3: -Instr: offset=102, Opname=END_FOR, arg=None, argval=None, argrepr=, starts_line=7 -Instr: offset=104, Opname=PUSH_NULL, arg=None, argval=None, argrepr=, starts_line=15 -Instr: offset=106, Opname=LOAD_NAME, arg=8, argval=print, argrepr=print, starts_line=None -Instr: offset=108, Opname=LOAD_NAME, arg=4, argval=y, argrepr=y, starts_line=None -Instr: offset=110, Opname=LOAD_CONST, arg=0, argval=0, argrepr=0, starts_line=None -Instr: offset=112, Opname=BINARY_OP, arg=11, argval=11, argrepr=/, starts_line=None -Instr: offset=116, Opname=CALL, arg=1, argval=1, argrepr=, starts_line=None -Instr: offset=124, Opname=POP_TOP, arg=None, argval=None, argrepr=, starts_line=None -Instr: offset=126, Opname=PUSH_NULL, arg=None, argval=None, argrepr=, starts_line=16 -Instr: offset=128, Opname=LOAD_NAME, arg=8, argval=print, argrepr=print, starts_line=None -Instr: offset=130, Opname=LOAD_NAME, arg=4, argval=y, argrepr=y, starts_line=None -Instr: offset=132, Opname=CALL, arg=1, argval=1, argrepr=, starts_line=None -Instr: offset=140, Opname=POP_TOP, arg=None, argval=None, argrepr=, starts_line=None -Instr: offset=142, Opname=PUSH_NULL, arg=None, argval=None, argrepr=, starts_line=17 -Instr: offset=144, Opname=LOAD_NAME, arg=8, argval=print, argrepr=print, starts_line=None -Instr: offset=146, Opname=LOAD_CONST, arg=8, argval=hello, argrepr='hello', starts_line=None -Instr: offset=148, Opname=CALL, arg=1, argval=1, argrepr=, starts_line=None -Instr: offset=156, Opname=POP_TOP, arg=None, argval=None, argrepr=, starts_line=None -Instr: offset=158, Opname=RETURN_CONST, arg=9, argval=None, argrepr=None, starts_line=None -Exception occured: division by zero From c3f59ff483fa954a56c831e83b8826e320865da5 Mon Sep 17 00:00:00 2001 From: clin155 Date: Fri, 22 Nov 2024 17:56:50 -0500 Subject: [PATCH 45/84] added offsets to BBs --- jac/cfg.gv.pdf | Bin 10187 -> 10188 bytes jac/jaclang/runtimelib/cfg.py | 10 ++-- jac/out | 108 ++++++++++++++++++++++++++++++++++ 3 files changed, 112 insertions(+), 6 deletions(-) create mode 100644 jac/out diff --git a/jac/cfg.gv.pdf b/jac/cfg.gv.pdf index 807cb2eb9612a8e652845409a5f1774496a91492..5d74969074dd9fc82c492c7f308145de278d7b5d 100644 GIT binary patch delta 351 zcmV-l0igcNPs~rSm?eKtYlJWm#qaqPb1BtBHOcy?EV74HSV}3#Zf~WB5Q7^iMv_>% z-@X%FEhWrhe!R(h!!V$P6_8WHf#r;_5_V-qstVHg+o&LIMXwwIfb>;&4nBYbg)@B4 zs5aB!fsw;uo@lMh;l*X&cUo3b)>oDI6t3r;DYzA+t)8c4;FfPT%8CF5J(1S<0 zgKX2EteHlrs?daf@tEm~E=a8y+!(y%ZN)F(?WESOMpdJ}wN&TRF+j{5_*pqKS*aZC zHqQ$VO20&Rc!d;y>(#=GFVo+*!wcM(L(wlMC~ne|VIdQfye16+IFrgI%{1)+im6>@ xU;qGXQVdTDWo~41baG{3Z3<;>WN%_>3UhQ}a&&ldWo8OFIWsv5B_%~qMhew{qe%b& delta 324 zcmV-K0lWUpPs>lRm?eKfYlJWmh41+lb1BtBHIvn~EV74HSV}2~+gs@&#NY;sktCMx zzi*1l9)I0)JLu3q#oMQe&^G8bK)#NW0Jb3Fc-*6*Cj*x5yZ?aSTqK{X2d%A@loR?e3 zHvQS?X@s&2P3RYonXc&Kso{eigO|9i_ywGq None: + def __init__(self, op: int, arg: int, offset: int, argval:int, argrepr:str, is_jump_target: bool) -> None: self.op = op self.arg = arg self.offset = offset self.argval = argval self.argrepr = argrepr self.is_jump_target= is_jump_target - self.starts_line = starts_line # self.line_number = line_number #default the offset self.__offset_size = 0 def __repr__(self): - return f"Instr: offset={self.offset}, Opname={self.op}, arg={self.arg}, argval={self.argval}, argrepr={self.argrepr}, starts_line={self.starts_line}" + return f"Instr: offset={self.offset}, Opname={self.op}, arg={self.arg}, argval={self.argval}, argrepr={self.argrepr}" def is_branch(self) -> bool: return self.op in { "JUMP_ABSOLUTE", @@ -56,9 +55,9 @@ def __init__(self, id: int, instructions: List): self.instructions = instructions self.exec_count = 0 # Potentially use offset instead - self.line_nos = set([instr.starts_line for instr in self.instructions if instr.starts_line != None]) + self.bytecode_offsets = set([instr.offset for instr in self.instructions if instr.offset != None]) - print(id, self.line_nos) + print(id, self.bytecode_offsets) def __repr__(self): @@ -91,7 +90,6 @@ def disassemble_bytecode(bytecode): argval=instr.argval, argrepr=instr.argrepr, is_jump_target=instr.is_jump_target, - starts_line=instr.starts_line, )) #set offest size for calculating next instruction #last instruction is default of 2, but shouldn't be needed diff --git a/jac/out b/jac/out new file mode 100644 index 0000000000..b836640c5d --- /dev/null +++ b/jac/out @@ -0,0 +1,108 @@ +0 {0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 30, 32, 34, 36, 38, 40, 44, 46, 48, 52, 54, 56, 58, 60, 64, 66, 68, 70, 78} +1 {80} +2 {98, 100, 84, 86, 88, 90, 92, 94} +3 {128, 130, 132, 140, 142, 144, 146, 148, 156, 158, 102, 104, 106, 108, 110, 112, 116, 124, 126} +Name: example +bb0: +Instr: offset=0, Opname=RESUME, arg=0, argval=0, argrepr= +Instr: offset=2, Opname=SETUP_ANNOTATIONS, arg=None, argval=None, argrepr= +Instr: offset=4, Opname=LOAD_CONST, arg=0, argval=0, argrepr=0 +Instr: offset=6, Opname=LOAD_CONST, arg=1, argval=('annotations',), argrepr=('annotations',) +Instr: offset=8, Opname=IMPORT_NAME, arg=0, argval=__future__, argrepr=__future__ +Instr: offset=10, Opname=IMPORT_FROM, arg=1, argval=annotations, argrepr=annotations +Instr: offset=12, Opname=STORE_NAME, arg=1, argval=annotations, argrepr=annotations +Instr: offset=14, Opname=POP_TOP, arg=None, argval=None, argrepr= +Instr: offset=16, Opname=LOAD_CONST, arg=0, argval=0, argrepr=0 +Instr: offset=18, Opname=STORE_NAME, arg=2, argval=x, argrepr=x +Instr: offset=20, Opname=LOAD_CONST, arg=2, argval=int, argrepr='int' +Instr: offset=22, Opname=LOAD_NAME, arg=3, argval=__annotations__, argrepr=__annotations__ +Instr: offset=24, Opname=LOAD_CONST, arg=3, argval=x, argrepr='x' +Instr: offset=26, Opname=STORE_SUBSCR, arg=None, argval=None, argrepr= +Instr: offset=30, Opname=LOAD_CONST, arg=4, argval=3, argrepr=3 +Instr: offset=32, Opname=STORE_NAME, arg=4, argval=y, argrepr=y +Instr: offset=34, Opname=LOAD_CONST, arg=2, argval=int, argrepr='int' +Instr: offset=36, Opname=LOAD_NAME, arg=3, argval=__annotations__, argrepr=__annotations__ +Instr: offset=38, Opname=LOAD_CONST, arg=5, argval=y, argrepr='y' +Instr: offset=40, Opname=STORE_SUBSCR, arg=None, argval=None, argrepr= +Instr: offset=44, Opname=LOAD_NAME, arg=2, argval=x, argrepr=x +Instr: offset=46, Opname=LOAD_NAME, arg=4, argval=y, argrepr=y +Instr: offset=48, Opname=BINARY_OP, arg=0, argval=0, argrepr=+ +Instr: offset=52, Opname=STORE_NAME, arg=5, argval=z, argrepr=z +Instr: offset=54, Opname=LOAD_CONST, arg=2, argval=int, argrepr='int' +Instr: offset=56, Opname=LOAD_NAME, arg=3, argval=__annotations__, argrepr=__annotations__ +Instr: offset=58, Opname=LOAD_CONST, arg=6, argval=z, argrepr='z' +Instr: offset=60, Opname=STORE_SUBSCR, arg=None, argval=None, argrepr= +Instr: offset=64, Opname=PUSH_NULL, arg=None, argval=None, argrepr= +Instr: offset=66, Opname=LOAD_NAME, arg=6, argval=range, argrepr=range +Instr: offset=68, Opname=LOAD_CONST, arg=0, argval=0, argrepr=0 +Instr: offset=70, Opname=CALL, arg=1, argval=1, argrepr= +Instr: offset=78, Opname=GET_ITER, arg=None, argval=None, argrepr= +bb1: +Instr: offset=80, Opname=FOR_ITER, arg=9, argval=102, argrepr=to 102 +bb2: +Instr: offset=84, Opname=STORE_NAME, arg=7, argval=i, argrepr=i +Instr: offset=86, Opname=LOAD_CONST, arg=7, argval=4, argrepr=4 +Instr: offset=88, Opname=STORE_NAME, arg=2, argval=x, argrepr=x +Instr: offset=90, Opname=LOAD_NAME, arg=4, argval=y, argrepr=y +Instr: offset=92, Opname=LOAD_NAME, arg=2, argval=x, argrepr=x +Instr: offset=94, Opname=BINARY_OP, arg=0, argval=0, argrepr=+ +Instr: offset=98, Opname=STORE_NAME, arg=4, argval=y, argrepr=y +Instr: offset=100, Opname=JUMP_BACKWARD, arg=11, argval=80, argrepr=to 80 +bb3: +Instr: offset=102, Opname=END_FOR, arg=None, argval=None, argrepr= +Instr: offset=104, Opname=PUSH_NULL, arg=None, argval=None, argrepr= +Instr: offset=106, Opname=LOAD_NAME, arg=8, argval=print, argrepr=print +Instr: offset=108, Opname=LOAD_NAME, arg=4, argval=y, argrepr=y +Instr: offset=110, Opname=LOAD_CONST, arg=0, argval=0, argrepr=0 +Instr: offset=112, Opname=BINARY_OP, arg=11, argval=11, argrepr=/ +Instr: offset=116, Opname=CALL, arg=1, argval=1, argrepr= +Instr: offset=124, Opname=POP_TOP, arg=None, argval=None, argrepr= +Instr: offset=126, Opname=PUSH_NULL, arg=None, argval=None, argrepr= +Instr: offset=128, Opname=LOAD_NAME, arg=8, argval=print, argrepr=print +Instr: offset=130, Opname=LOAD_NAME, arg=4, argval=y, argrepr=y +Instr: offset=132, Opname=CALL, arg=1, argval=1, argrepr= +Instr: offset=140, Opname=POP_TOP, arg=None, argval=None, argrepr= +Instr: offset=142, Opname=PUSH_NULL, arg=None, argval=None, argrepr= +Instr: offset=144, Opname=LOAD_NAME, arg=8, argval=print, argrepr=print +Instr: offset=146, Opname=LOAD_CONST, arg=8, argval=hello, argrepr='hello' +Instr: offset=148, Opname=CALL, arg=1, argval=1, argrepr= +Instr: offset=156, Opname=POP_TOP, arg=None, argval=None, argrepr= +Instr: offset=158, Opname=RETURN_CONST, arg=9, argval=None, argrepr=None +2 +4 +6 +8 +10 +12 +14 +16 +18 +20 +22 +24 +26 +30 +32 +34 +36 +38 +40 +44 +46 +48 +52 +54 +56 +58 +60 +64 +66 +68 +70 +78 +80 +104 +106 +108 +110 +112 From eb4ca17d28f04b6053243fb49f029bb1095b4902 Mon Sep 17 00:00:00 2001 From: clin155 Date: Fri, 22 Nov 2024 18:11:18 -0500 Subject: [PATCH 46/84] Dynamic Profiling on offsets --- jac/cfg.gv | 3 +- jac/cfg.gv.pdf | Bin 10188 -> 10308 bytes jac/example.jac | 6 +- jac/jaclang/runtimelib/machine.py | 73 ++++++++++---------- jac/out | 108 ------------------------------ 5 files changed, 42 insertions(+), 148 deletions(-) delete mode 100644 jac/out diff --git a/jac/cfg.gv b/jac/cfg.gv index e77210720a..91da2daeb3 100644 --- a/jac/cfg.gv +++ b/jac/cfg.gv @@ -4,8 +4,9 @@ digraph { bb1 [label=BB1] bb2 [label=BB2] bb3 [label=BB3] + bb0 -> bb3 bb0 -> bb1 - bb1 -> bb2 bb1 -> bb3 + bb1 -> bb2 bb2 -> bb1 } diff --git a/jac/cfg.gv.pdf b/jac/cfg.gv.pdf index 5d74969074dd9fc82c492c7f308145de278d7b5d..acade2ad2bb6f0bdd945585f7b44a8175f48268b 100644 GIT binary patch delta 8961 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 bY6^37VRCeMa%E-;F)%PSI0_{tMNdWw6YUCw delta 8812 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 diff --git a/jac/example.jac b/jac/example.jac index 57d65fcdbd..addc69248b 100644 --- a/jac/example.jac +++ b/jac/example.jac @@ -2,15 +2,15 @@ with entry { x:int = 0; y:int = 3; z:int = x + y; - # i:int = 0; + i:int = 0; - for i in range(0) { + while (i < 3) { # if i % 2 { # print("d"); # } x = 4; y = y + x; - # i += 1; + i += 1; } print(y/0); print(y); diff --git a/jac/jaclang/runtimelib/machine.py b/jac/jaclang/runtimelib/machine.py index 94cff4916d..b424024e24 100644 --- a/jac/jaclang/runtimelib/machine.py +++ b/jac/jaclang/runtimelib/machine.py @@ -373,33 +373,33 @@ def trace_callback(self, frame: types.FrameType, event: str, arg: any) -> Option if ".jac" not in code.co_filename: return self.trace_callback - if event == 'opcode': - print(frame.f_lasti) - if event != 'line': - return self.trace_callback - + # if event != 'line': + # return self.trace_callback + + if event == 'opcode': + print(frame.f_lasti) # print(frame.f_lineno, frame.f_lasti) #edge case to handle executing code not within a function - filename = os.path.basename(code.co_filename) - module = code.co_name if code.co_name != "" else os.path.splitext(filename)[0] + filename = os.path.basename(code.co_filename) + module = code.co_name if code.co_name != "" else os.path.splitext(filename)[0] - # bytecode = dis.Bytecode(code) - # for instr in bytecode: - # if instr.starts_line: - # print(f" Offset: {instr.offset}, Op: {instr.opname}, Line: {instr.starts_line}") - # pass - variable_dict = {} - if '__annotations__' in frame.f_locals: - for var_name in frame.f_locals['__annotations__']: - variable_dict[var_name] = frame.f_locals[var_name] + # bytecode = dis.Bytecode(code) + # for instr in bytecode: + # if instr.starts_line: + # print(f" Offset: {instr.offset}, Op: {instr.opname}, Line: {instr.starts_line}") + # pass + # variable_dict = {} + # if '__annotations__' in frame.f_locals: + # for var_name in frame.f_locals['__annotations__']: + # variable_dict[var_name] = frame.f_locals[var_name] - self.inst_lock.acquire() - self.executed_inst_list.append((module, frame.f_lineno, variable_dict)) - self.inst_lock.release() + self.inst_lock.acquire() + self.executed_inst_list.append((module, frame.f_lasti)) + self.inst_lock.release() # self.variable_values[code.co_name][frame.f_lineno] = {} @@ -466,8 +466,8 @@ def set_finished(self, exception: Exception = None): self.finished_exception_lock.release() def worker(self): - #this is temporary while developing - + + # get static cfgs self.cfg_cv.acquire() while (self.cfgs == None): @@ -475,39 +475,40 @@ def worker(self): # print(self.cfgs) for module_name, cfg in self.cfgs.items(): print(f"Name: {module_name}\n{cfg.display_instructions()}") - pass self.cfg_cv.release() variables_by_line = [] # Once cv has been notifie, self.cfgs is no longer accessed across threads - current_executing_bb = [0] + current_executing_bbs = {} + def update_cfg(): exec_inst_list = self.tracker.get_exec_inst() - for module, inst, variables in exec_inst_list: - cfg = self.cfgs[module] + for module, offset in exec_inst_list: + cfg = self.cfgs[module] - inst_line_no_list = [] - for instruction in cfg.block_map.idx_to_block[current_executing_bb[0]].instructions: - pass - if inst not in cfg.block_map.idx_to_block[current_executing_bb[0]].line_nos: - for next in cfg.edges[current_executing_bb[0]]: - if inst in cfg.block_map.idx_to_block[next].line_nos: - cfg.edge_counts[(current_executing_bb[0], next)] += 1 + if module not in current_executing_bbs: # this means start at bb0, set exec count for bb0 to 1 + current_executing_bbs[module] = 0 + cfg.block_map.idx_to_block[0].exec_count = 1 + + if offset not in cfg.block_map.idx_to_block[current_executing_bbs[module]].bytecode_offsets: + for next in cfg.edges[current_executing_bbs[module]]: + if offset in cfg.block_map.idx_to_block[next].bytecode_offsets: + cfg.edge_counts[(current_executing_bbs[module], next)] += 1 cfg.block_map.idx_to_block[next].exec_count += 1 - current_executing_bb[0] = next + current_executing_bbs[module] = next break # print("current local variable values:" f"Inst #{inst}", variables) - variables_by_line.append((inst, variables)) + # variables_by_line.append((inst, variables)) - # assert(inst in cfg.block_map.idx_to_block[current_executing_bb[0]].line_nos) + assert(offset in cfg.block_map.idx_to_block[current_executing_bbs[module]].bytecode_offsets) # cfg.block_map.idx_to_block[current_executing_bb[0]].start_inst_variables_map[inst] = variables self.finished_exception_lock.acquire() @@ -520,7 +521,7 @@ def update_cfg(): self.finished_exception_lock.acquire() update_cfg() - # print(self.cfgs) + print(self.cfgs) # for module_name, cfg in self.cfgs.items(): # print(f"Name: {module_name}\n{cfg.display_instructions()}") diff --git a/jac/out b/jac/out deleted file mode 100644 index b836640c5d..0000000000 --- a/jac/out +++ /dev/null @@ -1,108 +0,0 @@ -0 {0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 30, 32, 34, 36, 38, 40, 44, 46, 48, 52, 54, 56, 58, 60, 64, 66, 68, 70, 78} -1 {80} -2 {98, 100, 84, 86, 88, 90, 92, 94} -3 {128, 130, 132, 140, 142, 144, 146, 148, 156, 158, 102, 104, 106, 108, 110, 112, 116, 124, 126} -Name: example -bb0: -Instr: offset=0, Opname=RESUME, arg=0, argval=0, argrepr= -Instr: offset=2, Opname=SETUP_ANNOTATIONS, arg=None, argval=None, argrepr= -Instr: offset=4, Opname=LOAD_CONST, arg=0, argval=0, argrepr=0 -Instr: offset=6, Opname=LOAD_CONST, arg=1, argval=('annotations',), argrepr=('annotations',) -Instr: offset=8, Opname=IMPORT_NAME, arg=0, argval=__future__, argrepr=__future__ -Instr: offset=10, Opname=IMPORT_FROM, arg=1, argval=annotations, argrepr=annotations -Instr: offset=12, Opname=STORE_NAME, arg=1, argval=annotations, argrepr=annotations -Instr: offset=14, Opname=POP_TOP, arg=None, argval=None, argrepr= -Instr: offset=16, Opname=LOAD_CONST, arg=0, argval=0, argrepr=0 -Instr: offset=18, Opname=STORE_NAME, arg=2, argval=x, argrepr=x -Instr: offset=20, Opname=LOAD_CONST, arg=2, argval=int, argrepr='int' -Instr: offset=22, Opname=LOAD_NAME, arg=3, argval=__annotations__, argrepr=__annotations__ -Instr: offset=24, Opname=LOAD_CONST, arg=3, argval=x, argrepr='x' -Instr: offset=26, Opname=STORE_SUBSCR, arg=None, argval=None, argrepr= -Instr: offset=30, Opname=LOAD_CONST, arg=4, argval=3, argrepr=3 -Instr: offset=32, Opname=STORE_NAME, arg=4, argval=y, argrepr=y -Instr: offset=34, Opname=LOAD_CONST, arg=2, argval=int, argrepr='int' -Instr: offset=36, Opname=LOAD_NAME, arg=3, argval=__annotations__, argrepr=__annotations__ -Instr: offset=38, Opname=LOAD_CONST, arg=5, argval=y, argrepr='y' -Instr: offset=40, Opname=STORE_SUBSCR, arg=None, argval=None, argrepr= -Instr: offset=44, Opname=LOAD_NAME, arg=2, argval=x, argrepr=x -Instr: offset=46, Opname=LOAD_NAME, arg=4, argval=y, argrepr=y -Instr: offset=48, Opname=BINARY_OP, arg=0, argval=0, argrepr=+ -Instr: offset=52, Opname=STORE_NAME, arg=5, argval=z, argrepr=z -Instr: offset=54, Opname=LOAD_CONST, arg=2, argval=int, argrepr='int' -Instr: offset=56, Opname=LOAD_NAME, arg=3, argval=__annotations__, argrepr=__annotations__ -Instr: offset=58, Opname=LOAD_CONST, arg=6, argval=z, argrepr='z' -Instr: offset=60, Opname=STORE_SUBSCR, arg=None, argval=None, argrepr= -Instr: offset=64, Opname=PUSH_NULL, arg=None, argval=None, argrepr= -Instr: offset=66, Opname=LOAD_NAME, arg=6, argval=range, argrepr=range -Instr: offset=68, Opname=LOAD_CONST, arg=0, argval=0, argrepr=0 -Instr: offset=70, Opname=CALL, arg=1, argval=1, argrepr= -Instr: offset=78, Opname=GET_ITER, arg=None, argval=None, argrepr= -bb1: -Instr: offset=80, Opname=FOR_ITER, arg=9, argval=102, argrepr=to 102 -bb2: -Instr: offset=84, Opname=STORE_NAME, arg=7, argval=i, argrepr=i -Instr: offset=86, Opname=LOAD_CONST, arg=7, argval=4, argrepr=4 -Instr: offset=88, Opname=STORE_NAME, arg=2, argval=x, argrepr=x -Instr: offset=90, Opname=LOAD_NAME, arg=4, argval=y, argrepr=y -Instr: offset=92, Opname=LOAD_NAME, arg=2, argval=x, argrepr=x -Instr: offset=94, Opname=BINARY_OP, arg=0, argval=0, argrepr=+ -Instr: offset=98, Opname=STORE_NAME, arg=4, argval=y, argrepr=y -Instr: offset=100, Opname=JUMP_BACKWARD, arg=11, argval=80, argrepr=to 80 -bb3: -Instr: offset=102, Opname=END_FOR, arg=None, argval=None, argrepr= -Instr: offset=104, Opname=PUSH_NULL, arg=None, argval=None, argrepr= -Instr: offset=106, Opname=LOAD_NAME, arg=8, argval=print, argrepr=print -Instr: offset=108, Opname=LOAD_NAME, arg=4, argval=y, argrepr=y -Instr: offset=110, Opname=LOAD_CONST, arg=0, argval=0, argrepr=0 -Instr: offset=112, Opname=BINARY_OP, arg=11, argval=11, argrepr=/ -Instr: offset=116, Opname=CALL, arg=1, argval=1, argrepr= -Instr: offset=124, Opname=POP_TOP, arg=None, argval=None, argrepr= -Instr: offset=126, Opname=PUSH_NULL, arg=None, argval=None, argrepr= -Instr: offset=128, Opname=LOAD_NAME, arg=8, argval=print, argrepr=print -Instr: offset=130, Opname=LOAD_NAME, arg=4, argval=y, argrepr=y -Instr: offset=132, Opname=CALL, arg=1, argval=1, argrepr= -Instr: offset=140, Opname=POP_TOP, arg=None, argval=None, argrepr= -Instr: offset=142, Opname=PUSH_NULL, arg=None, argval=None, argrepr= -Instr: offset=144, Opname=LOAD_NAME, arg=8, argval=print, argrepr=print -Instr: offset=146, Opname=LOAD_CONST, arg=8, argval=hello, argrepr='hello' -Instr: offset=148, Opname=CALL, arg=1, argval=1, argrepr= -Instr: offset=156, Opname=POP_TOP, arg=None, argval=None, argrepr= -Instr: offset=158, Opname=RETURN_CONST, arg=9, argval=None, argrepr=None -2 -4 -6 -8 -10 -12 -14 -16 -18 -20 -22 -24 -26 -30 -32 -34 -36 -38 -40 -44 -46 -48 -52 -54 -56 -58 -60 -64 -66 -68 -70 -78 -80 -104 -106 -108 -110 -112 From 526f8b995490d4a6769bedcb06bec4da8230e63a Mon Sep 17 00:00:00 2001 From: clin155 Date: Fri, 22 Nov 2024 18:14:38 -0500 Subject: [PATCH 47/84] fix for exceptions --- jac/jaclang/runtimelib/machine.py | 30 +++--------------------------- 1 file changed, 3 insertions(+), 27 deletions(-) diff --git a/jac/jaclang/runtimelib/machine.py b/jac/jaclang/runtimelib/machine.py index b424024e24..e174c50f98 100644 --- a/jac/jaclang/runtimelib/machine.py +++ b/jac/jaclang/runtimelib/machine.py @@ -519,36 +519,12 @@ def update_cfg(): time.sleep(1) self.finished_exception_lock.acquire() - + + self.finished_exception_lock.release() update_cfg() print(self.cfgs) - # for module_name, cfg in self.cfgs.items(): - # print(f"Name: {module_name}\n{cfg.display_instructions()}") - - - - # for func_name, dic in curr_variables.items(): - # print(func_name)module - - # for lin_no ,v in dic.items(): - # print("line: ", lin_no) - # print(v) - - # # check the variable values ever 3 seconds - # self.finished_exception_lock.release() - # time.sleep(0.5) - # self.finished_exception_lock.acquire() - - # self.finished_exception_lock.release() - # print("Getting Current Variable Values") - # for func_name, dic in self.tracker.get_variable_values().items(): - # print("name:", func_name) - - # for lin_no ,v in dic.items(): - # print("line: ", lin_no) - # print(v) # # there should be no other thread trying to access finished/exception - + self.finished_exception_lock.acquire() if self.exception: print("Exception occured:", self.exception) self.finished_exception_lock.release() From 1356c20780a30a416c15f0a7a4a2fc49f58a3e0f Mon Sep 17 00:00:00 2001 From: clin155 Date: Sun, 24 Nov 2024 13:46:15 -0800 Subject: [PATCH 48/84] Add gemini prompting and variable values --- jac/example.jac | 50 +++++----- jac/jaclang/runtimelib/cfg.py | 4 +- jac/jaclang/runtimelib/machine.py | 159 +++++++++++++++++++----------- 3 files changed, 128 insertions(+), 85 deletions(-) diff --git a/jac/example.jac b/jac/example.jac index addc69248b..d657278edb 100644 --- a/jac/example.jac +++ b/jac/example.jac @@ -1,33 +1,33 @@ -with entry { - x:int = 0; - y:int = 3; - z:int = x + y; - i:int = 0; - - while (i < 3) { - # if i % 2 { - # print("d"); - # } - x = 4; - y = y + x; - i += 1; - } - print(y/0); - print(y); - print("hello"); -} # with entry { # x:int = 0; # y:int = 3; # z:int = x + y; -# for i in range(100000) { -# x = 4 * i + y * (z); -# if x % 2 { -# y = y + x; -# z = x + y; -# } +# i:int = 0; + +# while (i < 3) { +# # if i % 2 { +# # print("d"); +# # } +# x = 4; +# y = y + x; +# i += 1; # } -# z = x/0; +# print(y/0); # print(y); # print("hello"); # } +with entry { + x:int = 0; + y:int = 3; + z:int = x + y; + for i in range(100000) { + x = 4 * i + y * (z); + if x % 2 { + y = y + x; + z = x + y; + } + } + z = x/0; + print(y); + print("hello"); +} diff --git a/jac/jaclang/runtimelib/cfg.py b/jac/jaclang/runtimelib/cfg.py index 8aaca7ea7d..68ff2fde23 100644 --- a/jac/jaclang/runtimelib/cfg.py +++ b/jac/jaclang/runtimelib/cfg.py @@ -56,9 +56,7 @@ def __init__(self, id: int, instructions: List): self.exec_count = 0 # Potentially use offset instead self.bytecode_offsets = set([instr.offset for instr in self.instructions if instr.offset != None]) - - print(id, self.bytecode_offsets) - + def __repr__(self): instructions = "\n".join([str(instr) for instr in self.instructions]) diff --git a/jac/jaclang/runtimelib/machine.py b/jac/jaclang/runtimelib/machine.py index e174c50f98..503d82e33a 100644 --- a/jac/jaclang/runtimelib/machine.py +++ b/jac/jaclang/runtimelib/machine.py @@ -10,10 +10,11 @@ import sys import tempfile import types +import asyncio import dis import google.generativeai as genai import threading -from collections import deque +from collections import defaultdict from contextvars import ContextVar from typing import Optional, Union @@ -334,8 +335,11 @@ def get_bytecode( class CFGTracker: def __init__(self): - self.executed_inst_list = deque() + self.executed_insts = {} self.inst_lock = threading.Lock() + + self.curr_variables_lock = threading.Lock() + self.curr_variables = {} def start_tracking(self): """Start tracking branch coverage""" @@ -347,14 +351,21 @@ def stop_tracking(self): sys.settrace(None) def get_exec_inst(self): - ret = [] self.inst_lock.acquire() - while len(self.executed_inst_list) > 0: - ret.append(self.executed_inst_list.popleft()) + cpy = copy.deepcopy(self.executed_insts) + self.executed_insts = {} self.inst_lock.release() - return ret + return cpy + + def get_variable_values(self): + self.curr_variables_lock.acquire() + cpy = copy.deepcopy(self.curr_variables) + self.curr_variables_lock.release() + + return cpy + def trace_callback(self, frame: types.FrameType, event: str, arg: any) -> Optional[types.TraceFunction]: if event == "call": @@ -379,27 +390,26 @@ def trace_callback(self, frame: types.FrameType, event: str, arg: any) -> Option # return self.trace_callback if event == 'opcode': - print(frame.f_lasti) + # print(frame.f_lasti) # print(frame.f_lineno, frame.f_lasti) #edge case to handle executing code not within a function filename = os.path.basename(code.co_filename) module = code.co_name if code.co_name != "" else os.path.splitext(filename)[0] - - # bytecode = dis.Bytecode(code) - # for instr in bytecode: - # if instr.starts_line: - # print(f" Offset: {instr.offset}, Op: {instr.opname}, Line: {instr.starts_line}") - # pass - # variable_dict = {} - # if '__annotations__' in frame.f_locals: - # for var_name in frame.f_locals['__annotations__']: - # variable_dict[var_name] = frame.f_locals[var_name] self.inst_lock.acquire() - self.executed_inst_list.append((module, frame.f_lasti)) + if module not in self.executed_insts: + self.executed_insts[module] = [] + self.executed_insts[module].append(frame.f_lasti) self.inst_lock.release() + variable_dict = {} + if '__annotations__' in frame.f_locals: + self.curr_variables_lock.acquire() + for var_name in frame.f_locals['__annotations__']: + variable_dict[var_name] = frame.f_locals[var_name] + self.curr_variables[module] = (frame.f_lasti, variable_dict) + self.curr_variables_lock.release() # self.variable_values[code.co_name][frame.f_lineno] = {} @@ -448,6 +458,11 @@ def __init__(self): self.finished_exception_lock = threading.Lock() self.exception = None self.finished = False + self.variable_values = None + + genai.configure(api_key=os.getenv("GEN_AI_KEY")) + self.model = genai.GenerativeModel("gemini-1.5-flash") + def set_cfgs(self, cfgs): self.cfg_cv.acquire() @@ -465,19 +480,53 @@ def set_finished(self, exception: Exception = None): self.finished = True self.finished_exception_lock.release() + def prompt_llm(self): + prompt = """I have a program. +CFGS: +{cfgs}, +Instructions per basic block: +{instructions}""" + + cfg_string = "" + ins_string = "" + + for module, cfg in self.cfgs.items(): + cfg_string += f"Module: {module}\n{cfg}" + ins_string += f"Module: {module}\n{cfg.display_instructions()}" + + prompt = prompt.format(cfgs=cfg_string, instructions=ins_string) + + if self.variable_values != None: + prompt += "\nCurrent variable values at the specified bytecode offset:" + + for module, var_map in self.variable_values.items(): + prompt += f"\nModule {module}: Offset: {var_map[0]}, Variables: {str(var_map[1])}" + + self.finished_exception_lock.acquire() + + if self.exception: + prompt += f"\nException: {self.exception}" + + self.finished_exception_lock.release() + + prompt += "\nCan you identity optimizations or where the code has an error?" + + print(prompt) + + response = self.model.generate_content(prompt) + + print(response.text) + def worker(self): - # get static cfgs self.cfg_cv.acquire() while (self.cfgs == None): self.cfg_cv.wait() # print(self.cfgs) - for module_name, cfg in self.cfgs.items(): - print(f"Name: {module_name}\n{cfg.display_instructions()}") + # for module_name, cfg in self.cfgs.items(): + # print(f"Name: {module_name}\n{cfg.display_instructions()}") self.cfg_cv.release() - - variables_by_line = [] # Once cv has been notifie, self.cfgs is no longer accessed across threads @@ -485,9 +534,11 @@ def worker(self): current_executing_bbs = {} def update_cfg(): - exec_inst_list = self.tracker.get_exec_inst() + exec_insts = self.tracker.get_exec_inst() - for module, offset in exec_inst_list: + # don't prompt if there's nothing new + if exec_insts == {}: return + for module, offset_list in exec_insts.items(): cfg = self.cfgs[module] @@ -495,48 +546,42 @@ def update_cfg(): current_executing_bbs[module] = 0 cfg.block_map.idx_to_block[0].exec_count = 1 - if offset not in cfg.block_map.idx_to_block[current_executing_bbs[module]].bytecode_offsets: - for next in cfg.edges[current_executing_bbs[module]]: - if offset in cfg.block_map.idx_to_block[next].bytecode_offsets: - cfg.edge_counts[(current_executing_bbs[module], next)] += 1 - cfg.block_map.idx_to_block[next].exec_count += 1 - - current_executing_bbs[module] = next - break - - # print("current local variable values:" f"Inst #{inst}", variables) - # variables_by_line.append((inst, variables)) - - - assert(offset in cfg.block_map.idx_to_block[current_executing_bbs[module]].bytecode_offsets) - # cfg.block_map.idx_to_block[current_executing_bb[0]].start_inst_variables_map[inst] = variables + for offset in offset_list: + if offset not in cfg.block_map.idx_to_block[current_executing_bbs[module]].bytecode_offsets: + for next in cfg.edges[current_executing_bbs[module]]: + if offset in cfg.block_map.idx_to_block[next].bytecode_offsets: + cfg.edge_counts[(current_executing_bbs[module], next)] += 1 + cfg.block_map.idx_to_block[next].exec_count += 1 + + current_executing_bbs[module] = next + break + assert(offset in cfg.block_map.idx_to_block[current_executing_bbs[module]].bytecode_offsets) + + self.variable_values = self.tracker.get_variable_values() + self.prompt_llm() self.finished_exception_lock.acquire() while (not self.finished): self.finished_exception_lock.release() - - update_cfg() - time.sleep(1) + time.sleep(5) + update_cfg() self.finished_exception_lock.acquire() self.finished_exception_lock.release() - update_cfg() - print(self.cfgs) - # # there should be no other thread trying to access finished/exception - self.finished_exception_lock.acquire() - if self.exception: - print("Exception occured:", self.exception) - self.finished_exception_lock.release() + # print(self.cfgs) + # self.finished_exception_lock.acquire() + # if self.exception: + # print("Exception occured:", self.exception) + # self.finished_exception_lock.release() + update_cfg() - # genai.configure(api_key=os.getenv("GEN_AI_KEY")) - # model = genai.GenerativeModel("gemini-1.5-flash") - response_dict = {'cfg': self.cfgs, 'instructions': self.cfgs[module_name].display_instructions(), 'list of local variables at sequential line numbers': variables_by_line} - prompt = [] - for k,v in response_dict.items(): - prompt.append(f"here is my {k}:\n{v}") - prompt.append("\nCan you identify where the code could have an error?") + # response_dict = {'cfg': self.cfgs, 'instructions': self.cfgs[module_name].display_instructions(), 'list of local variables at sequential line numbers': variables_by_line} + # prompt = [] + # for k,v in response_dict.items(): + # prompt.append(f"here is my {k}:\n{v}") + # prompt.append("\nCan you identify where the code could have an error?") # response = model.generate_content("".join(prompt)) # print("PROMPT:\n") From e610a198a7552cb93fd5f79be51250c05eecdda1 Mon Sep 17 00:00:00 2001 From: jayanaka-98 Date: Mon, 25 Nov 2024 13:32:42 -0500 Subject: [PATCH 49/84] your commit message --- cfg.gv | 13 +- cfg.gv.pdf | Bin 11975 -> 4921 bytes jac/cfg.gv | 13 +- jac/cfg.gv.pdf | Bin 10308 -> 6648 bytes jac/jaclang/compiler/passes/cfg.py | 5 +- .../compiler/passes/main/cfg_gen_pass.py | 8 +- .../passes/main/cfg_gen_pass_class_based.py | 274 ------------------ jac/jaclang/runtimelib/gins/__init__.py | 1 + jac/jaclang/runtimelib/{ => gins}/cfg.py | 0 jac/jaclang/runtimelib/gins/tracer.py | 122 ++++++++ jac/jaclang/runtimelib/machine.py | 63 ++-- 11 files changed, 181 insertions(+), 318 deletions(-) delete mode 100644 jac/jaclang/compiler/passes/main/cfg_gen_pass_class_based.py create mode 100644 jac/jaclang/runtimelib/gins/__init__.py rename jac/jaclang/runtimelib/{ => gins}/cfg.py (100%) create mode 100644 jac/jaclang/runtimelib/gins/tracer.py diff --git a/cfg.gv b/cfg.gv index 0774a4c90f..76ab6f6c18 100644 --- a/cfg.gv +++ b/cfg.gv @@ -3,18 +3,7 @@ digraph { bb0 [label=BB0] bb1 [label=BB1] bb2 [label=BB2] - bb3 [label=BB3] - bb4 [label=BB4] - bb5 [label=BB5] - bb6 [label=BB6] - bb7 [label=BB7] - bb0 -> bb7 + bb0 -> bb2 bb0 -> bb1 - bb1 -> bb3 bb1 -> bb2 - bb3 -> bb4 - bb4 -> bb6 - bb4 -> bb5 - bb5 -> bb1 - bb6 -> bb7 } diff --git a/cfg.gv.pdf b/cfg.gv.pdf index e1f747ab44aefba9c2956f4e7d7f5b3f995e6529..c0df284829fe4c8e7795e77ab9bad23e149e7d76 100644 GIT binary patch literal 4921 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 bb3 + bb4 [label=BB4] + bb5 [label=BB5] + bb6 [label=BB6] + bb7 [label=BB7] + bb0 -> bb7 bb0 -> bb1 bb1 -> bb3 bb1 -> bb2 - bb2 -> bb1 + bb2 -> bb4 + bb3 -> bb4 + bb4 -> bb6 + bb4 -> bb5 + bb5 -> bb1 + bb6 -> bb7 } diff --git a/jac/cfg.gv.pdf b/jac/cfg.gv.pdf index acade2ad2bb6f0bdd945585f7b44a8175f48268b..7d43940e67e80cee1460eab71aeefb1633db62d7 100644 GIT binary patch literal 6648 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 M2Z)IooG}Fa56ezFRR910 literal 10308 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 Dict[int, CFGNode]: self.cfg_cache[code] = blocks return blocks - def trace_callback(self, frame: types.FrameType, event: str, arg: Any) -> Optional[types.TraceFunction]: + def trace_callback(self, frame: types.FrameType, event: str) -> Optional[types.TraceFunction]: """Trace function to track executed branches""" if event != 'line': return self.trace_callback diff --git a/jac/jaclang/compiler/passes/main/cfg_gen_pass.py b/jac/jaclang/compiler/passes/main/cfg_gen_pass.py index 44203c131e..b7ea50b22e 100644 --- a/jac/jaclang/compiler/passes/main/cfg_gen_pass.py +++ b/jac/jaclang/compiler/passes/main/cfg_gen_pass.py @@ -7,7 +7,7 @@ import jaclang.compiler.absyntree as ast from jaclang.compiler.passes import Pass -from jaclang.runtimelib.cfg import visualize_cfg, disassemble_bytecode, create_BBs, create_cfg +from jaclang.runtimelib.gins.cfg import visualize_cfg, disassemble_bytecode, create_BBs, create_cfg class CfgGenPass(Pass): """Control flow graph generation pass.""" @@ -37,9 +37,9 @@ def enter_module(self, node: ast.Module) -> None: BBs = create_BBs(instructions) cfg = create_cfg(BBs) module_cfgs[mod.name] = cfg - for cfg in module_cfgs.values(): - dot = visualize_cfg(cfg) - dot.render('cfg.gv', view=True) + # for cfg in module_cfgs.values(): + # dot = visualize_cfg(cfg) + # dot.render('cfg.gv', view=True) if JacMachine.get().gin: try: JacMachine.get().gin.set_cfgs(cfgs=module_cfgs) diff --git a/jac/jaclang/compiler/passes/main/cfg_gen_pass_class_based.py b/jac/jaclang/compiler/passes/main/cfg_gen_pass_class_based.py deleted file mode 100644 index 6a57ef1d74..0000000000 --- a/jac/jaclang/compiler/passes/main/cfg_gen_pass_class_based.py +++ /dev/null @@ -1,274 +0,0 @@ -"""Genrate a control flow graph from genarated bytecode. - -This pass generates a control flow graph from the bytecode generated by the previous pass. -""" - -import ast as ast3 -import marshal -import dis -from collections import defaultdict -import networkx as nx -import matplotlib.pyplot as plt -from typing import List, Optional, Iterator -import jaclang.compiler.absyntree as ast -from jaclang.compiler.passes import Pass - -CODEUNIT_SIZE = 2 -class CfgGenPass(Pass): - """Control flow graph generation pass.""" - - def before_pass(self) -> None: - """Before pass.""" - return super().before_pass() - - def enter_module(self, node: ast.Module) -> None: - """Sub objects. - - name: str, - doc: Token, - body: Optional['Elements'], - mod_path: str, - is_imported: bool, - sym_tab: Optional[SymbolTable], - """ - mods = [node] + self.get_all_sub_nodes(node, ast.Module) - module_cfgs = generate_module_cfg(mods) - # for module_name, cfg_graph in module_cfgs.items(): - # print(f"Control Flow Graph for {module_name}:") - # nx.draw(cfg_graph, with_labels=True) - # plt.title("Control Flow Graph") - # plt.show() - # plt.savefig(f"{module_name}_cfg.png") - -class BytecodeOp: - def __init__(self, index: int, op: int, arg: int) -> None: - self.idx = index - self.op = op - self.arg = arg - - def next_instr_idx(self) -> int: - return self.idx + 1 - def next_instr_offset(self) -> int: - return self.next_instr_idx() * CODEUNIT_SIZE - def __repr__(self): - return f"{self.idx}: f{self.op} - {self.arg}" - def is_branch(self) -> bool: - return self.op in { - #"FOR_ITER", - #"JUMP_ABSOLUTE", - "JUMP_FORWARD", - "POP_JUMP_IF_TRUE", - "POP_JUMP_IF_FALSE", - "JUMP_IF_TRUE_OR_POP", - "JUMP_IF_FALSE_OR_POP", - } - def is_relative_branch(self) -> bool: - return self.op in { - "FOR_ITER", - "JUMP_FORWARD", - } - def next_instr_idx(self) -> int: - return self.idx+1 - def next_instr_offset(self) -> int: - return self.next_instr_idx()*CODEUNIT_SIZE - - def jump_target(self) -> int: - if self.is_relative_branch(): - return self.next_instr_offset() + self.arg - return self.arg - def jump_target_idx(self) -> int: - return self.jump_target() // CODEUNIT_SIZE - - def is_return(self) -> bool: - return self.op == "RETURN_VALUE" - - def is_raise(self) -> bool: - return self.op == "RAISE_VARARGS" - -class BytecodeSlice: - """A slice of bytecode from [start, end).""" - - def __init__( - self, - bytecode: List[BytecodeOp], - start: Optional[int] = None, - end: Optional[int] = None, - ) -> None: - self.bytecode = bytecode - self.start: int = 0 if start is None else start - self.end: int = len(bytecode) if end is None else end - - def __repr__(self) -> str: - return f"" - def size(self) -> int: - return self.end - self.start - def __iter__(self) -> Iterator[BytecodeOp]: - return iter(self.bytecode[self.start : self.end]) - -class Block: - def __init__(self, id: int, bytecode: BytecodeSlice): - self.id: int = id - self.bytecode: BytecodeSlice = bytecode - -class BlockMap: - def __init__(self) -> None: - self.idx_to_block: Dict[int, Block] = {} - - def add_block(self, idx, block): - self.idx_to_block[idx] = block - - def __repr__(self) -> str: - result = [] - for block in self.idx_to_block.values(): - result.append(f"bb{block.id}:") - for instr in block.bytecode: - if instr.is_branch(): - target_idx = instr.jump_target_idx() - target = self.idx_to_block[target_idx] - result.append(f" {instr.op} bb{target.id}") - else: - result.append(f" {instr}") - return "\n".join(result) - def __str__(self) -> str: - return self.__repr__() - -def disassemble_bytecode(bytecode): - code_object = marshal.loads(bytecode) - instructions = [] - for i, instr in enumerate(dis.get_instructions(code_object)): - instructions.append(BytecodeOp(i,instr.opname, instr.arg)) - return instructions - -def create_BBs(instructions: BytecodeSlice) -> BlockMap: - block_starts = set([0]) - block_map = BlockMap() - num_instr = instructions.size() - for instr in instructions: - if instr.is_branch(): - block_starts.add(instr.next_instr_idx()) - block_starts.add(instr.jump_target_idx()) - elif instr.is_return(): - next_instr_idx = instr.next_instr_idx() - if next_instr_idx < num_instr: - block_starts.add(next_instr_idx) - elif instr.is_raise(): - block_starts.add(instr.next_instr_idx()) - - block_starts_ordered = list(sorted(block_starts)) - - block_count = len(block_starts) - - for i, start_idx in enumerate(block_starts_ordered): - print(i) - end_idx = block_starts_ordered[i + 1] if i + 1 < block_count else num_instr - print(f"{start_idx}:{end_idx}") - block_instrs = BytecodeSlice(instructions.bytecode, start_idx, end_idx) - block_map.add_block(start_idx, Block(i, block_instrs)) - return block_map - - - -def extract_cfg_from_instructions(instructions): - cfg = defaultdict(list) - current_block = [] - block_id = 0 - block_map = {} # Maps instruction offsets to blocks - edges = {} - - for instr in instructions: - current_block.append(instr) - if instr.opname in { - "JUMP_ABSOLUTE", - "JUMP_FORWARD", - "POP_JUMP_IF_TRUE", - "POP_JUMP_IF_FALSE", - "JUMP_IF_TRUE_OR_POP", - "JUMP_IF_FALSE_OR_POP", - }: - cfg[block_id] = current_block - block_map[instr.offset] = block_id - target = ( - instr.offset + instr.argval + 2 - if instr.opname == "JUMP_FORWARD" - else instr.argval - ) - edges[block_id] = target - block_id += 1 - - # Update edges to use block numbers instead of offsets - for block_id, target_offset in edges.items(): - if target_offset in block_map: - edges[block_id] = block_map[target_offset] - else: - print(f"Warning: Target offset {target_offset} not found in block_map") - return cfg, block_map, edges - - -def build_cfg_graph(cfg, block_map, edges): - graph = nx.DiGraph() - - for block_id, instructions in cfg.items(): - print(f"Block ID {block_id}:") - print( - "\n".join( - [ - f"{instr.offset}: {instr.opname} {instr.argval}" - for instr in instructions - ] - ) - ) - graph.add_node(block_id, instructions=instructions) - last_instruction = instructions[-1] if instructions else None - - # Verify last_instruction is valid and has 'opname' attribute - if last_instruction and hasattr(last_instruction, "opname"): - if ( - "JUMP" in last_instruction.opname - and last_instruction.argval in block_map - ): - target_block = block_map[last_instruction.offset] - graph.add_edge(block_id, target_block) - else: - print( - f"Warning: Block ID {block_id} does not have a valid jump target or last instruction" - ) - return graph - - -def generate_module_cfg(modules): - module_cfgs = {} - for mod in modules: - bytecode = mod.gen.py_bytecode - instructions = disassemble_bytecode(bytecode) - bytecode_slice = BytecodeSlice(instructions) - BBs = create_BBs(bytecode_slice) - #cfg, block_map, edges = extract_cfg_from_instructions(instructions) - #module_cfgs[mod.name] = build_cfg_graph(cfg, block_map, edges) - #return module_cfgs - - -# Compile the simple function `decisions` -source_code = """ -def f(x): - if x: - y = 1 - else: - y = 2 - return y -""" -compiled_code = compile(source_code, filename="", mode="exec") - -# Extract the code object of the `decisions` function -decisions_code = compiled_code.co_consts[0] # The first constant is the code object - -# Serialize the bytecode of the function -serialized_bytecode = marshal.dumps(decisions_code) - -# Disassemble the serialized bytecode -disassembled_instructions = disassemble_bytecode(serialized_bytecode) -bytecode_slice = BytecodeSlice(disassembled_instructions) -print(bytecode_slice) - -# Generate and print basic blocks -BBs = create_BBs(bytecode_slice) -print(BBs) diff --git a/jac/jaclang/runtimelib/gins/__init__.py b/jac/jaclang/runtimelib/gins/__init__.py new file mode 100644 index 0000000000..ab33b08fb8 --- /dev/null +++ b/jac/jaclang/runtimelib/gins/__init__.py @@ -0,0 +1 @@ +"""Core primitives for Jaseci for GINS feature.""" diff --git a/jac/jaclang/runtimelib/cfg.py b/jac/jaclang/runtimelib/gins/cfg.py similarity index 100% rename from jac/jaclang/runtimelib/cfg.py rename to jac/jaclang/runtimelib/gins/cfg.py diff --git a/jac/jaclang/runtimelib/gins/tracer.py b/jac/jaclang/runtimelib/gins/tracer.py new file mode 100644 index 0000000000..842a8720f3 --- /dev/null +++ b/jac/jaclang/runtimelib/gins/tracer.py @@ -0,0 +1,122 @@ +import types +from typing import Optional, Union +import threading +import sys +import copy +import os + +class CFGTracker: + def __init__(self): + self.executed_insts = {} + self.inst_lock = threading.Lock() + + self.curr_variables_lock = threading.Lock() + self.curr_variables = {} + + def start_tracking(self): + """Start tracking branch coverage""" + frame = sys._getframe() + frame.f_trace_opcodes = True + sys.settrace(self.trace_callback) + def stop_tracking(self): + """Stop tracking branch coverage""" + sys.settrace(None) + + def get_exec_inst(self): + + self.inst_lock.acquire() + cpy = copy.deepcopy(self.executed_insts) + self.executed_insts = {} + self.inst_lock.release() + + return cpy + + def get_variable_values(self): + self.curr_variables_lock.acquire() + cpy = copy.deepcopy(self.curr_variables) + self.curr_variables_lock.release() + + return cpy + + + def trace_callback(self, frame: types.FrameType, event: str, arg: any) -> Optional[types.TraceFunction]: + if event == "call": + frame.f_trace_opcodes = True + # frame.f_trace_lines = False + # def tracefunc(frame, event, arg): + # if event == 'call': + # frame.f_trace_opcodes = True + # elif event == 'opcode': + # if frame.f_code.co_code[frame.f_lasti] == dis.opmap['MAKE_FUNCTION']: + # makefunctiontracefunc(frame) + # return tracefunc + + """Trace function to track executed branches""" + code = frame.f_code + if ".jac" not in code.co_filename: + return self.trace_callback + + + + # if event != 'line': + # return self.trace_callback + + if event == 'opcode': + # print(frame.f_lasti) + + # print(frame.f_lineno, frame.f_lasti) + + #edge case to handle executing code not within a function + filename = os.path.basename(code.co_filename) + module = code.co_name if code.co_name != "" else os.path.splitext(filename)[0] + + self.inst_lock.acquire() + if module not in self.executed_insts: + self.executed_insts[module] = [] + self.executed_insts[module].append(frame.f_lasti) + self.inst_lock.release() + variable_dict = {} + if '__annotations__' in frame.f_locals: + self.curr_variables_lock.acquire() + for var_name in frame.f_locals['__annotations__']: + variable_dict[var_name] = frame.f_locals[var_name] + self.curr_variables[module] = (frame.f_lasti, variable_dict) + self.curr_variables_lock.release() + + # self.variable_values[code.co_name][frame.f_lineno] = {} + + + # print(f"{frame.f_lineno}") + # print(f"Function Name: {code.co_name}") + # print(f"Filename: {code.co_filename}") + # print(f"First Line Number: {code.co_firstlineno}") + # print(f"Argument Count: {code.co_argcount}") + # print(f"Constants: {code.co_consts}") + # print(f"Local Variables: {code.co_varnames}") + + # if event != 'line': + # return self.trace_callback + + # code = frame.f_code + # if code not in self.cfg_cache: + # self.build_cfg(code) + + # # Find current basic block + # blocks = self.cfg_cache[code] + # current_offset = frame.f_lasti + + # # Find the block containing this offset + # current_block = None + # for block in blocks.values(): + # if block.offset <= current_offset <= block.offset + sum(inst.size for inst in block.instructions): + # current_block = block + # break + + # if current_block: + # current_block.hits += 1 + # # Record taken branches + # for next_block in current_block.next: + # self.coverage_data[code].add( + # (current_block.offset, next_block.offset)) + + return self.trace_callback \ No newline at end of file diff --git a/jac/jaclang/runtimelib/machine.py b/jac/jaclang/runtimelib/machine.py index 503d82e33a..ec9af96e9e 100644 --- a/jac/jaclang/runtimelib/machine.py +++ b/jac/jaclang/runtimelib/machine.py @@ -97,6 +97,8 @@ def get_sem_ir(self, mod_sem_ir: SemRegistry | None) -> None: self.jac_program.sem_ir.registry.update(mod_sem_ir.registry) else: self.jac_program.sem_ir = mod_sem_ir + if self.gin and mod_sem_ir: + self.gin.sem_ir = mod_sem_ir def load_module(self, module_name: str, module: types.ModuleType) -> None: """Load a module into the machine.""" @@ -454,13 +456,14 @@ def __init__(self): self.cfgs = None self.cfg_cv = threading.Condition() self.tracker = CFGTracker() + self.sem_ir = None self.finished_exception_lock = threading.Lock() self.exception = None self.finished = False self.variable_values = None - genai.configure(api_key=os.getenv("GEN_AI_KEY")) + genai.configure(api_key=os.getenv("GEMINI_API_KEY")) self.model = genai.GenerativeModel("gemini-1.5-flash") @@ -480,21 +483,22 @@ def set_finished(self, exception: Exception = None): self.finished = True self.finished_exception_lock.release() - def prompt_llm(self): + def prompt_llm(self, verbose: bool = False): prompt = """I have a program. CFGS: {cfgs}, Instructions per basic block: -{instructions}""" +{instructions} +Semantic and Type information from source code: +{sem_ir}""" cfg_string = "" ins_string = "" - for module, cfg in self.cfgs.items(): cfg_string += f"Module: {module}\n{cfg}" ins_string += f"Module: {module}\n{cfg.display_instructions()}" - prompt = prompt.format(cfgs=cfg_string, instructions=ins_string) + prompt = prompt.format(cfgs=cfg_string, instructions=ins_string, sem_ir=self.sem_ir) if self.variable_values != None: prompt += "\nCurrent variable values at the specified bytecode offset:" @@ -509,9 +513,11 @@ def prompt_llm(self): self.finished_exception_lock.release() - prompt += "\nCan you identity optimizations or where the code has an error?" + prompt += "\nCan you identity bottlneck optimizations or where the code can error out?" + prompt += "\n(Reason about the program using bytecode, cfg, semantic and type information to infer the source code indirectly)" - print(prompt) + if verbose: + print(prompt) response = self.model.generate_content(prompt) @@ -539,33 +545,38 @@ def update_cfg(): # don't prompt if there's nothing new if exec_insts == {}: return for module, offset_list in exec_insts.items(): - - cfg = self.cfgs[module] - - if module not in current_executing_bbs: # this means start at bb0, set exec count for bb0 to 1 - current_executing_bbs[module] = 0 - cfg.block_map.idx_to_block[0].exec_count = 1 - - for offset in offset_list: - if offset not in cfg.block_map.idx_to_block[current_executing_bbs[module]].bytecode_offsets: - for next in cfg.edges[current_executing_bbs[module]]: - if offset in cfg.block_map.idx_to_block[next].bytecode_offsets: - cfg.edge_counts[(current_executing_bbs[module], next)] += 1 - cfg.block_map.idx_to_block[next].exec_count += 1 - - current_executing_bbs[module] = next - break - assert(offset in cfg.block_map.idx_to_block[current_executing_bbs[module]].bytecode_offsets) + try: + cfg = self.cfgs[module] + + if module not in current_executing_bbs: # this means start at bb0, set exec count for bb0 to 1 + current_executing_bbs[module] = 0 + cfg.block_map.idx_to_block[0].exec_count = 1 + + for offset in offset_list: + if offset not in cfg.block_map.idx_to_block[current_executing_bbs[module]].bytecode_offsets: + for next in cfg.edges[current_executing_bbs[module]]: + if offset in cfg.block_map.idx_to_block[next].bytecode_offsets: + cfg.edge_counts[(current_executing_bbs[module], next)] += 1 + cfg.block_map.idx_to_block[next].exec_count += 1 + + current_executing_bbs[module] = next + break + assert(offset in cfg.block_map.idx_to_block[current_executing_bbs[module]].bytecode_offsets) + except Exception as e: + self.set_finished(e) + print(e) + return self.variable_values = self.tracker.get_variable_values() - self.prompt_llm() self.finished_exception_lock.acquire() while (not self.finished): self.finished_exception_lock.release() time.sleep(5) + print('\nUpdating cfgs') update_cfg() + self.prompt_llm() self.finished_exception_lock.acquire() self.finished_exception_lock.release() @@ -575,7 +586,9 @@ def update_cfg(): # if self.exception: # print("Exception occured:", self.exception) # self.finished_exception_lock.release() + print('\nUpdating cfgs at the end') update_cfg() + self.prompt_llm() # response_dict = {'cfg': self.cfgs, 'instructions': self.cfgs[module_name].display_instructions(), 'list of local variables at sequential line numbers': variables_by_line} # prompt = [] From 4e8ac6daa5a423443a661d0126731f1085148fe1 Mon Sep 17 00:00:00 2001 From: Jayanaka-98 Date: Mon, 25 Nov 2024 15:35:46 -0500 Subject: [PATCH 50/84] modular ghost --- jac/jaclang/runtimelib/gins/ghost.py | 164 +++++++++++++++ jac/jaclang/runtimelib/gins/tracer.py | 4 +- jac/jaclang/runtimelib/machine.py | 281 +------------------------- 3 files changed, 169 insertions(+), 280 deletions(-) create mode 100644 jac/jaclang/runtimelib/gins/ghost.py diff --git a/jac/jaclang/runtimelib/gins/ghost.py b/jac/jaclang/runtimelib/gins/ghost.py new file mode 100644 index 0000000000..ef70c93c47 --- /dev/null +++ b/jac/jaclang/runtimelib/gins/ghost.py @@ -0,0 +1,164 @@ +"""The Shell Ghost code for gins""" +import os +import threading +import time + + +from jaclang.runtimelib.gins.tracer import CFGTracker +try: + import google.generativeai as genai +except Exception as e: + print("google.generativeai module not present. Please install using 'pip install google.generativeai'.") + +class ShellGhost: + def __init__(self): + self.cfgs = None + self.cfg_cv = threading.Condition() + self.tracker = CFGTracker() + self.sem_ir = None + + self.finished_exception_lock = threading.Lock() + self.exception = None + self.finished = False + self.variable_values = None + + genai.configure(api_key=os.getenv("GEMINI_API_KEY")) + self.model = genai.GenerativeModel("gemini-1.5-flash") + + + def set_cfgs(self, cfgs): + self.cfg_cv.acquire() + self.cfgs = cfgs + self.cfg_cv.notify() + self.cfg_cv.release() + + def start_ghost(self): + self.__ghost_thread = threading.Thread(target=self.worker) + self.__ghost_thread.start() + + def set_finished(self, exception: Exception = None): + self.finished_exception_lock.acquire() + self.exception = exception + self.finished = True + self.finished_exception_lock.release() + + def prompt_llm(self, verbose: bool = False): + prompt = """I have a program. +CFGS: +{cfgs}, +Instructions per basic block: +{instructions} +Semantic and Type information from source code: +{sem_ir}""" + + cfg_string = "" + ins_string = "" + for module, cfg in self.cfgs.items(): + cfg_string += f"Module: {module}\n{cfg}" + ins_string += f"Module: {module}\n{cfg.display_instructions()}" + + prompt = prompt.format(cfgs=cfg_string, instructions=ins_string, sem_ir=self.sem_ir) + + if self.variable_values != None: + prompt += "\nCurrent variable values at the specified bytecode offset:" + + for module, var_map in self.variable_values.items(): + prompt += f"\nModule {module}: Offset: {var_map[0]}, Variables: {str(var_map[1])}" + + self.finished_exception_lock.acquire() + + if self.exception: + prompt += f"\nException: {self.exception}" + + self.finished_exception_lock.release() + + prompt += "\nCan you identity bottlneck optimizations or where the code can error out?" + prompt += "\n(Reason about the program using bytecode, cfg, semantic and type information to infer the source code indirectly)" + + if verbose: + print(prompt) + + response = self.model.generate_content(prompt) + + print(response.text) + + def worker(self): + + # get static cfgs + self.cfg_cv.acquire() + while (self.cfgs == None): + self.cfg_cv.wait() + # print(self.cfgs) + # for module_name, cfg in self.cfgs.items(): + # print(f"Name: {module_name}\n{cfg.display_instructions()}") + self.cfg_cv.release() + + # Once cv has been notifie, self.cfgs is no longer accessed across threads + + + current_executing_bbs = {} + + def update_cfg(): + exec_insts = self.tracker.get_exec_inst() + + # don't prompt if there's nothing new + if exec_insts == {}: return + for module, offset_list in exec_insts.items(): + try: + cfg = self.cfgs[module] + + if module not in current_executing_bbs: # this means start at bb0, set exec count for bb0 to 1 + current_executing_bbs[module] = 0 + cfg.block_map.idx_to_block[0].exec_count = 1 + + for offset in offset_list: + if offset not in cfg.block_map.idx_to_block[current_executing_bbs[module]].bytecode_offsets: + for next in cfg.edges[current_executing_bbs[module]]: + if offset in cfg.block_map.idx_to_block[next].bytecode_offsets: + cfg.edge_counts[(current_executing_bbs[module], next)] += 1 + cfg.block_map.idx_to_block[next].exec_count += 1 + + current_executing_bbs[module] = next + break + assert(offset in cfg.block_map.idx_to_block[current_executing_bbs[module]].bytecode_offsets) + except Exception as e: + self.set_finished(e) + print(e) + return + + self.variable_values = self.tracker.get_variable_values() + + self.finished_exception_lock.acquire() + while (not self.finished): + self.finished_exception_lock.release() + + time.sleep(5) + print('\nUpdating cfgs') + update_cfg() + self.prompt_llm() + self.finished_exception_lock.acquire() + + self.finished_exception_lock.release() + + # print(self.cfgs) + # self.finished_exception_lock.acquire() + # if self.exception: + # print("Exception occured:", self.exception) + # self.finished_exception_lock.release() + print('\nUpdating cfgs at the end') + update_cfg() + self.prompt_llm() + + # response_dict = {'cfg': self.cfgs, 'instructions': self.cfgs[module_name].display_instructions(), 'list of local variables at sequential line numbers': variables_by_line} + # prompt = [] + # for k,v in response_dict.items(): + # prompt.append(f"here is my {k}:\n{v}") + # prompt.append("\nCan you identify where the code could have an error?") + # response = model.generate_content("".join(prompt)) + + # print("PROMPT:\n") + # print("".join(prompt)) + # print("RESPONSE:\n") + # print(response.text) + + # print(self.cfgs['hot_path'].display_instructions()) \ No newline at end of file diff --git a/jac/jaclang/runtimelib/gins/tracer.py b/jac/jaclang/runtimelib/gins/tracer.py index 842a8720f3..cbb2a152a4 100644 --- a/jac/jaclang/runtimelib/gins/tracer.py +++ b/jac/jaclang/runtimelib/gins/tracer.py @@ -1,5 +1,5 @@ import types -from typing import Optional, Union +from typing import Optional, Union, Callable import threading import sys import copy @@ -39,7 +39,7 @@ def get_variable_values(self): return cpy - def trace_callback(self, frame: types.FrameType, event: str, arg: any) -> Optional[types.TraceFunction]: + def trace_callback(self, frame: types.FrameType, event: str, arg: any) -> Optional[Callable]: if event == "call": frame.f_trace_opcodes = True # frame.f_trace_lines = False diff --git a/jac/jaclang/runtimelib/machine.py b/jac/jaclang/runtimelib/machine.py index ec9af96e9e..f93168d4a0 100644 --- a/jac/jaclang/runtimelib/machine.py +++ b/jac/jaclang/runtimelib/machine.py @@ -5,16 +5,10 @@ import inspect import marshal import os -import copy -import time import sys import tempfile import types -import asyncio -import dis -import google.generativeai as genai -import threading -from collections import defaultdict + from contextvars import ContextVar from typing import Optional, Union @@ -29,6 +23,7 @@ NodeArchitype, WalkerArchitype, ) +from jaclang.runtimelib.gins.ghost import ShellGhost from jaclang.utils.log import logging from jaclang.compiler.passes.main.schedules import py_code_gen, type_checker_sched @@ -332,274 +327,4 @@ def get_bytecode( if result.ir.gen.py_bytecode is not None: return marshal.loads(result.ir.gen.py_bytecode) else: - return None - - -class CFGTracker: - def __init__(self): - self.executed_insts = {} - self.inst_lock = threading.Lock() - - self.curr_variables_lock = threading.Lock() - self.curr_variables = {} - - def start_tracking(self): - """Start tracking branch coverage""" - frame = sys._getframe() - frame.f_trace_opcodes = True - sys.settrace(self.trace_callback) - def stop_tracking(self): - """Stop tracking branch coverage""" - sys.settrace(None) - - def get_exec_inst(self): - - self.inst_lock.acquire() - cpy = copy.deepcopy(self.executed_insts) - self.executed_insts = {} - self.inst_lock.release() - - return cpy - - def get_variable_values(self): - self.curr_variables_lock.acquire() - cpy = copy.deepcopy(self.curr_variables) - self.curr_variables_lock.release() - - return cpy - - - def trace_callback(self, frame: types.FrameType, event: str, arg: any) -> Optional[types.TraceFunction]: - if event == "call": - frame.f_trace_opcodes = True - # frame.f_trace_lines = False - # def tracefunc(frame, event, arg): - # if event == 'call': - # frame.f_trace_opcodes = True - # elif event == 'opcode': - # if frame.f_code.co_code[frame.f_lasti] == dis.opmap['MAKE_FUNCTION']: - # makefunctiontracefunc(frame) - # return tracefunc - - """Trace function to track executed branches""" - code = frame.f_code - if ".jac" not in code.co_filename: - return self.trace_callback - - - - # if event != 'line': - # return self.trace_callback - - if event == 'opcode': - # print(frame.f_lasti) - - # print(frame.f_lineno, frame.f_lasti) - - #edge case to handle executing code not within a function - filename = os.path.basename(code.co_filename) - module = code.co_name if code.co_name != "" else os.path.splitext(filename)[0] - - self.inst_lock.acquire() - if module not in self.executed_insts: - self.executed_insts[module] = [] - self.executed_insts[module].append(frame.f_lasti) - self.inst_lock.release() - variable_dict = {} - if '__annotations__' in frame.f_locals: - self.curr_variables_lock.acquire() - for var_name in frame.f_locals['__annotations__']: - variable_dict[var_name] = frame.f_locals[var_name] - self.curr_variables[module] = (frame.f_lasti, variable_dict) - self.curr_variables_lock.release() - - # self.variable_values[code.co_name][frame.f_lineno] = {} - - - # print(f"{frame.f_lineno}") - # print(f"Function Name: {code.co_name}") - # print(f"Filename: {code.co_filename}") - # print(f"First Line Number: {code.co_firstlineno}") - # print(f"Argument Count: {code.co_argcount}") - # print(f"Constants: {code.co_consts}") - # print(f"Local Variables: {code.co_varnames}") - - # if event != 'line': - # return self.trace_callback - - # code = frame.f_code - # if code not in self.cfg_cache: - # self.build_cfg(code) - - # # Find current basic block - # blocks = self.cfg_cache[code] - # current_offset = frame.f_lasti - - # # Find the block containing this offset - # current_block = None - # for block in blocks.values(): - # if block.offset <= current_offset <= block.offset + sum(inst.size for inst in block.instructions): - # current_block = block - # break - - # if current_block: - # current_block.hits += 1 - # # Record taken branches - # for next_block in current_block.next: - # self.coverage_data[code].add( - # (current_block.offset, next_block.offset)) - - return self.trace_callback - -class ShellGhost: - def __init__(self): - self.cfgs = None - self.cfg_cv = threading.Condition() - self.tracker = CFGTracker() - self.sem_ir = None - - self.finished_exception_lock = threading.Lock() - self.exception = None - self.finished = False - self.variable_values = None - - genai.configure(api_key=os.getenv("GEMINI_API_KEY")) - self.model = genai.GenerativeModel("gemini-1.5-flash") - - - def set_cfgs(self, cfgs): - self.cfg_cv.acquire() - self.cfgs = cfgs - self.cfg_cv.notify() - self.cfg_cv.release() - - def start_ghost(self): - self.__ghost_thread = threading.Thread(target=self.worker) - self.__ghost_thread.start() - - def set_finished(self, exception: Exception = None): - self.finished_exception_lock.acquire() - self.exception = exception - self.finished = True - self.finished_exception_lock.release() - - def prompt_llm(self, verbose: bool = False): - prompt = """I have a program. -CFGS: -{cfgs}, -Instructions per basic block: -{instructions} -Semantic and Type information from source code: -{sem_ir}""" - - cfg_string = "" - ins_string = "" - for module, cfg in self.cfgs.items(): - cfg_string += f"Module: {module}\n{cfg}" - ins_string += f"Module: {module}\n{cfg.display_instructions()}" - - prompt = prompt.format(cfgs=cfg_string, instructions=ins_string, sem_ir=self.sem_ir) - - if self.variable_values != None: - prompt += "\nCurrent variable values at the specified bytecode offset:" - - for module, var_map in self.variable_values.items(): - prompt += f"\nModule {module}: Offset: {var_map[0]}, Variables: {str(var_map[1])}" - - self.finished_exception_lock.acquire() - - if self.exception: - prompt += f"\nException: {self.exception}" - - self.finished_exception_lock.release() - - prompt += "\nCan you identity bottlneck optimizations or where the code can error out?" - prompt += "\n(Reason about the program using bytecode, cfg, semantic and type information to infer the source code indirectly)" - - if verbose: - print(prompt) - - response = self.model.generate_content(prompt) - - print(response.text) - - def worker(self): - - # get static cfgs - self.cfg_cv.acquire() - while (self.cfgs == None): - self.cfg_cv.wait() - # print(self.cfgs) - # for module_name, cfg in self.cfgs.items(): - # print(f"Name: {module_name}\n{cfg.display_instructions()}") - self.cfg_cv.release() - - # Once cv has been notifie, self.cfgs is no longer accessed across threads - - - current_executing_bbs = {} - - def update_cfg(): - exec_insts = self.tracker.get_exec_inst() - - # don't prompt if there's nothing new - if exec_insts == {}: return - for module, offset_list in exec_insts.items(): - try: - cfg = self.cfgs[module] - - if module not in current_executing_bbs: # this means start at bb0, set exec count for bb0 to 1 - current_executing_bbs[module] = 0 - cfg.block_map.idx_to_block[0].exec_count = 1 - - for offset in offset_list: - if offset not in cfg.block_map.idx_to_block[current_executing_bbs[module]].bytecode_offsets: - for next in cfg.edges[current_executing_bbs[module]]: - if offset in cfg.block_map.idx_to_block[next].bytecode_offsets: - cfg.edge_counts[(current_executing_bbs[module], next)] += 1 - cfg.block_map.idx_to_block[next].exec_count += 1 - - current_executing_bbs[module] = next - break - assert(offset in cfg.block_map.idx_to_block[current_executing_bbs[module]].bytecode_offsets) - except Exception as e: - self.set_finished(e) - print(e) - return - - self.variable_values = self.tracker.get_variable_values() - - self.finished_exception_lock.acquire() - while (not self.finished): - self.finished_exception_lock.release() - - time.sleep(5) - print('\nUpdating cfgs') - update_cfg() - self.prompt_llm() - self.finished_exception_lock.acquire() - - self.finished_exception_lock.release() - - # print(self.cfgs) - # self.finished_exception_lock.acquire() - # if self.exception: - # print("Exception occured:", self.exception) - # self.finished_exception_lock.release() - print('\nUpdating cfgs at the end') - update_cfg() - self.prompt_llm() - - # response_dict = {'cfg': self.cfgs, 'instructions': self.cfgs[module_name].display_instructions(), 'list of local variables at sequential line numbers': variables_by_line} - # prompt = [] - # for k,v in response_dict.items(): - # prompt.append(f"here is my {k}:\n{v}") - # prompt.append("\nCan you identify where the code could have an error?") - # response = model.generate_content("".join(prompt)) - - # print("PROMPT:\n") - # print("".join(prompt)) - # print("RESPONSE:\n") - # print(response.text) - - # print(self.cfgs['hot_path'].display_instructions()) \ No newline at end of file + return None \ No newline at end of file From f4f2594efd0cb3569cfb0899e38519244c09e930 Mon Sep 17 00:00:00 2001 From: Jayanaka-98 Date: Mon, 25 Nov 2024 15:42:13 -0500 Subject: [PATCH 51/84] visualization code uncomment --- jac/jaclang/compiler/passes/main/cfg_gen_pass.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/jac/jaclang/compiler/passes/main/cfg_gen_pass.py b/jac/jaclang/compiler/passes/main/cfg_gen_pass.py index b7ea50b22e..dc52a67a77 100644 --- a/jac/jaclang/compiler/passes/main/cfg_gen_pass.py +++ b/jac/jaclang/compiler/passes/main/cfg_gen_pass.py @@ -37,9 +37,9 @@ def enter_module(self, node: ast.Module) -> None: BBs = create_BBs(instructions) cfg = create_cfg(BBs) module_cfgs[mod.name] = cfg - # for cfg in module_cfgs.values(): - # dot = visualize_cfg(cfg) - # dot.render('cfg.gv', view=True) + for cfg in module_cfgs.values(): + dot = visualize_cfg(cfg) + dot.render('cfg.gv', view=True) if JacMachine.get().gin: try: JacMachine.get().gin.set_cfgs(cfgs=module_cfgs) From f7e975b76ce31e70d58b61b52df96ed47d0337dd Mon Sep 17 00:00:00 2001 From: Jayanaka-98 Date: Mon, 25 Nov 2024 15:46:55 -0500 Subject: [PATCH 52/84] new jac example for threading --- jac/examples/ginsScripts/power.jac | 44 ++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 jac/examples/ginsScripts/power.jac diff --git a/jac/examples/ginsScripts/power.jac b/jac/examples/ginsScripts/power.jac new file mode 100644 index 0000000000..e9b2472ce0 --- /dev/null +++ b/jac/examples/ginsScripts/power.jac @@ -0,0 +1,44 @@ +with entry { + +# Data structure representing system configuration +system_config = { + 'base_load': 1000, # Base power load in watts + 'min_duration': 5, # Minimum valid duration in minutes + 'mode': 'active' +}; + +# Input data representing power readings +power_readings = [880, 920, 950, 980, 1000]; # Last reading equals base_load +time_periods = [15, 20, 25, 30, 35]; + +# Initialize results storage +efficiency_metrics = []; +total_operational_time = 0; + +# Process each power reading +for (idx, current_power) in enumerate(power_readings){ + if system_config['mode'] != 'active'{ + continue; + } + duration = time_periods[idx]; + if duration < system_config['min_duration']{ + continue; + } + # This division will fail when current_power equals base_load (1000W) + # The error is hidden because it's part of a complex formula that looks valid + power_utilization = (current_power - system_config['base_load']) / (max(power_readings) - system_config['base_load']); + + # Complex metric calculation makes the division less obvious + period_efficiency = power_utilization * (duration / max(time_periods)) * 100; + + efficiency_metrics.append(period_efficiency); + total_operational_time += duration; +} + +# Calculate final metrics +average_efficiency = sum(efficiency_metrics) / len(efficiency_metrics) if efficiency_metrics else 0; +operational_hours = total_operational_time / 60; + +print(f"System Analysis Complete - Efficiency: {average_efficiency}%"); + +} \ No newline at end of file From eb630bb217e5a6d6cc12cc7c790fedd0bf864624 Mon Sep 17 00:00:00 2001 From: Jakob Louis Therkelsen Date: Mon, 25 Nov 2024 19:03:54 -0500 Subject: [PATCH 53/84] consistent file naming for examples --- jac/examples/{ginsScripts => gins_scripts}/cfg.gv | 0 .../{ginsScripts => gins_scripts}/cfg.gv.pdf | Bin .../{ginsScripts => gins_scripts}/hot_path.jac | 0 .../{ginsScripts => gins_scripts}/hot_path_cfg.png | Bin .../{ginsScripts => gins_scripts}/power.jac | 0 .../{ginsScripts => gins_scripts}/simple.jac | 0 .../{ginsScripts => gins_scripts}/simple_cfg.png | Bin .../compiler/passes/{cfg.py => cfg_to_delete.py} | 0 8 files changed, 0 insertions(+), 0 deletions(-) rename jac/examples/{ginsScripts => gins_scripts}/cfg.gv (100%) rename jac/examples/{ginsScripts => gins_scripts}/cfg.gv.pdf (100%) rename jac/examples/{ginsScripts => gins_scripts}/hot_path.jac (100%) rename jac/examples/{ginsScripts => gins_scripts}/hot_path_cfg.png (100%) rename jac/examples/{ginsScripts => gins_scripts}/power.jac (100%) rename jac/examples/{ginsScripts => gins_scripts}/simple.jac (100%) rename jac/examples/{ginsScripts => gins_scripts}/simple_cfg.png (100%) rename jac/jaclang/compiler/passes/{cfg.py => cfg_to_delete.py} (100%) diff --git a/jac/examples/ginsScripts/cfg.gv b/jac/examples/gins_scripts/cfg.gv similarity index 100% rename from jac/examples/ginsScripts/cfg.gv rename to jac/examples/gins_scripts/cfg.gv diff --git a/jac/examples/ginsScripts/cfg.gv.pdf b/jac/examples/gins_scripts/cfg.gv.pdf similarity index 100% rename from jac/examples/ginsScripts/cfg.gv.pdf rename to jac/examples/gins_scripts/cfg.gv.pdf diff --git a/jac/examples/ginsScripts/hot_path.jac b/jac/examples/gins_scripts/hot_path.jac similarity index 100% rename from jac/examples/ginsScripts/hot_path.jac rename to jac/examples/gins_scripts/hot_path.jac diff --git a/jac/examples/ginsScripts/hot_path_cfg.png b/jac/examples/gins_scripts/hot_path_cfg.png similarity index 100% rename from jac/examples/ginsScripts/hot_path_cfg.png rename to jac/examples/gins_scripts/hot_path_cfg.png diff --git a/jac/examples/ginsScripts/power.jac b/jac/examples/gins_scripts/power.jac similarity index 100% rename from jac/examples/ginsScripts/power.jac rename to jac/examples/gins_scripts/power.jac diff --git a/jac/examples/ginsScripts/simple.jac b/jac/examples/gins_scripts/simple.jac similarity index 100% rename from jac/examples/ginsScripts/simple.jac rename to jac/examples/gins_scripts/simple.jac diff --git a/jac/examples/ginsScripts/simple_cfg.png b/jac/examples/gins_scripts/simple_cfg.png similarity index 100% rename from jac/examples/ginsScripts/simple_cfg.png rename to jac/examples/gins_scripts/simple_cfg.png diff --git a/jac/jaclang/compiler/passes/cfg.py b/jac/jaclang/compiler/passes/cfg_to_delete.py similarity index 100% rename from jac/jaclang/compiler/passes/cfg.py rename to jac/jaclang/compiler/passes/cfg_to_delete.py From b1e7350ac5326cbc0563a0af4ae64639e25c5ffc Mon Sep 17 00:00:00 2001 From: Jakob Louis Therkelsen Date: Mon, 25 Nov 2024 19:49:15 -0500 Subject: [PATCH 54/84] clean up bb logic --- jac/examples/gins_scripts/cfg.gv | 16 ++++++++++++---- jac/examples/gins_scripts/cfg.gv.pdf | Bin 11975 -> 13177 bytes jac/jaclang/runtimelib/gins/cfg.py | 12 ++++-------- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/jac/examples/gins_scripts/cfg.gv b/jac/examples/gins_scripts/cfg.gv index 0774a4c90f..d5a088b0e3 100644 --- a/jac/examples/gins_scripts/cfg.gv +++ b/jac/examples/gins_scripts/cfg.gv @@ -8,13 +8,21 @@ digraph { bb5 [label=BB5] bb6 [label=BB6] bb7 [label=BB7] - bb0 -> bb7 + bb8 [label=BB8] + bb9 [label=BB9] + bb10 [label=BB10] bb0 -> bb1 - bb1 -> bb3 bb1 -> bb2 - bb3 -> bb4 + bb1 -> bb7 + bb2 -> bb4 + bb2 -> bb3 + bb3 -> bb1 bb4 -> bb6 bb4 -> bb5 bb5 -> bb1 - bb6 -> bb7 + bb6 -> bb1 + bb7 -> bb9 + bb7 -> bb8 + bb8 -> bb10 + bb9 -> bb10 } diff --git a/jac/examples/gins_scripts/cfg.gv.pdf b/jac/examples/gins_scripts/cfg.gv.pdf index de98ee28068a00dfd3f7656a4257a2d8ff19c028..7a5133769502c3d23c9e533bb6e1fd7e47fd94bf 100644 GIT binary patch delta 11817 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 qh`0tZg%LzBGwN;wis_zZU;qG6*9+8>Q8OJ2F*h BlockMap: def valid_offset(offset): return offset >= 0 and offset <= max_offset + # Identify all block starts for instr in instructions: if instr.is_branch() or instr.op == "FOR_ITER": next_instr_offset = instr.get_next_instruction_offset() + target_offset = instr.argval - if 0 <= next_instr_offset <= max_offset: + if valid_offset(next_instr_offset): block_starts.add(next_instr_offset) - - #TODO: Confirm we can clean this up - if instr.is_relative_branch(): - target_offset = instr.argval - else: - target_offset = instr.argval - + if valid_offset(target_offset): block_starts.add(target_offset) From f582d1f46fd1700eaefe3e57100d8b90696c90b4 Mon Sep 17 00:00:00 2001 From: Jakob Louis Therkelsen Date: Mon, 25 Nov 2024 20:36:40 -0500 Subject: [PATCH 55/84] simplify and fix cfg logic --- .gitignore | 4 +++ jac/examples/gins_scripts/simple_for.jac | 13 ++++++++ .../compiler/passes/main/cfg_gen_pass.py | 2 +- jac/jaclang/runtimelib/gins/cfg.py | 32 ++++++++----------- 4 files changed, 32 insertions(+), 19 deletions(-) create mode 100644 jac/examples/gins_scripts/simple_for.jac diff --git a/.gitignore b/.gitignore index 4c0607f61e..395fe8ba7d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,6 @@ .jac_mypy_cache/ .envrc + +#ignore generated visual files +cfg.gv.pdf +cfg.gv \ No newline at end of file diff --git a/jac/examples/gins_scripts/simple_for.jac b/jac/examples/gins_scripts/simple_for.jac new file mode 100644 index 0000000000..00fbcb3a01 --- /dev/null +++ b/jac/examples/gins_scripts/simple_for.jac @@ -0,0 +1,13 @@ +with entry { + x:int = 0; + y:int = 3; + z:int = x + y; + for i in range(3) { + x = 4 * i + y * (z); + if x % 2 { + y = y + x; + z = x + y; + } + } + z = 10; +} \ No newline at end of file diff --git a/jac/jaclang/compiler/passes/main/cfg_gen_pass.py b/jac/jaclang/compiler/passes/main/cfg_gen_pass.py index dc52a67a77..853d150daf 100644 --- a/jac/jaclang/compiler/passes/main/cfg_gen_pass.py +++ b/jac/jaclang/compiler/passes/main/cfg_gen_pass.py @@ -34,7 +34,7 @@ def enter_module(self, node: ast.Module) -> None: for mod in mods: bytecode = mod.gen.py_bytecode instructions = disassemble_bytecode(bytecode) - BBs = create_BBs(instructions) + BBs = create_BBs(instructions) cfg = create_cfg(BBs) module_cfgs[mod.name] = cfg for cfg in module_cfgs.values(): diff --git a/jac/jaclang/runtimelib/gins/cfg.py b/jac/jaclang/runtimelib/gins/cfg.py index bb341b5249..a5a06b26b9 100644 --- a/jac/jaclang/runtimelib/gins/cfg.py +++ b/jac/jaclang/runtimelib/gins/cfg.py @@ -22,7 +22,7 @@ def __init__(self, op: int, arg: int, offset: int, argval:int, argrepr:str, is_j self.__offset_size = 0 def __repr__(self): - return f"Instr: offset={self.offset}, Opname={self.op}, arg={self.arg}, argval={self.argval}, argrepr={self.argrepr}" + return f"Instr: offset={self.offset}, Opname={self.op}, arg={self.arg}, argval={self.argval}, argrepr={self.argrepr}, jump_t={self.is_jump_target}" def is_branch(self) -> bool: return self.op in { "JUMP_ABSOLUTE", @@ -115,14 +115,14 @@ def valid_offset(offset): next_instr_offset = instr.get_next_instruction_offset() target_offset = instr.argval - if valid_offset(next_instr_offset): + if instr.op == "FOR_ITER": + block_starts.add(instr.offset) + elif valid_offset(next_instr_offset): block_starts.add(next_instr_offset) if valid_offset(target_offset): block_starts.add(target_offset) - if instr.is_jump_target: - block_starts.add(instr.offset) block_starts_ordered = sorted(block_starts) # print(f"Identified block starts: {block_starts_ordered}") @@ -186,7 +186,15 @@ def create_cfg(block_map: BlockMap) -> CFG: x = 1 cfg.add_node(block_id) + first_instr = block.instructions[0] last_instr = block.instructions[-1] + if first_instr.op == "FOR_ITER": + # Edge to END_FOR or loop exit + end_for_offset = first_instr.argval + end_for_block = find_block_by_offset(block_map, end_for_offset) + if end_for_block is not None: + cfg.add_edge(block_id, end_for_block) + # Handle conditional jumps (e.g., POP_JUMP_IF_FALSE) if last_instr.is_branch(): @@ -211,18 +219,6 @@ def create_cfg(block_map: BlockMap) -> CFG: if target_block is not None: cfg.add_edge(block_id, target_block) - elif last_instr.op == "FOR_ITER": - # Edge to loop body - loop_body_offset = last_instr.get_next_instruction_offset() - loop_body_block = find_block_by_offset(block_map, loop_body_offset) - if loop_body_block is not None: - cfg.add_edge(block_id, loop_body_block) - # Edge to END_FOR or loop exit - end_for_offset = last_instr.argval - end_for_block = find_block_by_offset(block_map, end_for_offset) - if end_for_block is not None: - cfg.add_edge(block_id, end_for_block) - # Handle fall-through to the next block for non-control flow instructions else: fall_through_offset = block.instructions[-1].get_next_instruction_offset() @@ -252,8 +248,8 @@ def visualize_cfg(cfg: CFG): ##simple= #instructions = disassemble_bytecode(b'c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x01\xf3*\x00\x00\x00\x97\x00d\x00d\x01l\x00m\x01Z\x01\x01\x00d\x00Z\x02d\x00Z\x03e\x03d\x00k\\\x00\x00r\x02d\x02Z\x02d\x03Z\x02y\x04)\x05\xe9\x00\x00\x00\x00)\x01\xda\x0bannotations\xe9\x01\x00\x00\x00\xe9\xff\xff\xff\xffN)\x04\xda\n__future__r\x02\x00\x00\x00\xda\x01a\xda\x01x\xa9\x00\xf3\x00\x00\x00\x00\xfaP/Users/jakobtherkelsen/Documents/jaseci-ginS/jac/examples/ginsScripts/simple.jac\xfa\x08r\x0b\x00\x00\x00\x01\x00\x00\x00s%\x00\x00\x00\xf0\x03\x01\x01\x01\xf5\x02\x07\x02\x03\xd8\x05\x06\x801\xd8\x05\x06\x801\xd8\x06\x07\x881\x82f\xd8\x07\x08\x80Q\xe0\x05\x07\x811r\t\x00\x00\x00') #hot path -# instructions = disassemble_bytecode(b'c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x01\xf3T\x00\x00\x00\x97\x00d\x00d\x01l\x00m\x01Z\x01\x01\x00d\x00Z\x02d\x00Z\x03e\x02d\x02k\x02\x00\x00r\x19e\x02d\x03z\x06\x00\x00d\x00k(\x00\x00r\x03d\x04Z\x03n\x02d\x03Z\x03e\x02d\x04z\r\x00\x00Z\x02e\x02d\x02k\x02\x00\x00r\x01\x8c\x18y\x05y\x05)\x06\xe9\x00\x00\x00\x00)\x01\xda\x0bannotations\xe9\x0f\x00\x00\x00\xe9\x02\x00\x00\x00\xe9\x01\x00\x00\x00N)\x04\xda\n__future__r\x02\x00\x00\x00\xda\x01a\xda\x01b\xa9\x00\xf3\x00\x00\x00\x00\xfaR/Users/jakobtherkelsen/Documents/jaseci-ginS/jac/examples/ginsScripts/hot_path.jac\xfa\x08r\x0c\x00\x00\x00\x01\x00\x00\x00sD\x00\x00\x00\xf0\x03\x01\x01\x01\xf5\x02\x0c\x02\x03\xd8\x07\x08\x801\xd8\x07\x08\x801\xd8\t\n\x88R\x8a\x16\xd8\x08\t\x88A\x89\x05\x90\x11\x8a\n\xd8\x0b\x0c\x81q\xf0\x06\x00\x0c\r\x80q\xe0\x05\x06\x88!\x81W\x80Q\xf0\x0f\x00\n\x0b\x88R\x8d\x16r\n\x00\x00\x00') -# # # #guess_game_bc = disassemble_bytecode(b'c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x01\xf3\x9e\x01\x00\x00\x97\x00d\x00Z\x00d\x01d\x02l\x01m\x02Z\x02\x01\x00d\x01d\x03l\x03m\x04Z\x05\x01\x00d\x01d\x04l\x06Z\x07d\x01d\x05l\x08m\tZ\n\x01\x00d\x01d\x06l\x0b\xad\x02\x01\x00d\x01d\x07l\x0cm\rZ\x0e\x01\x00e\x07j\x1e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00r\x05d\x01d\x04l\x10Z\x10n\x10\x02\x00e\x05d\x08e\x11d\td\nd\x04i\x00\xac\x0b\xab\x06\x00\x00\x00\x00\x00\x00\\\x01\x00\x00Z\x10\x02\x00e\nj$\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00g\x00g\x00\xac\x0c\xab\x02\x00\x00\x00\x00\x00\x00\x02\x00e\x0ed\n\xac\r\xab\x01\x00\x00\x00\x00\x00\x00\x02\x00G\x00d\x0e\x84\x00d\x0fe\nj&\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xab\x03\x00\x00\x00\x00\x00\x00\xab\x00\x00\x00\x00\x00\x00\x00\xab\x00\x00\x00\x00\x00\x00\x00Z\x14\x02\x00e\nj$\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00g\x00g\x00\xac\x0c\xab\x02\x00\x00\x00\x00\x00\x00\x02\x00e\x0ed\n\xac\r\xab\x01\x00\x00\x00\x00\x00\x00\x02\x00G\x00d\x10\x84\x00d\x11e\x14e\nj&\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xab\x04\x00\x00\x00\x00\x00\x00\xab\x00\x00\x00\x00\x00\x00\x00\xab\x00\x00\x00\x00\x00\x00\x00Z\x15\t\x00\x02\x00e\x15\xab\x00\x00\x00\x00\x00\x00\x00Z\x16e\x16j/\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xab\x00\x00\x00\x00\x00\x00\x00\x01\x00y\x04)\x12\xfa\x16A Number Guessing Game\xe9\x00\x00\x00\x00)\x01\xda\x0bannotations)\x01\xda\njac_importN)\x01\xda\nJacFeature)\x01\xda\x01*)\x01\xda\tdataclass\xda\x06random\xda\x02pyF)\x06\xda\x06target\xda\tbase_path\xda\x03lng\xda\x06absorb\xda\tmdl_alias\xda\x05items)\x02\xda\x08on_entry\xda\x07on_exit)\x01\xda\x02eqc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x01\xf3 \x00\x00\x00\x97\x00e\x00Z\x01d\x00Z\x02d\x01Z\x03d\x05d\x02\x84\x04Z\x04d\x06d\x03\x84\x04Z\x05y\x04)\x07\xda\x04Game\xe1\x1a\x01\x00\x00\nA generic Game base class.\n\nThe obj keyword is used to define the class.\nThe can keyword is used to define methods (functions) within the class.\nThe self keyword is used to refer to the current instance of the class.\nConstructors are defined using the init method with parameters.\nc\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x01\xf3 \x00\x00\x00\x97\x00|\x01|\x00_\x00\x00\x00\x00\x00\x00\x00\x00\x00d\x01|\x00_\x01\x00\x00\x00\x00\x00\x00\x00\x00y\x00)\x02NF)\x02\xda\x08attempts\xda\x03won)\x02\xda\x04selfr\x17\x00\x00\x00s\x02\x00\x00\x00 \xfaT/Users/jakobtherkelsen/Documents/jaseci-ginS/jac/examples/guess_game/guess_game1.jac\xda\x08__init__z\rGame.__init__\x0e\x00\x00\x00s\x10\x00\x00\x00\x80\x00\xd8\x19!\x88\x14\x8c\x1d\xd8\x14\x19\x88\x14\x8d\x18\xf3\x00\x00\x00\x00c\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03\x00\x00\x01\xf3\x18\x00\x00\x00\x97\x00t\x01\x00\x00\x00\x00\x00\x00\x00\x00d\x01\xab\x01\x00\x00\x00\x00\x00\x00\x82\x01)\x02N\xfa&Subclasses must implement this method.)\x01\xda\x13NotImplementedError)\x01r\x19\x00\x00\x00s\x01\x00\x00\x00 r\x1a\x00\x00\x00\xda\x04playz\tGame.play\x13\x00\x00\x00s\x12\x00\x00\x00\x80\x00\xdc\x0f"\xd8\r5\xf3\x03\x02\x10\x10\xf0\x00\x02\n\x0cr\x1c\x00\x00\x00N\xa9\x04r\x17\x00\x00\x00\xda\x03int\xda\x06return\xda\x04None\xa9\x02r#\x00\x00\x00r$\x00\x00\x00)\x06\xda\x08__name__\xda\n__module__\xda\x0c__qualname__\xda\x07__doc__r\x1b\x00\x00\x00r \x00\x00\x00\xa9\x00r\x1c\x00\x00\x00r\x1a\x00\x00\x00r\x14\x00\x00\x00r\x14\x00\x00\x00\x05\x00\x00\x00s\x11\x00\x00\x00\x84\x00\xf1\x00\x07\x02\x05\xf3\x12\x03\x06\x07\xf4\n\x04\x06\x07r\x1c\x00\x00\x00r\x14\x00\x00\x00c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x01\xf36\x00\x00\x00\x87\x00\x97\x00e\x00Z\x01d\x00Z\x02d\x01Z\x03d\x05d\x06\x88\x00f\x01d\x02\x84\rZ\x04d\x07d\x03\x84\x04Z\x05d\x08d\x04\x84\x04Z\x06\x88\x00x\x01Z\x07S\x00)\t\xda\x12GuessTheNumberGame\xfa\xae\nA number guessing game. The player must guess a number between 1 and 100.\n\nThis class inherits from Game. The super() function is used to call the parent class constructor.\nc\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x03\x00\x00\x01\xf3Z\x00\x00\x00\x95\x01\x97\x00t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x89\x02|\x00\x8d\x05\x00\x00|\x01\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00t\x05\x00\x00\x00\x00\x00\x00\x00\x00j\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00d\x01d\x02\xab\x02\x00\x00\x00\x00\x00\x00|\x00_\x04\x00\x00\x00\x00\x00\x00\x00\x00y\x00)\x03N\xe9\x01\x00\x00\x00\xe9d\x00\x00\x00)\x05\xda\x05superr\x1b\x00\x00\x00r\x08\x00\x00\x00\xda\x07randint\xda\x0ecorrect_number)\x03r\x19\x00\x00\x00r\x17\x00\x00\x00\xda\t__class__s\x03\x00\x00\x00 \x80r\x1a\x00\x00\x00r\x1b\x00\x00\x00z\x1bGuessTheNumberGame.__init__ \x00\x00\x00s \x00\x00\x00\xf8\x80\x00\xde\t\x0e\x89\x1a\x90H\xd4\t\x1d\xdc\x1f%\x9f~\x99~\xa8a\xb0\x13\xd3\x1f5\x88\x14\xd5\t\x1cr\x1c\x00\x00\x00c\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x03\x00\x00\x01\xf3\xf4\x00\x00\x00\x97\x00|\x00j\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00d\x01kD\x00\x00rQt\x03\x00\x00\x00\x00\x00\x00\x00\x00d\x02\xab\x01\x00\x00\x00\x00\x00\x00}\x01|\x01j\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xab\x00\x00\x00\x00\x00\x00\x00r\x1b|\x00j\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00t\t\x00\x00\x00\x00\x00\x00\x00\x00|\x01\xab\x01\x00\x00\x00\x00\x00\x00\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00n\x0bt\x0b\x00\x00\x00\x00\x00\x00\x00\x00d\x03\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00|\x00j\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00d\x01kD\x00\x00r\x01\x8cQ|\x00j\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00s\x0ct\x0b\x00\x00\x00\x00\x00\x00\x00\x00d\x04\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00y\x00y\x00)\x05Nr\x02\x00\x00\x00\xfa"Guess a number between 1 and 100: \xfa%That\'s not a valid number! Try again.\xfa:Sorry, you didn\'t guess the number. Better luck next time!)\x07r\x17\x00\x00\x00\xda\x05input\xda\x07isdigit\xda\rprocess_guessr"\x00\x00\x00\xda\x05printr\x18\x00\x00\x00\xa9\x02r\x19\x00\x00\x00\xda\x05guesss\x02\x00\x00\x00 r\x1a\x00\x00\x00\xfa\x04playz\x17GuessTheNumberGame.play%\x00\x00\x00sd\x00\x00\x00\x80\x00\xe0\x0f\x13\x8f}\x89}\x98q\xd2\x0f \xdc\x15\x1a\xd0\x1b?\xd3\x15@\x88U\xd8\x10\x15\x97\r\x91\r\x94\x0f\xd8\x11\x15\xd7\x11#\xd1\x11#\xa4C\xa8\x05\xa3J\xd5\x11/\xe4\x11\x16\xd0\x17>\xd4\x11?\xf0\x0b\x00\x10\x14\x8f}\x89}\x98q\xd3\x0f \xf0\x10\x00\x11\x15\x97\x08\x92\x08\xdc\r\x12\xd8\x11M\xf5\x03\x02\x0e\x0f\xf0\x03\x00\x11\x19r\x1c\x00\x00\x00c\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x03\x00\x00\x01\xf3\xfe\x00\x00\x00\x97\x00|\x01|\x00j\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00kD\x00\x00r\x0ct\x03\x00\x00\x00\x00\x00\x00\x00\x00d\x01\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00n4|\x01|\x00j\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00k\x02\x00\x00r\x0ct\x03\x00\x00\x00\x00\x00\x00\x00\x00d\x02\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00n\x19t\x03\x00\x00\x00\x00\x00\x00\x00\x00d\x03\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00d\x04|\x00_\x02\x00\x00\x00\x00\x00\x00\x00\x00d\x05|\x00_\x03\x00\x00\x00\x00\x00\x00\x00\x00|\x00x\x01j\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00d\x06z\x17\x00\x00c\x02_\x02\x00\x00\x00\x00\x00\x00\x00\x00t\x03\x00\x00\x00\x00\x00\x00\x00\x00d\x07|\x00j\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9b\x00d\x08\x9d\x03\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00y\x00)\tN\xfa\tToo high!\xfa\x08Too low!\xfa\'Congratulations! You guessed correctly.r\x02\x00\x00\x00Tr/\x00\x00\x00\xfa\tYou have \xfa\x0f attempts left.)\x04r3\x00\x00\x00r<\x00\x00\x00r\x17\x00\x00\x00r\x18\x00\x00\x00r=\x00\x00\x00s\x02\x00\x00\x00 r\x1a\x00\x00\x00\xfa\rprocess_guessz GuessTheNumberGame.process_guess6\x00\x00\x00se\x00\x00\x00\x80\x00\xd8\x0c\x11\x90D\xd7\x14\'\xd1\x14\'\xd2\x0c\'\xdc\r\x12\x90;\xd5\r\x1f\xd8\x10\x15\x98\x04\xd7\x18+\xd1\x18+\xd2\x10+\xdc\r\x12\x90:\xd5\r\x1e\xe4\r\x12\xd0\x13<\xd4\r=\xd8\x1d\x1e\x88T\x8c]\xd8\x18\x1c\x88T\x8cX\xe0\t\r\x8f\x1d\x8a\x1d\x98!\xd1\t\x1c\x8d\x1d\xdc\t\x0e\xd0\x0f9\x984\x9f=\x9a=\xd1\x0f9\xd5\t:r\x1c\x00\x00\x00)\x01\xe9\n\x00\x00\x00r!\x00\x00\x00r%\x00\x00\x00)\x04r>\x00\x00\x00r"\x00\x00\x00r#\x00\x00\x00r$\x00\x00\x00)\x08r&\x00\x00\x00r\'\x00\x00\x00r(\x00\x00\x00r)\x00\x00\x00r\x1b\x00\x00\x00r \x00\x00\x00r;\x00\x00\x00\xda\r__classcell__)\x01r4\x00\x00\x00s\x01\x00\x00\x00@r\x1a\x00\x00\x00r,\x00\x00\x00r,\x00\x00\x00\x1a\x00\x00\x00s\x17\x00\x00\x00\xf8\x84\x00\xf1\x00\x04\x02\x05\xf6\x0c\x03\x06\x07\xf3\n\x0f\x06\x07\xf7"\x0c\x06\x07r\x1c\x00\x00\x00r,\x00\x00\x00)\x18r)\x00\x00\x00\xda\n__future__r\x03\x00\x00\x00\xda\x07jaclangr\x04\x00\x00\x00\xda\x0e__jac_import__\xda\x06typing\xda\x08_jac_typ\xda\x16jaclang.plugin.featurer\x05\x00\x00\x00\xda\x04_Jac\xda\x16jaclang.plugin.builtin\xda\x0bdataclassesr\x07\x00\x00\x00\xda\x11__jac_dataclass__\xda\rTYPE_CHECKINGr\x08\x00\x00\x00\xda\x08__file__\xda\x08make_obj\xda\x03Objr\x14\x00\x00\x00r,\x00\x00\x00\xda\x04gamer \x00\x00\x00r*\x00\x00\x00r\x1c\x00\x00\x00r\x1a\x00\x00\x00\xda\x08rX\x00\x00\x00\x01\x00\x00\x00s\xaa\x00\x00\x00\xf0\x03\x01\x01\x01\xd9\x01\x1d\xf7\x00K\x01\x02\x03\xf7\x00K\x01\x02\x03\xf7\x00K\x01\x02\x03\xf7\x00K\x01\x02\x03\xf0\x00K\x01\x02\x03\xe7\x01\x12\xd7\x01\x12\xd4\x01\x12\x80s\xd7\x01\x12\xd2\x01\x12\xf1\x04\x13\x02\x03\xef&\xe9\x00\xf7\'\x13\x02\x03\xf7\x00\x13\x02\x03\xf4\x00\x13\x02\x03\xef&\xe9\x00\xf7\'\x13\x02\x03\xf4\x00\x13\x02\x03\xf1*)\x02\x03\xefR\x01\xe9\x00\xf7S\x01)\x02\x03\xf7\x00)\x02\x03\xf3\x00)\x02\x03\xf0\n\x00\x1a\x1e\xf0\x0b)\x02\x03\xefR\x01\xe9\x00\xf7S\x01)\x02\x03\xf4\x00)\x02\x03\xf0X\x01\x02\x02\x05\xf1\x08\x00\r\x1f\xd3\x0c \x80T\xd8\x05\t\x87Y\x81Y\x85[r\x1c\x00\x00\x00') +# instructions = disassemble_bytecode(b'c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x01\xf3\x96\x00\x00\x00\x97\x00U\x00d\x00d\x01l\x00m\x01Z\x01\x01\x00d\x00Z\x02d\x02e\x03d\x03<\x00\x00\x00d\x04Z\x04d\x02e\x03d\x05<\x00\x00\x00e\x02e\x04z\x00\x00\x00Z\x05d\x02e\x03d\x06<\x00\x00\x00\x02\x00e\x06d\x04\xab\x01\x00\x00\x00\x00\x00\x00D\x00]\x1d\x00\x00Z\x07d\x07e\x07z\x05\x00\x00e\x04e\x05z\x05\x00\x00z\x00\x00\x00Z\x02e\x02d\x08z\x06\x00\x00s\x01\x8c\x14e\x04e\x02z\x00\x00\x00Z\x04e\x02e\x04z\x00\x00\x00Z\x05\x8c\x1f\x04\x00d\tZ\x05y\n)\x0b\xe9\x00\x00\x00\x00)\x01\xda\x0bannotations\xda\x03int\xda\x01x\xe9\x03\x00\x00\x00\xda\x01y\xda\x01z\xe9\x04\x00\x00\x00\xe9\x02\x00\x00\x00\xe9\n\x00\x00\x00N)\x08\xda\n__future__r\x02\x00\x00\x00r\x04\x00\x00\x00\xda\x0f__annotations__r\x06\x00\x00\x00r\x07\x00\x00\x00\xda\x05range\xda\x01i\xa9\x00\xf3\x00\x00\x00\x00\xfaU/Users/jakobtherkelsen/Documents/jaseci-ginS/jac/examples/gins_scripts/simple_for.jac\xda\x08r\x12\x00\x00\x00\x01\x00\x00\x00sh\x00\x00\x00\xf0\x03\x01\x01\x01\xf6\x02\x0c\x02\x03\xd8\r\x0e\x80Q\x80s\x83Z\xd8\r\x0e\x80Q\x80s\x83Z\xd8\r\x0e\x90\x11\x89U\x80Q\x80s\x83^\xd9\x0e\x13\x90A\x8eh\x88\x11\xd8\r\x0e\x90\x11\x89U\x90Q\x98!\x91W\x89_\x88\x11\xd8\x0c\r\x90\x01\x8bE\xd8\x11\x12\x90Q\x91\x15\x88Q\xd8\x11\x12\x90Q\x91\x15\x89Q\xf0\t\x00\x0f\x17\xf0\x0e\x00\n\x0c\x81Qr\x10\x00\x00\x00') +# # # # #guess_game_bc = disassemble_bytecode(b'c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x01\xf3\x9e\x01\x00\x00\x97\x00d\x00Z\x00d\x01d\x02l\x01m\x02Z\x02\x01\x00d\x01d\x03l\x03m\x04Z\x05\x01\x00d\x01d\x04l\x06Z\x07d\x01d\x05l\x08m\tZ\n\x01\x00d\x01d\x06l\x0b\xad\x02\x01\x00d\x01d\x07l\x0cm\rZ\x0e\x01\x00e\x07j\x1e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00r\x05d\x01d\x04l\x10Z\x10n\x10\x02\x00e\x05d\x08e\x11d\td\nd\x04i\x00\xac\x0b\xab\x06\x00\x00\x00\x00\x00\x00\\\x01\x00\x00Z\x10\x02\x00e\nj$\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00g\x00g\x00\xac\x0c\xab\x02\x00\x00\x00\x00\x00\x00\x02\x00e\x0ed\n\xac\r\xab\x01\x00\x00\x00\x00\x00\x00\x02\x00G\x00d\x0e\x84\x00d\x0fe\nj&\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xab\x03\x00\x00\x00\x00\x00\x00\xab\x00\x00\x00\x00\x00\x00\x00\xab\x00\x00\x00\x00\x00\x00\x00Z\x14\x02\x00e\nj$\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00g\x00g\x00\xac\x0c\xab\x02\x00\x00\x00\x00\x00\x00\x02\x00e\x0ed\n\xac\r\xab\x01\x00\x00\x00\x00\x00\x00\x02\x00G\x00d\x10\x84\x00d\x11e\x14e\nj&\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xab\x04\x00\x00\x00\x00\x00\x00\xab\x00\x00\x00\x00\x00\x00\x00\xab\x00\x00\x00\x00\x00\x00\x00Z\x15\t\x00\x02\x00e\x15\xab\x00\x00\x00\x00\x00\x00\x00Z\x16e\x16j/\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xab\x00\x00\x00\x00\x00\x00\x00\x01\x00y\x04)\x12\xfa\x16A Number Guessing Game\xe9\x00\x00\x00\x00)\x01\xda\x0bannotations)\x01\xda\njac_importN)\x01\xda\nJacFeature)\x01\xda\x01*)\x01\xda\tdataclass\xda\x06random\xda\x02pyF)\x06\xda\x06target\xda\tbase_path\xda\x03lng\xda\x06absorb\xda\tmdl_alias\xda\x05items)\x02\xda\x08on_entry\xda\x07on_exit)\x01\xda\x02eqc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x01\xf3 \x00\x00\x00\x97\x00e\x00Z\x01d\x00Z\x02d\x01Z\x03d\x05d\x02\x84\x04Z\x04d\x06d\x03\x84\x04Z\x05y\x04)\x07\xda\x04Game\xe1\x1a\x01\x00\x00\nA generic Game base class.\n\nThe obj keyword is used to define the class.\nThe can keyword is used to define methods (functions) within the class.\nThe self keyword is used to refer to the current instance of the class.\nConstructors are defined using the init method with parameters.\nc\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x01\xf3 \x00\x00\x00\x97\x00|\x01|\x00_\x00\x00\x00\x00\x00\x00\x00\x00\x00d\x01|\x00_\x01\x00\x00\x00\x00\x00\x00\x00\x00y\x00)\x02NF)\x02\xda\x08attempts\xda\x03won)\x02\xda\x04selfr\x17\x00\x00\x00s\x02\x00\x00\x00 \xfaT/Users/jakobtherkelsen/Documents/jaseci-ginS/jac/examples/guess_game/guess_game1.jac\xda\x08__init__z\rGame.__init__\x0e\x00\x00\x00s\x10\x00\x00\x00\x80\x00\xd8\x19!\x88\x14\x8c\x1d\xd8\x14\x19\x88\x14\x8d\x18\xf3\x00\x00\x00\x00c\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03\x00\x00\x01\xf3\x18\x00\x00\x00\x97\x00t\x01\x00\x00\x00\x00\x00\x00\x00\x00d\x01\xab\x01\x00\x00\x00\x00\x00\x00\x82\x01)\x02N\xfa&Subclasses must implement this method.)\x01\xda\x13NotImplementedError)\x01r\x19\x00\x00\x00s\x01\x00\x00\x00 r\x1a\x00\x00\x00\xda\x04playz\tGame.play\x13\x00\x00\x00s\x12\x00\x00\x00\x80\x00\xdc\x0f"\xd8\r5\xf3\x03\x02\x10\x10\xf0\x00\x02\n\x0cr\x1c\x00\x00\x00N\xa9\x04r\x17\x00\x00\x00\xda\x03int\xda\x06return\xda\x04None\xa9\x02r#\x00\x00\x00r$\x00\x00\x00)\x06\xda\x08__name__\xda\n__module__\xda\x0c__qualname__\xda\x07__doc__r\x1b\x00\x00\x00r \x00\x00\x00\xa9\x00r\x1c\x00\x00\x00r\x1a\x00\x00\x00r\x14\x00\x00\x00r\x14\x00\x00\x00\x05\x00\x00\x00s\x11\x00\x00\x00\x84\x00\xf1\x00\x07\x02\x05\xf3\x12\x03\x06\x07\xf4\n\x04\x06\x07r\x1c\x00\x00\x00r\x14\x00\x00\x00c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x01\xf36\x00\x00\x00\x87\x00\x97\x00e\x00Z\x01d\x00Z\x02d\x01Z\x03d\x05d\x06\x88\x00f\x01d\x02\x84\rZ\x04d\x07d\x03\x84\x04Z\x05d\x08d\x04\x84\x04Z\x06\x88\x00x\x01Z\x07S\x00)\t\xda\x12GuessTheNumberGame\xfa\xae\nA number guessing game. The player must guess a number between 1 and 100.\n\nThis class inherits from Game. The super() function is used to call the parent class constructor.\nc\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x03\x00\x00\x01\xf3Z\x00\x00\x00\x95\x01\x97\x00t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x89\x02|\x00\x8d\x05\x00\x00|\x01\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00t\x05\x00\x00\x00\x00\x00\x00\x00\x00j\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00d\x01d\x02\xab\x02\x00\x00\x00\x00\x00\x00|\x00_\x04\x00\x00\x00\x00\x00\x00\x00\x00y\x00)\x03N\xe9\x01\x00\x00\x00\xe9d\x00\x00\x00)\x05\xda\x05superr\x1b\x00\x00\x00r\x08\x00\x00\x00\xda\x07randint\xda\x0ecorrect_number)\x03r\x19\x00\x00\x00r\x17\x00\x00\x00\xda\t__class__s\x03\x00\x00\x00 \x80r\x1a\x00\x00\x00r\x1b\x00\x00\x00z\x1bGuessTheNumberGame.__init__ \x00\x00\x00s \x00\x00\x00\xf8\x80\x00\xde\t\x0e\x89\x1a\x90H\xd4\t\x1d\xdc\x1f%\x9f~\x99~\xa8a\xb0\x13\xd3\x1f5\x88\x14\xd5\t\x1cr\x1c\x00\x00\x00c\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x03\x00\x00\x01\xf3\xf4\x00\x00\x00\x97\x00|\x00j\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00d\x01kD\x00\x00rQt\x03\x00\x00\x00\x00\x00\x00\x00\x00d\x02\xab\x01\x00\x00\x00\x00\x00\x00}\x01|\x01j\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xab\x00\x00\x00\x00\x00\x00\x00r\x1b|\x00j\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00t\t\x00\x00\x00\x00\x00\x00\x00\x00|\x01\xab\x01\x00\x00\x00\x00\x00\x00\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00n\x0bt\x0b\x00\x00\x00\x00\x00\x00\x00\x00d\x03\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00|\x00j\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00d\x01kD\x00\x00r\x01\x8cQ|\x00j\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00s\x0ct\x0b\x00\x00\x00\x00\x00\x00\x00\x00d\x04\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00y\x00y\x00)\x05Nr\x02\x00\x00\x00\xfa"Guess a number between 1 and 100: \xfa%That\'s not a valid number! Try again.\xfa:Sorry, you didn\'t guess the number. Better luck next time!)\x07r\x17\x00\x00\x00\xda\x05input\xda\x07isdigit\xda\rprocess_guessr"\x00\x00\x00\xda\x05printr\x18\x00\x00\x00\xa9\x02r\x19\x00\x00\x00\xda\x05guesss\x02\x00\x00\x00 r\x1a\x00\x00\x00\xfa\x04playz\x17GuessTheNumberGame.play%\x00\x00\x00sd\x00\x00\x00\x80\x00\xe0\x0f\x13\x8f}\x89}\x98q\xd2\x0f \xdc\x15\x1a\xd0\x1b?\xd3\x15@\x88U\xd8\x10\x15\x97\r\x91\r\x94\x0f\xd8\x11\x15\xd7\x11#\xd1\x11#\xa4C\xa8\x05\xa3J\xd5\x11/\xe4\x11\x16\xd0\x17>\xd4\x11?\xf0\x0b\x00\x10\x14\x8f}\x89}\x98q\xd3\x0f \xf0\x10\x00\x11\x15\x97\x08\x92\x08\xdc\r\x12\xd8\x11M\xf5\x03\x02\x0e\x0f\xf0\x03\x00\x11\x19r\x1c\x00\x00\x00c\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x03\x00\x00\x01\xf3\xfe\x00\x00\x00\x97\x00|\x01|\x00j\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00kD\x00\x00r\x0ct\x03\x00\x00\x00\x00\x00\x00\x00\x00d\x01\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00n4|\x01|\x00j\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00k\x02\x00\x00r\x0ct\x03\x00\x00\x00\x00\x00\x00\x00\x00d\x02\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00n\x19t\x03\x00\x00\x00\x00\x00\x00\x00\x00d\x03\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00d\x04|\x00_\x02\x00\x00\x00\x00\x00\x00\x00\x00d\x05|\x00_\x03\x00\x00\x00\x00\x00\x00\x00\x00|\x00x\x01j\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00d\x06z\x17\x00\x00c\x02_\x02\x00\x00\x00\x00\x00\x00\x00\x00t\x03\x00\x00\x00\x00\x00\x00\x00\x00d\x07|\x00j\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9b\x00d\x08\x9d\x03\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00y\x00)\tN\xfa\tToo high!\xfa\x08Too low!\xfa\'Congratulations! You guessed correctly.r\x02\x00\x00\x00Tr/\x00\x00\x00\xfa\tYou have \xfa\x0f attempts left.)\x04r3\x00\x00\x00r<\x00\x00\x00r\x17\x00\x00\x00r\x18\x00\x00\x00r=\x00\x00\x00s\x02\x00\x00\x00 r\x1a\x00\x00\x00\xfa\rprocess_guessz GuessTheNumberGame.process_guess6\x00\x00\x00se\x00\x00\x00\x80\x00\xd8\x0c\x11\x90D\xd7\x14\'\xd1\x14\'\xd2\x0c\'\xdc\r\x12\x90;\xd5\r\x1f\xd8\x10\x15\x98\x04\xd7\x18+\xd1\x18+\xd2\x10+\xdc\r\x12\x90:\xd5\r\x1e\xe4\r\x12\xd0\x13<\xd4\r=\xd8\x1d\x1e\x88T\x8c]\xd8\x18\x1c\x88T\x8cX\xe0\t\r\x8f\x1d\x8a\x1d\x98!\xd1\t\x1c\x8d\x1d\xdc\t\x0e\xd0\x0f9\x984\x9f=\x9a=\xd1\x0f9\xd5\t:r\x1c\x00\x00\x00)\x01\xe9\n\x00\x00\x00r!\x00\x00\x00r%\x00\x00\x00)\x04r>\x00\x00\x00r"\x00\x00\x00r#\x00\x00\x00r$\x00\x00\x00)\x08r&\x00\x00\x00r\'\x00\x00\x00r(\x00\x00\x00r)\x00\x00\x00r\x1b\x00\x00\x00r \x00\x00\x00r;\x00\x00\x00\xda\r__classcell__)\x01r4\x00\x00\x00s\x01\x00\x00\x00@r\x1a\x00\x00\x00r,\x00\x00\x00r,\x00\x00\x00\x1a\x00\x00\x00s\x17\x00\x00\x00\xf8\x84\x00\xf1\x00\x04\x02\x05\xf6\x0c\x03\x06\x07\xf3\n\x0f\x06\x07\xf7"\x0c\x06\x07r\x1c\x00\x00\x00r,\x00\x00\x00)\x18r)\x00\x00\x00\xda\n__future__r\x03\x00\x00\x00\xda\x07jaclangr\x04\x00\x00\x00\xda\x0e__jac_import__\xda\x06typing\xda\x08_jac_typ\xda\x16jaclang.plugin.featurer\x05\x00\x00\x00\xda\x04_Jac\xda\x16jaclang.plugin.builtin\xda\x0bdataclassesr\x07\x00\x00\x00\xda\x11__jac_dataclass__\xda\rTYPE_CHECKINGr\x08\x00\x00\x00\xda\x08__file__\xda\x08make_obj\xda\x03Objr\x14\x00\x00\x00r,\x00\x00\x00\xda\x04gamer \x00\x00\x00r*\x00\x00\x00r\x1c\x00\x00\x00r\x1a\x00\x00\x00\xda\x08rX\x00\x00\x00\x01\x00\x00\x00s\xaa\x00\x00\x00\xf0\x03\x01\x01\x01\xd9\x01\x1d\xf7\x00K\x01\x02\x03\xf7\x00K\x01\x02\x03\xf7\x00K\x01\x02\x03\xf7\x00K\x01\x02\x03\xf0\x00K\x01\x02\x03\xe7\x01\x12\xd7\x01\x12\xd4\x01\x12\x80s\xd7\x01\x12\xd2\x01\x12\xf1\x04\x13\x02\x03\xef&\xe9\x00\xf7\'\x13\x02\x03\xf7\x00\x13\x02\x03\xf4\x00\x13\x02\x03\xef&\xe9\x00\xf7\'\x13\x02\x03\xf4\x00\x13\x02\x03\xf1*)\x02\x03\xefR\x01\xe9\x00\xf7S\x01)\x02\x03\xf7\x00)\x02\x03\xf3\x00)\x02\x03\xf0\n\x00\x1a\x1e\xf0\x0b)\x02\x03\xefR\x01\xe9\x00\xf7S\x01)\x02\x03\xf4\x00)\x02\x03\xf0X\x01\x02\x02\x05\xf1\x08\x00\r\x1f\xd3\x0c \x80T\xd8\x05\t\x87Y\x81Y\x85[r\x1c\x00\x00\x00') # BBs = create_BBs(instructions) # print(BBs) From b66a3f4aec0dcfc4d14b8b123c108f8e81fb7dba Mon Sep 17 00:00:00 2001 From: Jakob Louis Therkelsen Date: Mon, 25 Nov 2024 21:30:22 -0500 Subject: [PATCH 56/84] simplify cfg and bb logic --- jac/examples/gins_scripts/simple_for.jac | 13 +-- jac/jaclang/runtimelib/gins/cfg.py | 101 +++++++++++------------ 2 files changed, 55 insertions(+), 59 deletions(-) diff --git a/jac/examples/gins_scripts/simple_for.jac b/jac/examples/gins_scripts/simple_for.jac index 00fbcb3a01..488ce84ecd 100644 --- a/jac/examples/gins_scripts/simple_for.jac +++ b/jac/examples/gins_scripts/simple_for.jac @@ -3,11 +3,14 @@ with entry { y:int = 3; z:int = x + y; for i in range(3) { - x = 4 * i + y * (z); - if x % 2 { - y = y + x; - z = x + y; - } + if x % 2 { + y = y + x; + z = x + y; + } + x = 4 * i + y * (z); } z = 10; + if z == 10 { + z =4; + } } \ No newline at end of file diff --git a/jac/jaclang/runtimelib/gins/cfg.py b/jac/jaclang/runtimelib/gins/cfg.py index a5a06b26b9..ab2ba7a044 100644 --- a/jac/jaclang/runtimelib/gins/cfg.py +++ b/jac/jaclang/runtimelib/gins/cfg.py @@ -17,7 +17,6 @@ def __init__(self, op: int, arg: int, offset: int, argval:int, argrepr:str, is_j self.argval = argval self.argrepr = argrepr self.is_jump_target= is_jump_target - # self.line_number = line_number #default the offset self.__offset_size = 0 @@ -27,11 +26,21 @@ def is_branch(self) -> bool: return self.op in { "JUMP_ABSOLUTE", "JUMP_FORWARD", + "JUMP_BACKWARD", "POP_JUMP_IF_TRUE", "POP_JUMP_IF_FALSE", "JUMP_IF_TRUE_OR_POP", "JUMP_IF_FALSE_OR_POP", } + def is_conditional_branch(self) -> bool: + return self.op in { + # TODO:These may not be used anymore? + "JUMP_IF_TRUE_OR_POP", + "JUMP_IF_FALSE_OR_POP", + "POP_JUMP_IF_TRUE", + "POP_JUMP_IF_FALSE", + } + def is_relative_branch(self) -> bool: return False def is_return(self) -> bool: @@ -40,6 +49,9 @@ def is_return(self) -> bool: def is_raise(self) -> bool: return self.op == "RAISE_VARARGS" + def is_for_iter(self) -> bool: + return self.op == "FOR_ITER" + def set_offset_size(self, size) -> None: self.__offset_size = size @@ -90,7 +102,7 @@ def disassemble_bytecode(bytecode): is_jump_target=instr.is_jump_target, )) #set offest size for calculating next instruction - #last instruction is default of 2, but shouldn't be needed + #last instruction is default of 0, but shouldn't be needed if i != 0: instruction = instructions[i-1] instruction.set_offset_size(instr.offset - instructions[i-1].offset) @@ -111,11 +123,11 @@ def valid_offset(offset): # Identify all block starts for instr in instructions: - if instr.is_branch() or instr.op == "FOR_ITER": + if instr.is_branch() or instr.is_for_iter(): next_instr_offset = instr.get_next_instruction_offset() target_offset = instr.argval - if instr.op == "FOR_ITER": + if instr.is_for_iter(): block_starts.add(instr.offset) elif valid_offset(next_instr_offset): block_starts.add(next_instr_offset) @@ -123,24 +135,18 @@ def valid_offset(offset): if valid_offset(target_offset): block_starts.add(target_offset) - + #identify the blocks, since we define BBs by jumps, a sorted list of those + #instructions give a range for instructions each BB will hold block_starts_ordered = sorted(block_starts) - # print(f"Identified block starts: {block_starts_ordered}") - for block_id, start_offset in enumerate(block_starts_ordered): end_offset = block_starts_ordered[block_id + 1] if block_id + 1 < len(block_starts_ordered) else instructions[-1].get_next_instruction_offset() start_index = offset_to_index[start_offset] - end_index = num_instr - - # Find the corresponding end_index - for offset in block_starts_ordered: - if offset > start_offset: - try: - end_index = offset_to_index[offset] - except Exception as e: - print(f'Error: {e}') - break - + end_index = offset_to_index[end_offset] + + # capture last instruction if the BB only has 1 + if start_index == end_index: + end_index += 1 + # Collect instructions for this block block_instrs = instructions[start_index:end_index] block_map.add_block(block_id, Block(block_id, block_instrs)) @@ -178,48 +184,35 @@ def __repr__(self): for succ in self.edges[node]: result.append(f' -> bb{succ} (edge exec count={self.edge_counts[(node, succ)]})') return "\n".join(result) + def create_cfg(block_map: BlockMap) -> CFG: cfg = CFG(block_map) for block_id, block in block_map.idx_to_block.items(): - if block_id == 7: - x = 1 cfg.add_node(block_id) first_instr = block.instructions[0] last_instr = block.instructions[-1] - if first_instr.op == "FOR_ITER": - # Edge to END_FOR or loop exit + if first_instr.is_for_iter(): + # get the BB that starts with END_FOR end_for_offset = first_instr.argval end_for_block = find_block_by_offset(block_map, end_for_offset) if end_for_block is not None: cfg.add_edge(block_id, end_for_block) - - # Handle conditional jumps (e.g., POP_JUMP_IF_FALSE) + # handle jumps if last_instr.is_branch(): - target_offset = last_instr.argval if not last_instr.is_relative_branch() else (last_instr.offset + last_instr.argval) + target_offset = last_instr.argval target_block = find_block_by_offset(block_map, target_offset) if target_block is not None: cfg.add_edge(block_id, target_block) - # Fall-through to next block if it's a conditional branch - if last_instr.op.startswith('POP_JUMP_IF'): + if last_instr.is_conditional_branch(): fall_through_offset = block.instructions[-1].get_next_instruction_offset() fall_through_block = find_block_by_offset(block_map, fall_through_offset) if fall_through_block is not None: cfg.add_edge(block_id, fall_through_block) - # Handle unconditional jumps (e.g., JUMP_FORWARD, JUMP_ABSOLUTE) - elif last_instr.op.startswith("JUMP"): - if last_instr.op == "JUMP_BACKWARD": - target_offset = last_instr.argval if not last_instr.is_relative_branch() else (last_instr.offset - last_instr.argval) - else: - target_offset = last_instr.argval if not last_instr.is_relative_branch() else (last_instr.offset + last_instr.argval) - target_block = find_block_by_offset(block_map, target_offset) - if target_block is not None: - cfg.add_edge(block_id, target_block) - - # Handle fall-through to the next block for non-control flow instructions + # handle fall-through to the next block for non-control flow instructions else: fall_through_offset = block.instructions[-1].get_next_instruction_offset() fall_through_block = find_block_by_offset(block_map, fall_through_offset) @@ -244,19 +237,19 @@ def visualize_cfg(cfg: CFG): dot.edge(f"bb{from_node}", f"bb{to_node}") return dot -# Sample list of instructions for processing -##simple= -#instructions = disassemble_bytecode(b'c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x01\xf3*\x00\x00\x00\x97\x00d\x00d\x01l\x00m\x01Z\x01\x01\x00d\x00Z\x02d\x00Z\x03e\x03d\x00k\\\x00\x00r\x02d\x02Z\x02d\x03Z\x02y\x04)\x05\xe9\x00\x00\x00\x00)\x01\xda\x0bannotations\xe9\x01\x00\x00\x00\xe9\xff\xff\xff\xffN)\x04\xda\n__future__r\x02\x00\x00\x00\xda\x01a\xda\x01x\xa9\x00\xf3\x00\x00\x00\x00\xfaP/Users/jakobtherkelsen/Documents/jaseci-ginS/jac/examples/ginsScripts/simple.jac\xfa\x08r\x0b\x00\x00\x00\x01\x00\x00\x00s%\x00\x00\x00\xf0\x03\x01\x01\x01\xf5\x02\x07\x02\x03\xd8\x05\x06\x801\xd8\x05\x06\x801\xd8\x06\x07\x881\x82f\xd8\x07\x08\x80Q\xe0\x05\x07\x811r\t\x00\x00\x00') -#hot path -# instructions = disassemble_bytecode(b'c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x01\xf3\x96\x00\x00\x00\x97\x00U\x00d\x00d\x01l\x00m\x01Z\x01\x01\x00d\x00Z\x02d\x02e\x03d\x03<\x00\x00\x00d\x04Z\x04d\x02e\x03d\x05<\x00\x00\x00e\x02e\x04z\x00\x00\x00Z\x05d\x02e\x03d\x06<\x00\x00\x00\x02\x00e\x06d\x04\xab\x01\x00\x00\x00\x00\x00\x00D\x00]\x1d\x00\x00Z\x07d\x07e\x07z\x05\x00\x00e\x04e\x05z\x05\x00\x00z\x00\x00\x00Z\x02e\x02d\x08z\x06\x00\x00s\x01\x8c\x14e\x04e\x02z\x00\x00\x00Z\x04e\x02e\x04z\x00\x00\x00Z\x05\x8c\x1f\x04\x00d\tZ\x05y\n)\x0b\xe9\x00\x00\x00\x00)\x01\xda\x0bannotations\xda\x03int\xda\x01x\xe9\x03\x00\x00\x00\xda\x01y\xda\x01z\xe9\x04\x00\x00\x00\xe9\x02\x00\x00\x00\xe9\n\x00\x00\x00N)\x08\xda\n__future__r\x02\x00\x00\x00r\x04\x00\x00\x00\xda\x0f__annotations__r\x06\x00\x00\x00r\x07\x00\x00\x00\xda\x05range\xda\x01i\xa9\x00\xf3\x00\x00\x00\x00\xfaU/Users/jakobtherkelsen/Documents/jaseci-ginS/jac/examples/gins_scripts/simple_for.jac\xda\x08r\x12\x00\x00\x00\x01\x00\x00\x00sh\x00\x00\x00\xf0\x03\x01\x01\x01\xf6\x02\x0c\x02\x03\xd8\r\x0e\x80Q\x80s\x83Z\xd8\r\x0e\x80Q\x80s\x83Z\xd8\r\x0e\x90\x11\x89U\x80Q\x80s\x83^\xd9\x0e\x13\x90A\x8eh\x88\x11\xd8\r\x0e\x90\x11\x89U\x90Q\x98!\x91W\x89_\x88\x11\xd8\x0c\r\x90\x01\x8bE\xd8\x11\x12\x90Q\x91\x15\x88Q\xd8\x11\x12\x90Q\x91\x15\x89Q\xf0\t\x00\x0f\x17\xf0\x0e\x00\n\x0c\x81Qr\x10\x00\x00\x00') -# # # # #guess_game_bc = disassemble_bytecode(b'c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x01\xf3\x9e\x01\x00\x00\x97\x00d\x00Z\x00d\x01d\x02l\x01m\x02Z\x02\x01\x00d\x01d\x03l\x03m\x04Z\x05\x01\x00d\x01d\x04l\x06Z\x07d\x01d\x05l\x08m\tZ\n\x01\x00d\x01d\x06l\x0b\xad\x02\x01\x00d\x01d\x07l\x0cm\rZ\x0e\x01\x00e\x07j\x1e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00r\x05d\x01d\x04l\x10Z\x10n\x10\x02\x00e\x05d\x08e\x11d\td\nd\x04i\x00\xac\x0b\xab\x06\x00\x00\x00\x00\x00\x00\\\x01\x00\x00Z\x10\x02\x00e\nj$\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00g\x00g\x00\xac\x0c\xab\x02\x00\x00\x00\x00\x00\x00\x02\x00e\x0ed\n\xac\r\xab\x01\x00\x00\x00\x00\x00\x00\x02\x00G\x00d\x0e\x84\x00d\x0fe\nj&\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xab\x03\x00\x00\x00\x00\x00\x00\xab\x00\x00\x00\x00\x00\x00\x00\xab\x00\x00\x00\x00\x00\x00\x00Z\x14\x02\x00e\nj$\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00g\x00g\x00\xac\x0c\xab\x02\x00\x00\x00\x00\x00\x00\x02\x00e\x0ed\n\xac\r\xab\x01\x00\x00\x00\x00\x00\x00\x02\x00G\x00d\x10\x84\x00d\x11e\x14e\nj&\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xab\x04\x00\x00\x00\x00\x00\x00\xab\x00\x00\x00\x00\x00\x00\x00\xab\x00\x00\x00\x00\x00\x00\x00Z\x15\t\x00\x02\x00e\x15\xab\x00\x00\x00\x00\x00\x00\x00Z\x16e\x16j/\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xab\x00\x00\x00\x00\x00\x00\x00\x01\x00y\x04)\x12\xfa\x16A Number Guessing Game\xe9\x00\x00\x00\x00)\x01\xda\x0bannotations)\x01\xda\njac_importN)\x01\xda\nJacFeature)\x01\xda\x01*)\x01\xda\tdataclass\xda\x06random\xda\x02pyF)\x06\xda\x06target\xda\tbase_path\xda\x03lng\xda\x06absorb\xda\tmdl_alias\xda\x05items)\x02\xda\x08on_entry\xda\x07on_exit)\x01\xda\x02eqc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x01\xf3 \x00\x00\x00\x97\x00e\x00Z\x01d\x00Z\x02d\x01Z\x03d\x05d\x02\x84\x04Z\x04d\x06d\x03\x84\x04Z\x05y\x04)\x07\xda\x04Game\xe1\x1a\x01\x00\x00\nA generic Game base class.\n\nThe obj keyword is used to define the class.\nThe can keyword is used to define methods (functions) within the class.\nThe self keyword is used to refer to the current instance of the class.\nConstructors are defined using the init method with parameters.\nc\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x01\xf3 \x00\x00\x00\x97\x00|\x01|\x00_\x00\x00\x00\x00\x00\x00\x00\x00\x00d\x01|\x00_\x01\x00\x00\x00\x00\x00\x00\x00\x00y\x00)\x02NF)\x02\xda\x08attempts\xda\x03won)\x02\xda\x04selfr\x17\x00\x00\x00s\x02\x00\x00\x00 \xfaT/Users/jakobtherkelsen/Documents/jaseci-ginS/jac/examples/guess_game/guess_game1.jac\xda\x08__init__z\rGame.__init__\x0e\x00\x00\x00s\x10\x00\x00\x00\x80\x00\xd8\x19!\x88\x14\x8c\x1d\xd8\x14\x19\x88\x14\x8d\x18\xf3\x00\x00\x00\x00c\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03\x00\x00\x01\xf3\x18\x00\x00\x00\x97\x00t\x01\x00\x00\x00\x00\x00\x00\x00\x00d\x01\xab\x01\x00\x00\x00\x00\x00\x00\x82\x01)\x02N\xfa&Subclasses must implement this method.)\x01\xda\x13NotImplementedError)\x01r\x19\x00\x00\x00s\x01\x00\x00\x00 r\x1a\x00\x00\x00\xda\x04playz\tGame.play\x13\x00\x00\x00s\x12\x00\x00\x00\x80\x00\xdc\x0f"\xd8\r5\xf3\x03\x02\x10\x10\xf0\x00\x02\n\x0cr\x1c\x00\x00\x00N\xa9\x04r\x17\x00\x00\x00\xda\x03int\xda\x06return\xda\x04None\xa9\x02r#\x00\x00\x00r$\x00\x00\x00)\x06\xda\x08__name__\xda\n__module__\xda\x0c__qualname__\xda\x07__doc__r\x1b\x00\x00\x00r \x00\x00\x00\xa9\x00r\x1c\x00\x00\x00r\x1a\x00\x00\x00r\x14\x00\x00\x00r\x14\x00\x00\x00\x05\x00\x00\x00s\x11\x00\x00\x00\x84\x00\xf1\x00\x07\x02\x05\xf3\x12\x03\x06\x07\xf4\n\x04\x06\x07r\x1c\x00\x00\x00r\x14\x00\x00\x00c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x01\xf36\x00\x00\x00\x87\x00\x97\x00e\x00Z\x01d\x00Z\x02d\x01Z\x03d\x05d\x06\x88\x00f\x01d\x02\x84\rZ\x04d\x07d\x03\x84\x04Z\x05d\x08d\x04\x84\x04Z\x06\x88\x00x\x01Z\x07S\x00)\t\xda\x12GuessTheNumberGame\xfa\xae\nA number guessing game. The player must guess a number between 1 and 100.\n\nThis class inherits from Game. The super() function is used to call the parent class constructor.\nc\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x03\x00\x00\x01\xf3Z\x00\x00\x00\x95\x01\x97\x00t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x89\x02|\x00\x8d\x05\x00\x00|\x01\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00t\x05\x00\x00\x00\x00\x00\x00\x00\x00j\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00d\x01d\x02\xab\x02\x00\x00\x00\x00\x00\x00|\x00_\x04\x00\x00\x00\x00\x00\x00\x00\x00y\x00)\x03N\xe9\x01\x00\x00\x00\xe9d\x00\x00\x00)\x05\xda\x05superr\x1b\x00\x00\x00r\x08\x00\x00\x00\xda\x07randint\xda\x0ecorrect_number)\x03r\x19\x00\x00\x00r\x17\x00\x00\x00\xda\t__class__s\x03\x00\x00\x00 \x80r\x1a\x00\x00\x00r\x1b\x00\x00\x00z\x1bGuessTheNumberGame.__init__ \x00\x00\x00s \x00\x00\x00\xf8\x80\x00\xde\t\x0e\x89\x1a\x90H\xd4\t\x1d\xdc\x1f%\x9f~\x99~\xa8a\xb0\x13\xd3\x1f5\x88\x14\xd5\t\x1cr\x1c\x00\x00\x00c\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x03\x00\x00\x01\xf3\xf4\x00\x00\x00\x97\x00|\x00j\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00d\x01kD\x00\x00rQt\x03\x00\x00\x00\x00\x00\x00\x00\x00d\x02\xab\x01\x00\x00\x00\x00\x00\x00}\x01|\x01j\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xab\x00\x00\x00\x00\x00\x00\x00r\x1b|\x00j\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00t\t\x00\x00\x00\x00\x00\x00\x00\x00|\x01\xab\x01\x00\x00\x00\x00\x00\x00\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00n\x0bt\x0b\x00\x00\x00\x00\x00\x00\x00\x00d\x03\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00|\x00j\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00d\x01kD\x00\x00r\x01\x8cQ|\x00j\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00s\x0ct\x0b\x00\x00\x00\x00\x00\x00\x00\x00d\x04\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00y\x00y\x00)\x05Nr\x02\x00\x00\x00\xfa"Guess a number between 1 and 100: \xfa%That\'s not a valid number! Try again.\xfa:Sorry, you didn\'t guess the number. Better luck next time!)\x07r\x17\x00\x00\x00\xda\x05input\xda\x07isdigit\xda\rprocess_guessr"\x00\x00\x00\xda\x05printr\x18\x00\x00\x00\xa9\x02r\x19\x00\x00\x00\xda\x05guesss\x02\x00\x00\x00 r\x1a\x00\x00\x00\xfa\x04playz\x17GuessTheNumberGame.play%\x00\x00\x00sd\x00\x00\x00\x80\x00\xe0\x0f\x13\x8f}\x89}\x98q\xd2\x0f \xdc\x15\x1a\xd0\x1b?\xd3\x15@\x88U\xd8\x10\x15\x97\r\x91\r\x94\x0f\xd8\x11\x15\xd7\x11#\xd1\x11#\xa4C\xa8\x05\xa3J\xd5\x11/\xe4\x11\x16\xd0\x17>\xd4\x11?\xf0\x0b\x00\x10\x14\x8f}\x89}\x98q\xd3\x0f \xf0\x10\x00\x11\x15\x97\x08\x92\x08\xdc\r\x12\xd8\x11M\xf5\x03\x02\x0e\x0f\xf0\x03\x00\x11\x19r\x1c\x00\x00\x00c\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x03\x00\x00\x01\xf3\xfe\x00\x00\x00\x97\x00|\x01|\x00j\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00kD\x00\x00r\x0ct\x03\x00\x00\x00\x00\x00\x00\x00\x00d\x01\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00n4|\x01|\x00j\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00k\x02\x00\x00r\x0ct\x03\x00\x00\x00\x00\x00\x00\x00\x00d\x02\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00n\x19t\x03\x00\x00\x00\x00\x00\x00\x00\x00d\x03\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00d\x04|\x00_\x02\x00\x00\x00\x00\x00\x00\x00\x00d\x05|\x00_\x03\x00\x00\x00\x00\x00\x00\x00\x00|\x00x\x01j\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00d\x06z\x17\x00\x00c\x02_\x02\x00\x00\x00\x00\x00\x00\x00\x00t\x03\x00\x00\x00\x00\x00\x00\x00\x00d\x07|\x00j\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9b\x00d\x08\x9d\x03\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00y\x00)\tN\xfa\tToo high!\xfa\x08Too low!\xfa\'Congratulations! You guessed correctly.r\x02\x00\x00\x00Tr/\x00\x00\x00\xfa\tYou have \xfa\x0f attempts left.)\x04r3\x00\x00\x00r<\x00\x00\x00r\x17\x00\x00\x00r\x18\x00\x00\x00r=\x00\x00\x00s\x02\x00\x00\x00 r\x1a\x00\x00\x00\xfa\rprocess_guessz GuessTheNumberGame.process_guess6\x00\x00\x00se\x00\x00\x00\x80\x00\xd8\x0c\x11\x90D\xd7\x14\'\xd1\x14\'\xd2\x0c\'\xdc\r\x12\x90;\xd5\r\x1f\xd8\x10\x15\x98\x04\xd7\x18+\xd1\x18+\xd2\x10+\xdc\r\x12\x90:\xd5\r\x1e\xe4\r\x12\xd0\x13<\xd4\r=\xd8\x1d\x1e\x88T\x8c]\xd8\x18\x1c\x88T\x8cX\xe0\t\r\x8f\x1d\x8a\x1d\x98!\xd1\t\x1c\x8d\x1d\xdc\t\x0e\xd0\x0f9\x984\x9f=\x9a=\xd1\x0f9\xd5\t:r\x1c\x00\x00\x00)\x01\xe9\n\x00\x00\x00r!\x00\x00\x00r%\x00\x00\x00)\x04r>\x00\x00\x00r"\x00\x00\x00r#\x00\x00\x00r$\x00\x00\x00)\x08r&\x00\x00\x00r\'\x00\x00\x00r(\x00\x00\x00r)\x00\x00\x00r\x1b\x00\x00\x00r \x00\x00\x00r;\x00\x00\x00\xda\r__classcell__)\x01r4\x00\x00\x00s\x01\x00\x00\x00@r\x1a\x00\x00\x00r,\x00\x00\x00r,\x00\x00\x00\x1a\x00\x00\x00s\x17\x00\x00\x00\xf8\x84\x00\xf1\x00\x04\x02\x05\xf6\x0c\x03\x06\x07\xf3\n\x0f\x06\x07\xf7"\x0c\x06\x07r\x1c\x00\x00\x00r,\x00\x00\x00)\x18r)\x00\x00\x00\xda\n__future__r\x03\x00\x00\x00\xda\x07jaclangr\x04\x00\x00\x00\xda\x0e__jac_import__\xda\x06typing\xda\x08_jac_typ\xda\x16jaclang.plugin.featurer\x05\x00\x00\x00\xda\x04_Jac\xda\x16jaclang.plugin.builtin\xda\x0bdataclassesr\x07\x00\x00\x00\xda\x11__jac_dataclass__\xda\rTYPE_CHECKINGr\x08\x00\x00\x00\xda\x08__file__\xda\x08make_obj\xda\x03Objr\x14\x00\x00\x00r,\x00\x00\x00\xda\x04gamer \x00\x00\x00r*\x00\x00\x00r\x1c\x00\x00\x00r\x1a\x00\x00\x00\xda\x08rX\x00\x00\x00\x01\x00\x00\x00s\xaa\x00\x00\x00\xf0\x03\x01\x01\x01\xd9\x01\x1d\xf7\x00K\x01\x02\x03\xf7\x00K\x01\x02\x03\xf7\x00K\x01\x02\x03\xf7\x00K\x01\x02\x03\xf0\x00K\x01\x02\x03\xe7\x01\x12\xd7\x01\x12\xd4\x01\x12\x80s\xd7\x01\x12\xd2\x01\x12\xf1\x04\x13\x02\x03\xef&\xe9\x00\xf7\'\x13\x02\x03\xf7\x00\x13\x02\x03\xf4\x00\x13\x02\x03\xef&\xe9\x00\xf7\'\x13\x02\x03\xf4\x00\x13\x02\x03\xf1*)\x02\x03\xefR\x01\xe9\x00\xf7S\x01)\x02\x03\xf7\x00)\x02\x03\xf3\x00)\x02\x03\xf0\n\x00\x1a\x1e\xf0\x0b)\x02\x03\xefR\x01\xe9\x00\xf7S\x01)\x02\x03\xf4\x00)\x02\x03\xf0X\x01\x02\x02\x05\xf1\x08\x00\r\x1f\xd3\x0c \x80T\xd8\x05\t\x87Y\x81Y\x85[r\x1c\x00\x00\x00') -# BBs = create_BBs(instructions) -# print(BBs) - -# cfg = create_cfg(BBs) -# print("\nControl Flow Graph (CFG):") -# print(cfg) - -# # Visualize CFG -# dot = visualize_cfg(cfg) -# dot.render('cfg.gv', view=True) \ No newline at end of file +if __name__ == "__main__": + # Sample list of instructions for processing + ##simple= + #instructions = disassemble_bytecode(b'c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x01\xf3*\x00\x00\x00\x97\x00d\x00d\x01l\x00m\x01Z\x01\x01\x00d\x00Z\x02d\x00Z\x03e\x03d\x00k\\\x00\x00r\x02d\x02Z\x02d\x03Z\x02y\x04)\x05\xe9\x00\x00\x00\x00)\x01\xda\x0bannotations\xe9\x01\x00\x00\x00\xe9\xff\xff\xff\xffN)\x04\xda\n__future__r\x02\x00\x00\x00\xda\x01a\xda\x01x\xa9\x00\xf3\x00\x00\x00\x00\xfaP/Users/jakobtherkelsen/Documents/jaseci-ginS/jac/examples/ginsScripts/simple.jac\xfa\x08r\x0b\x00\x00\x00\x01\x00\x00\x00s%\x00\x00\x00\xf0\x03\x01\x01\x01\xf5\x02\x07\x02\x03\xd8\x05\x06\x801\xd8\x05\x06\x801\xd8\x06\x07\x881\x82f\xd8\x07\x08\x80Q\xe0\x05\x07\x811r\t\x00\x00\x00') + #hot path + instructions = disassemble_bytecode(b'c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x01\xf3\xa4\x00\x00\x00\x97\x00U\x00d\x00d\x01l\x00m\x01Z\x01\x01\x00d\x00Z\x02d\x02e\x03d\x03<\x00\x00\x00d\x04Z\x04d\x02e\x03d\x05<\x00\x00\x00e\x02e\x04z\x00\x00\x00Z\x05d\x02e\x03d\x06<\x00\x00\x00\x02\x00e\x06d\x04\xab\x01\x00\x00\x00\x00\x00\x00D\x00]\x1c\x00\x00Z\x07e\x02d\x07z\x06\x00\x00r\ne\x04e\x02z\x00\x00\x00Z\x04e\x02e\x04z\x00\x00\x00Z\x05d\x08e\x07z\x05\x00\x00e\x04e\x05z\x05\x00\x00z\x00\x00\x00Z\x02\x8c\x1e\x04\x00d\tZ\x05e\x05d\tk(\x00\x00r\x03d\x08Z\x05y\ny\n)\x0b\xe9\x00\x00\x00\x00)\x01\xda\x0bannotations\xda\x03int\xda\x01x\xe9\x03\x00\x00\x00\xda\x01y\xda\x01z\xe9\x02\x00\x00\x00\xe9\x04\x00\x00\x00\xe9\n\x00\x00\x00N)\x08\xda\n__future__r\x02\x00\x00\x00r\x04\x00\x00\x00\xda\x0f__annotations__r\x06\x00\x00\x00r\x07\x00\x00\x00\xda\x05range\xda\x01i\xa9\x00\xf3\x00\x00\x00\x00\xfaU/Users/jakobtherkelsen/Documents/jaseci-ginS/jac/examples/gins_scripts/simple_for.jac\xda\x08r\x12\x00\x00\x00\x01\x00\x00\x00sy\x00\x00\x00\xf0\x03\x01\x01\x01\xf6\x02\x0f\x02\x03\xd8\r\x0e\x80Q\x80s\x83Z\xd8\r\x0e\x80Q\x80s\x83Z\xd8\r\x0e\x90\x11\x89U\x80Q\x80s\x83^\xd9\x0e\x13\x90A\x8eh\x88\x11\xd8\n\x0b\x88a\x8a%\xd8\r\x0e\x90\x11\x89U\x88\x11\xd8\r\x0e\x90\x11\x89U\x88\x11\xe0\x0b\x0c\x88q\x895\x901\x98\x01\x917\x89?\x81q\xf0\x0b\x00\x0f\x17\xf0\x0e\x00\n\x0c\x80Q\xd8\x08\t\x88R\x8a\x07\xd8\n\x0b\x81q\xf0\x03\x00\t\x10r\x10\x00\x00\x00') + BBs = create_BBs(instructions) + print(BBs) + + cfg = create_cfg(BBs) + print("\nControl Flow Graph (CFG):") + print(cfg) + + # Visualize CFG + dot = visualize_cfg(cfg) + dot.render('cfg.gv', view=True) \ No newline at end of file From a8e4133b8a4841b0a1c69dcc0abdc8bbec65f0b0 Mon Sep 17 00:00:00 2001 From: jayanaka-98 Date: Tue, 26 Nov 2024 12:06:12 -0500 Subject: [PATCH 57/84] update prompt --- jac/jaclang/runtimelib/gins/ghost.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jac/jaclang/runtimelib/gins/ghost.py b/jac/jaclang/runtimelib/gins/ghost.py index ef70c93c47..1d30ba0fc6 100644 --- a/jac/jaclang/runtimelib/gins/ghost.py +++ b/jac/jaclang/runtimelib/gins/ghost.py @@ -73,7 +73,7 @@ def prompt_llm(self, verbose: bool = False): self.finished_exception_lock.release() prompt += "\nCan you identity bottlneck optimizations or where the code can error out?" - prompt += "\n(Reason about the program using bytecode, cfg, semantic and type information to infer the source code indirectly)" + prompt += "\n(Reason about the program using cfg, semantic and type information. Do not include python code fixes or bytecode in response.)" if verbose: print(prompt) From 388f7b4aad18bebb4cc28e9ab5c23b9eb7d5b56e Mon Sep 17 00:00:00 2001 From: Jakob Louis Therkelsen Date: Wed, 27 Nov 2024 17:01:53 -0500 Subject: [PATCH 58/84] deque and history of cfg updates --- jac/examples/gins_scripts/cfg.gv | 15 +-- jac/examples/gins_scripts/cfg.gv.pdf | Bin 13177 -> 12051 bytes jac/examples/gins_scripts/hot_path.jac | 2 +- jac/examples/gins_scripts/simple_for.jac | 25 ++--- .../compiler/passes/main/cfg_gen_pass.py | 6 +- jac/jaclang/runtimelib/gins/cfg.py | 7 +- jac/jaclang/runtimelib/gins/ghost.py | 95 +++++++++++------- jac/jaclang/runtimelib/gins/tracer.py | 57 +---------- 8 files changed, 84 insertions(+), 123 deletions(-) diff --git a/jac/examples/gins_scripts/cfg.gv b/jac/examples/gins_scripts/cfg.gv index d5a088b0e3..677f5b02e7 100644 --- a/jac/examples/gins_scripts/cfg.gv +++ b/jac/examples/gins_scripts/cfg.gv @@ -8,21 +8,14 @@ digraph { bb5 [label=BB5] bb6 [label=BB6] bb7 [label=BB7] - bb8 [label=BB8] - bb9 [label=BB9] - bb10 [label=BB10] + bb0 -> bb7 bb0 -> bb1 + bb1 -> bb3 bb1 -> bb2 - bb1 -> bb7 bb2 -> bb4 - bb2 -> bb3 - bb3 -> bb1 + bb3 -> bb4 bb4 -> bb6 bb4 -> bb5 bb5 -> bb1 - bb6 -> bb1 - bb7 -> bb9 - bb7 -> bb8 - bb8 -> bb10 - bb9 -> bb10 + bb6 -> bb7 } diff --git a/jac/examples/gins_scripts/cfg.gv.pdf b/jac/examples/gins_scripts/cfg.gv.pdf index 7a5133769502c3d23c9e533bb6e1fd7e47fd94bf..9e44a974bdd78a2f83a0441e9dd70d3de98e06bc 100644 GIT binary patch delta 10740 zcmVR zNR4K0J+Xa*z>YK`DT;?Yq&X7)-7$XUR^#O<{1wQ*{rXdU|2xGm{{)Wz;@b!O{24xe zij*k+5t!o7QKY2GEtVdi_DyYRWRAj`xb_IEJX-2BY?C4c4Y8*a2o2VcX?#TU6J zDq|PTw41>4vYW3vtmoBafwWv8l?W`>R}X0R1hJO)WwXpmZ&3{m=KT>AN@;l z5lSM8FJHq+?LG+2uw?e^T|1fS%VS0~tL5p8wXG5BI)72{lLF9ol_GBJGFP-E@e(IG z43R^-uE1`)KJ04O-rWvb-9gK8ODeY$Xm&3_AE4#RUePk<+v}r!-O81iGOj^xNY>QxYL(_7S{?g&&B4UsgH(wMuUL#*ICaGyX>Yy>A)^Mw zM@|)L-+xXWp_-H{q^jd(m0Dq^BIulI6J!cpO)?r}BvBR5owMG37?XB{ESJ^>UfFq{ z>;$Kc-TcvFc$dj$wlU_K(!tkcMeH;uj{YW!tX(E-d0D1yvt7D0#zuV8)Q$O4cH(o` z-%J-d*LdNCngUG$z-%D}S(G-ZYFJfjl5+5#xqqov>v;TgPj{on^^LvMD=UnGH!8Bk z_(OXGD4+}w2e)pQ8b&9T`(Rfd811_aB;&V*5@)`GiKXs1F(dzW70z3DZM6cw#0`^W zXo9t_@RNCcIMlAZyS=_;d>>$X2FzNVT8C+imCJBeW@LlYa;Z+sT+8HTB%||k)7N+z zT7OQkEpNP>$K+)+@r{@9#d*2O!OPFpfLqzhsd+xF9a4XG#;v-B^~J5c#sp=nFFPR$ zhl=rQb3|-a^8{dtmwFf~PVnmrJ1MKKmfDqfx8ue~p`iu5jaxq9hUVA>K5g8z8Spk3(U>x36ZyBs;9c8wT_M&$X9&8sCFtWN;P6clj;}&;M zZNQn`!$jS^lNvfbSI10qwT8BKrOZJUk2JW^Ymlsc^&KBY)lG(8KnT{?TjjCCIDGkeaoONr7(u3VYrN8Ic3CP z+@;_@PpXRC!|PS}wXAC7y;PB@*3zH6wkz@iulFwf=+vUazNk+b4%|r(nU&=VxP7-! z0Q@^}oUed`{|mRi%LiY3kZrL=e}9P@X3K_Swp*8e+&q;+ymst%%rJX?7iRU0ndIaw zf-bU^8bT;CF|$$wHa16Liu6j8Ss@r-Ua2&gu)0zPm9QHH20m|DZ=-66S(4`B1KZH8 z)J}Rp40*3MnTgHdYv{M8jj0MKcy9!8WG4ec7w{&2^i0g|y{r8_h>L81K!2ha@0T!B z)xV?nd2(j$FD4=WhN#f4cz^R8oRnid$Y}G?@2$@8`w(%`!h4Xj4p>EJ&vU@B*P;p_ z%u>8)@~~MHKs0rG_P=6A=`YTrc13e3Fzc)mYqu;ui&FKNTdT2{WA3!6*Ihj6-G^Vo ze|h^9e+p%8WOHUsz0|9^#=mZ9G)5?bCcdtIN z9>DAbptVhF+U0+tocFH)gm(hy-d)tZc;&wzOvD+V``CFJTKu0K)EE zvan&nWsmbg0Q)ZFjah<>h`$-KvHTjAol91>-|5~dBx3n5SWa89s;L2>8nbc~qRf>I zcQ#9pNzY+f<;>>Rh0TQ@zh=U$564silq3L%2_oQVbufRmhmuqDMUX&8PX|C0`sjo_BMN9EJvyvQceO*m?OCD<1$Bcfu*7#LKV6N3Wx>-CU9nm zDLfwpA`3+5BX6p%Oer#w&dCfln>jX_5GPyAVP*@RW0rZ*ysxn61@b01pn+I%{oT{P zbh|xM2i

^|}^!T}xR_Ka6HspT%or(CdG;csw4COUsg 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%0AyrW<|RegN=e2ap}%8@ZOAt6KK*G$$tsgV@> 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 None: BBs = create_BBs(instructions) cfg = create_cfg(BBs) module_cfgs[mod.name] = cfg - for cfg in module_cfgs.values(): - dot = visualize_cfg(cfg) - dot.render('cfg.gv', view=True) + # for cfg in module_cfgs.values(): + # dot = visualize_cfg(cfg) + # dot.render('cfg.gv', view=True) if JacMachine.get().gin: try: JacMachine.get().gin.set_cfgs(cfgs=module_cfgs) diff --git a/jac/jaclang/runtimelib/gins/cfg.py b/jac/jaclang/runtimelib/gins/cfg.py index ab2ba7a044..ef57c4670b 100644 --- a/jac/jaclang/runtimelib/gins/cfg.py +++ b/jac/jaclang/runtimelib/gins/cfg.py @@ -175,14 +175,17 @@ def add_edge(self, from_node, to_node): def display_instructions(self): return repr(self.block_map) + + def get_cfg_repr(self): + return self.__repr__() def __repr__(self): result = [] for node in self.nodes: - result.append(f'Node bb{node} (exec count={self.block_map.idx_to_block[node].exec_count}):') + result.append(f'Node bb{node} (freq={self.block_map.idx_to_block[node].exec_count}):') if node in self.edges and self.edges[node]: for succ in self.edges[node]: - result.append(f' -> bb{succ} (edge exec count={self.edge_counts[(node, succ)]})') + result.append(f'(freq={self.edge_counts[(node, succ)]})-> bb{succ}') return "\n".join(result) def create_cfg(block_map: BlockMap) -> CFG: diff --git a/jac/jaclang/runtimelib/gins/ghost.py b/jac/jaclang/runtimelib/gins/ghost.py index 1d30ba0fc6..b941e13aa6 100644 --- a/jac/jaclang/runtimelib/gins/ghost.py +++ b/jac/jaclang/runtimelib/gins/ghost.py @@ -2,6 +2,7 @@ import os import threading import time +from collections import deque from jaclang.runtimelib.gins.tracer import CFGTracker @@ -10,6 +11,25 @@ except Exception as e: print("google.generativeai module not present. Please install using 'pip install google.generativeai'.") +# Helper class to maintain a fixed deque size +class CfgDeque(): + def __init__(self, max_size:int=10): + self.__max_size = max_size + self.__deque = deque() + + def add_cfg(self, cfg_repr:str): + self.__deque.append(cfg_repr) + if len(self.__deque) > self.__max_size: + self.__deque.popleft() + + def display_cfgs(self): + print("CFG change over updates\n") + for cfg in self.__deque: + print("\n") + print(cfg) + + + class ShellGhost: def __init__(self): self.cfgs = None @@ -25,6 +45,9 @@ def __init__(self): genai.configure(api_key=os.getenv("GEMINI_API_KEY")) self.model = genai.GenerativeModel("gemini-1.5-flash") + self.deque_lock = threading.Lock() + self.__cfg_deque = CfgDeque(2) + def set_cfgs(self, cfgs): self.cfg_cv.acquire() @@ -32,6 +55,14 @@ def set_cfgs(self, cfgs): self.cfg_cv.notify() self.cfg_cv.release() + def update_cfg_deque(self,cfg): + self.deque_lock.acquire() + self.__cfg_deque.add_cfg(cfg) + self.deque_lock.release() + + def get_cfg_deque_repr(self): + return self.__cfg_deque.display_cfgs() + def start_ghost(self): self.__ghost_thread = threading.Thread(target=self.worker) self.__ghost_thread.start() @@ -44,12 +75,12 @@ def set_finished(self, exception: Exception = None): def prompt_llm(self, verbose: bool = False): prompt = """I have a program. -CFGS: -{cfgs}, -Instructions per basic block: -{instructions} -Semantic and Type information from source code: -{sem_ir}""" + CFGS: + {cfgs}, + Instructions per basic block: + {instructions} + Semantic and Type information from source code: + {sem_ir}""" cfg_string = "" ins_string = "" @@ -83,10 +114,10 @@ def prompt_llm(self, verbose: bool = False): print(response.text) def worker(self): - # get static cfgs self.cfg_cv.acquire() - while (self.cfgs == None): + if self.cfgs == None: + print("waiting") self.cfg_cv.wait() # print(self.cfgs) # for module_name, cfg in self.cfgs.items(): @@ -94,15 +125,15 @@ def worker(self): self.cfg_cv.release() # Once cv has been notifie, self.cfgs is no longer accessed across threads - - current_executing_bbs = {} def update_cfg(): exec_insts = self.tracker.get_exec_inst() # don't prompt if there's nothing new - if exec_insts == {}: return + if exec_insts == {}: + return + for module, offset_list in exec_insts.items(): try: cfg = self.cfgs[module] @@ -113,12 +144,12 @@ def update_cfg(): for offset in offset_list: if offset not in cfg.block_map.idx_to_block[current_executing_bbs[module]].bytecode_offsets: - for next in cfg.edges[current_executing_bbs[module]]: - if offset in cfg.block_map.idx_to_block[next].bytecode_offsets: - cfg.edge_counts[(current_executing_bbs[module], next)] += 1 - cfg.block_map.idx_to_block[next].exec_count += 1 - - current_executing_bbs[module] = next + for next_bb in cfg.edges[current_executing_bbs[module]]: + if offset in cfg.block_map.idx_to_block[next_bb].bytecode_offsets: + cfg.edge_counts[(current_executing_bbs[module], next_bb)] += 1 + #do some deque op + cfg.block_map.idx_to_block[next_bb].exec_count += 1 + current_executing_bbs[module] = next_bb break assert(offset in cfg.block_map.idx_to_block[current_executing_bbs[module]].bytecode_offsets) except Exception as e: @@ -127,38 +158,24 @@ def update_cfg(): return self.variable_values = self.tracker.get_variable_values() + self.update_cfg_deque(cfg.get_cfg_repr()) + print(self.get_cfg_deque_repr()) + self.finished_exception_lock.acquire() while (not self.finished): self.finished_exception_lock.release() - time.sleep(5) + time.sleep(1) print('\nUpdating cfgs') update_cfg() - self.prompt_llm() + # self.prompt_llm() self.finished_exception_lock.acquire() self.finished_exception_lock.release() - # print(self.cfgs) - # self.finished_exception_lock.acquire() - # if self.exception: - # print("Exception occured:", self.exception) - # self.finished_exception_lock.release() print('\nUpdating cfgs at the end') update_cfg() - self.prompt_llm() - - # response_dict = {'cfg': self.cfgs, 'instructions': self.cfgs[module_name].display_instructions(), 'list of local variables at sequential line numbers': variables_by_line} - # prompt = [] - # for k,v in response_dict.items(): - # prompt.append(f"here is my {k}:\n{v}") - # prompt.append("\nCan you identify where the code could have an error?") - # response = model.generate_content("".join(prompt)) - - # print("PROMPT:\n") - # print("".join(prompt)) - # print("RESPONSE:\n") - # print(response.text) - - # print(self.cfgs['hot_path'].display_instructions()) \ No newline at end of file + # print(self.cfgs['hot_path'].display_instructions()) + # self.prompt_llm() + \ No newline at end of file diff --git a/jac/jaclang/runtimelib/gins/tracer.py b/jac/jaclang/runtimelib/gins/tracer.py index cbb2a152a4..9d50012f74 100644 --- a/jac/jaclang/runtimelib/gins/tracer.py +++ b/jac/jaclang/runtimelib/gins/tracer.py @@ -23,7 +23,6 @@ def stop_tracking(self): sys.settrace(None) def get_exec_inst(self): - self.inst_lock.acquire() cpy = copy.deepcopy(self.executed_insts) self.executed_insts = {} @@ -34,6 +33,7 @@ def get_exec_inst(self): def get_variable_values(self): self.curr_variables_lock.acquire() cpy = copy.deepcopy(self.curr_variables) + print(cpy) self.curr_variables_lock.release() return cpy @@ -42,31 +42,14 @@ def get_variable_values(self): def trace_callback(self, frame: types.FrameType, event: str, arg: any) -> Optional[Callable]: if event == "call": frame.f_trace_opcodes = True - # frame.f_trace_lines = False - # def tracefunc(frame, event, arg): - # if event == 'call': - # frame.f_trace_opcodes = True - # elif event == 'opcode': - # if frame.f_code.co_code[frame.f_lasti] == dis.opmap['MAKE_FUNCTION']: - # makefunctiontracefunc(frame) - # return tracefunc """Trace function to track executed branches""" code = frame.f_code if ".jac" not in code.co_filename: return self.trace_callback - - - # if event != 'line': - # return self.trace_callback - if event == 'opcode': - # print(frame.f_lasti) - - # print(frame.f_lineno, frame.f_lasti) - - #edge case to handle executing code not within a function + #edge case to handle executing code not within a function filename = os.path.basename(code.co_filename) module = code.co_name if code.co_name != "" else os.path.splitext(filename)[0] @@ -83,40 +66,4 @@ def trace_callback(self, frame: types.FrameType, event: str, arg: any) -> Option self.curr_variables[module] = (frame.f_lasti, variable_dict) self.curr_variables_lock.release() - # self.variable_values[code.co_name][frame.f_lineno] = {} - - - # print(f"{frame.f_lineno}") - # print(f"Function Name: {code.co_name}") - # print(f"Filename: {code.co_filename}") - # print(f"First Line Number: {code.co_firstlineno}") - # print(f"Argument Count: {code.co_argcount}") - # print(f"Constants: {code.co_consts}") - # print(f"Local Variables: {code.co_varnames}") - - # if event != 'line': - # return self.trace_callback - - # code = frame.f_code - # if code not in self.cfg_cache: - # self.build_cfg(code) - - # # Find current basic block - # blocks = self.cfg_cache[code] - # current_offset = frame.f_lasti - - # # Find the block containing this offset - # current_block = None - # for block in blocks.values(): - # if block.offset <= current_offset <= block.offset + sum(inst.size for inst in block.instructions): - # current_block = block - # break - - # if current_block: - # current_block.hits += 1 - # # Record taken branches - # for next_block in current_block.next: - # self.coverage_data[code].add( - # (current_block.offset, next_block.offset)) - return self.trace_callback \ No newline at end of file From 412d6bbe00264725573aa7d1997cd9a8e987e3cf Mon Sep 17 00:00:00 2001 From: Jayanaka-98 Date: Wed, 27 Nov 2024 23:04:28 -0500 Subject: [PATCH 59/84] black formatting --- jac/jaclang/runtimelib/gins/cfg.py | 130 ++++++++++++++++--------- jac/jaclang/runtimelib/gins/ghost.py | 132 +++++++++++++++----------- jac/jaclang/runtimelib/gins/tracer.py | 39 ++++---- 3 files changed, 185 insertions(+), 116 deletions(-) diff --git a/jac/jaclang/runtimelib/gins/cfg.py b/jac/jaclang/runtimelib/gins/cfg.py index ef57c4670b..fa52ac7733 100644 --- a/jac/jaclang/runtimelib/gins/cfg.py +++ b/jac/jaclang/runtimelib/gins/cfg.py @@ -2,6 +2,7 @@ This pass generates a control flow graph from the bytecode generated by the previous pass. """ + import marshal import dis from collections import defaultdict @@ -9,19 +10,29 @@ import graphviz from graphviz import Digraph + class BytecodeOp: - def __init__(self, op: int, arg: int, offset: int, argval:int, argrepr:str, is_jump_target: bool) -> None: + def __init__( + self, + op: int, + arg: int, + offset: int, + argval: int, + argrepr: str, + is_jump_target: bool, + ) -> None: self.op = op self.arg = arg self.offset = offset self.argval = argval self.argrepr = argrepr - self.is_jump_target= is_jump_target - #default the offset + self.is_jump_target = is_jump_target + # default the offset self.__offset_size = 0 def __repr__(self): return f"Instr: offset={self.offset}, Opname={self.op}, arg={self.arg}, argval={self.argval}, argrepr={self.argrepr}, jump_t={self.is_jump_target}" + def is_branch(self) -> bool: return self.op in { "JUMP_ABSOLUTE", @@ -32,6 +43,7 @@ def is_branch(self) -> bool: "JUMP_IF_TRUE_OR_POP", "JUMP_IF_FALSE_OR_POP", } + def is_conditional_branch(self) -> bool: return self.op in { # TODO:These may not be used anymore? @@ -40,39 +52,43 @@ def is_conditional_branch(self) -> bool: "POP_JUMP_IF_TRUE", "POP_JUMP_IF_FALSE", } - + def is_relative_branch(self) -> bool: return False + def is_return(self) -> bool: return self.op == "RETURN_VALUE" def is_raise(self) -> bool: return self.op == "RAISE_VARARGS" - + def is_for_iter(self) -> bool: return self.op == "FOR_ITER" - + def set_offset_size(self, size) -> None: self.__offset_size = size def get_offset_size(self) -> int: return self.__offset_size - + def get_next_instruction_offset(self) -> int: return self.__offset_size + self.offset + class Block: def __init__(self, id: int, instructions: List): self.id: int = id self.instructions = instructions self.exec_count = 0 # Potentially use offset instead - self.bytecode_offsets = set([instr.offset for instr in self.instructions if instr.offset != None]) - - + self.bytecode_offsets = set( + [instr.offset for instr in self.instructions if instr.offset != None] + ) + def __repr__(self): - instructions = "\n".join([str(instr) for instr in self.instructions]) - return f"bb{self.id}:\n{instructions}" + instructions = "\n".join([str(instr) for instr in self.instructions]) + return f"bb{self.id}:\n{instructions}" + class BlockMap: def __init__(self) -> None: @@ -84,35 +100,40 @@ def add_block(self, idx, block): def __repr__(self) -> str: result = [] for block in self.idx_to_block.values(): - result.append(repr(block)) + result.append(repr(block)) return "\n".join(result) + def __str__(self) -> str: return self.__repr__() + def disassemble_bytecode(bytecode): code_object = marshal.loads(bytecode) instructions = [] for i, instr in enumerate(dis.get_instructions(code_object)): - instructions.append(BytecodeOp( - op = instr.opname, - arg=instr.arg, - offset=instr.offset, - argval=instr.argval, - argrepr=instr.argrepr, - is_jump_target=instr.is_jump_target, - )) - #set offest size for calculating next instruction - #last instruction is default of 0, but shouldn't be needed + instructions.append( + BytecodeOp( + op=instr.opname, + arg=instr.arg, + offset=instr.offset, + argval=instr.argval, + argrepr=instr.argrepr, + is_jump_target=instr.is_jump_target, + ) + ) + # set offest size for calculating next instruction + # last instruction is default of 0, but shouldn't be needed if i != 0: - instruction = instructions[i-1] - instruction.set_offset_size(instr.offset - instructions[i-1].offset) + instruction = instructions[i - 1] + instruction.set_offset_size(instr.offset - instructions[i - 1].offset) return instructions + def create_BBs(instructions: List[BytecodeOp]) -> BlockMap: block_starts = set([0]) block_map = BlockMap() num_instr = len(instructions) - + # Create offset to index mapping offset_to_index = {instr.offset: idx for idx, instr in enumerate(instructions)} max_offset = instructions[-1].get_next_instruction_offset() @@ -134,12 +155,16 @@ def valid_offset(offset): if valid_offset(target_offset): block_starts.add(target_offset) - - #identify the blocks, since we define BBs by jumps, a sorted list of those - #instructions give a range for instructions each BB will hold + + # identify the blocks, since we define BBs by jumps, a sorted list of those + # instructions give a range for instructions each BB will hold block_starts_ordered = sorted(block_starts) for block_id, start_offset in enumerate(block_starts_ordered): - end_offset = block_starts_ordered[block_id + 1] if block_id + 1 < len(block_starts_ordered) else instructions[-1].get_next_instruction_offset() + end_offset = ( + block_starts_ordered[block_id + 1] + if block_id + 1 < len(block_starts_ordered) + else instructions[-1].get_next_instruction_offset() + ) start_index = offset_to_index[start_offset] end_index = offset_to_index[end_offset] @@ -154,7 +179,7 @@ def valid_offset(offset): class CFG: - def __init__(self, block_map:BlockMap): + def __init__(self, block_map: BlockMap): self.nodes = set() self.edges = {} self.edge_counts = {} @@ -170,30 +195,33 @@ def add_edge(self, from_node, to_node): self.edges[from_node].append(to_node) else: self.edges[from_node] = to_node - + self.edge_counts[(from_node, to_node)] = 0 def display_instructions(self): return repr(self.block_map) def get_cfg_repr(self): - return self.__repr__() - + return self.__repr__() + def __repr__(self): result = [] for node in self.nodes: - result.append(f'Node bb{node} (freq={self.block_map.idx_to_block[node].exec_count}):') + result.append( + f"Node bb{node} (freq={self.block_map.idx_to_block[node].exec_count}):" + ) if node in self.edges and self.edges[node]: for succ in self.edges[node]: - result.append(f'(freq={self.edge_counts[(node, succ)]})-> bb{succ}') + result.append(f"(freq={self.edge_counts[(node, succ)]})-> bb{succ}") return "\n".join(result) - + + def create_cfg(block_map: BlockMap) -> CFG: cfg = CFG(block_map) for block_id, block in block_map.idx_to_block.items(): cfg.add_node(block_id) - + first_instr = block.instructions[0] last_instr = block.instructions[-1] if first_instr.is_for_iter(): @@ -210,8 +238,12 @@ def create_cfg(block_map: BlockMap) -> CFG: if target_block is not None: cfg.add_edge(block_id, target_block) if last_instr.is_conditional_branch(): - fall_through_offset = block.instructions[-1].get_next_instruction_offset() - fall_through_block = find_block_by_offset(block_map, fall_through_offset) + fall_through_offset = block.instructions[ + -1 + ].get_next_instruction_offset() + fall_through_block = find_block_by_offset( + block_map, fall_through_offset + ) if fall_through_block is not None: cfg.add_edge(block_id, fall_through_block) @@ -219,17 +251,22 @@ def create_cfg(block_map: BlockMap) -> CFG: else: fall_through_offset = block.instructions[-1].get_next_instruction_offset() fall_through_block = find_block_by_offset(block_map, fall_through_offset) - if fall_through_block is not None and fall_through_offset != last_instr.offset: + if ( + fall_through_block is not None + and fall_through_offset != last_instr.offset + ): cfg.add_edge(block_id, fall_through_block) return cfg + def find_block_by_offset(block_map: BlockMap, offset: int) -> int: for block_id, block in block_map.idx_to_block.items(): if any(instr.offset == offset for instr in block.instructions): return block_id return None + # Function to visualize CFG using Graphviz def visualize_cfg(cfg: CFG): dot = Digraph(comment="Control Flow Graph") @@ -240,12 +277,15 @@ def visualize_cfg(cfg: CFG): dot.edge(f"bb{from_node}", f"bb{to_node}") return dot + if __name__ == "__main__": # Sample list of instructions for processing ##simple= - #instructions = disassemble_bytecode(b'c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x01\xf3*\x00\x00\x00\x97\x00d\x00d\x01l\x00m\x01Z\x01\x01\x00d\x00Z\x02d\x00Z\x03e\x03d\x00k\\\x00\x00r\x02d\x02Z\x02d\x03Z\x02y\x04)\x05\xe9\x00\x00\x00\x00)\x01\xda\x0bannotations\xe9\x01\x00\x00\x00\xe9\xff\xff\xff\xffN)\x04\xda\n__future__r\x02\x00\x00\x00\xda\x01a\xda\x01x\xa9\x00\xf3\x00\x00\x00\x00\xfaP/Users/jakobtherkelsen/Documents/jaseci-ginS/jac/examples/ginsScripts/simple.jac\xfa\x08r\x0b\x00\x00\x00\x01\x00\x00\x00s%\x00\x00\x00\xf0\x03\x01\x01\x01\xf5\x02\x07\x02\x03\xd8\x05\x06\x801\xd8\x05\x06\x801\xd8\x06\x07\x881\x82f\xd8\x07\x08\x80Q\xe0\x05\x07\x811r\t\x00\x00\x00') - #hot path - instructions = disassemble_bytecode(b'c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x01\xf3\xa4\x00\x00\x00\x97\x00U\x00d\x00d\x01l\x00m\x01Z\x01\x01\x00d\x00Z\x02d\x02e\x03d\x03<\x00\x00\x00d\x04Z\x04d\x02e\x03d\x05<\x00\x00\x00e\x02e\x04z\x00\x00\x00Z\x05d\x02e\x03d\x06<\x00\x00\x00\x02\x00e\x06d\x04\xab\x01\x00\x00\x00\x00\x00\x00D\x00]\x1c\x00\x00Z\x07e\x02d\x07z\x06\x00\x00r\ne\x04e\x02z\x00\x00\x00Z\x04e\x02e\x04z\x00\x00\x00Z\x05d\x08e\x07z\x05\x00\x00e\x04e\x05z\x05\x00\x00z\x00\x00\x00Z\x02\x8c\x1e\x04\x00d\tZ\x05e\x05d\tk(\x00\x00r\x03d\x08Z\x05y\ny\n)\x0b\xe9\x00\x00\x00\x00)\x01\xda\x0bannotations\xda\x03int\xda\x01x\xe9\x03\x00\x00\x00\xda\x01y\xda\x01z\xe9\x02\x00\x00\x00\xe9\x04\x00\x00\x00\xe9\n\x00\x00\x00N)\x08\xda\n__future__r\x02\x00\x00\x00r\x04\x00\x00\x00\xda\x0f__annotations__r\x06\x00\x00\x00r\x07\x00\x00\x00\xda\x05range\xda\x01i\xa9\x00\xf3\x00\x00\x00\x00\xfaU/Users/jakobtherkelsen/Documents/jaseci-ginS/jac/examples/gins_scripts/simple_for.jac\xda\x08r\x12\x00\x00\x00\x01\x00\x00\x00sy\x00\x00\x00\xf0\x03\x01\x01\x01\xf6\x02\x0f\x02\x03\xd8\r\x0e\x80Q\x80s\x83Z\xd8\r\x0e\x80Q\x80s\x83Z\xd8\r\x0e\x90\x11\x89U\x80Q\x80s\x83^\xd9\x0e\x13\x90A\x8eh\x88\x11\xd8\n\x0b\x88a\x8a%\xd8\r\x0e\x90\x11\x89U\x88\x11\xd8\r\x0e\x90\x11\x89U\x88\x11\xe0\x0b\x0c\x88q\x895\x901\x98\x01\x917\x89?\x81q\xf0\x0b\x00\x0f\x17\xf0\x0e\x00\n\x0c\x80Q\xd8\x08\t\x88R\x8a\x07\xd8\n\x0b\x81q\xf0\x03\x00\t\x10r\x10\x00\x00\x00') + # instructions = disassemble_bytecode(b'c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x01\xf3*\x00\x00\x00\x97\x00d\x00d\x01l\x00m\x01Z\x01\x01\x00d\x00Z\x02d\x00Z\x03e\x03d\x00k\\\x00\x00r\x02d\x02Z\x02d\x03Z\x02y\x04)\x05\xe9\x00\x00\x00\x00)\x01\xda\x0bannotations\xe9\x01\x00\x00\x00\xe9\xff\xff\xff\xffN)\x04\xda\n__future__r\x02\x00\x00\x00\xda\x01a\xda\x01x\xa9\x00\xf3\x00\x00\x00\x00\xfaP/Users/jakobtherkelsen/Documents/jaseci-ginS/jac/examples/ginsScripts/simple.jac\xfa\x08r\x0b\x00\x00\x00\x01\x00\x00\x00s%\x00\x00\x00\xf0\x03\x01\x01\x01\xf5\x02\x07\x02\x03\xd8\x05\x06\x801\xd8\x05\x06\x801\xd8\x06\x07\x881\x82f\xd8\x07\x08\x80Q\xe0\x05\x07\x811r\t\x00\x00\x00') + # hot path + instructions = disassemble_bytecode( + b"c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x01\xf3\xa4\x00\x00\x00\x97\x00U\x00d\x00d\x01l\x00m\x01Z\x01\x01\x00d\x00Z\x02d\x02e\x03d\x03<\x00\x00\x00d\x04Z\x04d\x02e\x03d\x05<\x00\x00\x00e\x02e\x04z\x00\x00\x00Z\x05d\x02e\x03d\x06<\x00\x00\x00\x02\x00e\x06d\x04\xab\x01\x00\x00\x00\x00\x00\x00D\x00]\x1c\x00\x00Z\x07e\x02d\x07z\x06\x00\x00r\ne\x04e\x02z\x00\x00\x00Z\x04e\x02e\x04z\x00\x00\x00Z\x05d\x08e\x07z\x05\x00\x00e\x04e\x05z\x05\x00\x00z\x00\x00\x00Z\x02\x8c\x1e\x04\x00d\tZ\x05e\x05d\tk(\x00\x00r\x03d\x08Z\x05y\ny\n)\x0b\xe9\x00\x00\x00\x00)\x01\xda\x0bannotations\xda\x03int\xda\x01x\xe9\x03\x00\x00\x00\xda\x01y\xda\x01z\xe9\x02\x00\x00\x00\xe9\x04\x00\x00\x00\xe9\n\x00\x00\x00N)\x08\xda\n__future__r\x02\x00\x00\x00r\x04\x00\x00\x00\xda\x0f__annotations__r\x06\x00\x00\x00r\x07\x00\x00\x00\xda\x05range\xda\x01i\xa9\x00\xf3\x00\x00\x00\x00\xfaU/Users/jakobtherkelsen/Documents/jaseci-ginS/jac/examples/gins_scripts/simple_for.jac\xda\x08r\x12\x00\x00\x00\x01\x00\x00\x00sy\x00\x00\x00\xf0\x03\x01\x01\x01\xf6\x02\x0f\x02\x03\xd8\r\x0e\x80Q\x80s\x83Z\xd8\r\x0e\x80Q\x80s\x83Z\xd8\r\x0e\x90\x11\x89U\x80Q\x80s\x83^\xd9\x0e\x13\x90A\x8eh\x88\x11\xd8\n\x0b\x88a\x8a%\xd8\r\x0e\x90\x11\x89U\x88\x11\xd8\r\x0e\x90\x11\x89U\x88\x11\xe0\x0b\x0c\x88q\x895\x901\x98\x01\x917\x89?\x81q\xf0\x0b\x00\x0f\x17\xf0\x0e\x00\n\x0c\x80Q\xd8\x08\t\x88R\x8a\x07\xd8\n\x0b\x81q\xf0\x03\x00\t\x10r\x10\x00\x00\x00" + ) BBs = create_BBs(instructions) print(BBs) @@ -255,4 +295,4 @@ def visualize_cfg(cfg: CFG): # Visualize CFG dot = visualize_cfg(cfg) - dot.render('cfg.gv', view=True) \ No newline at end of file + dot.render("cfg.gv", view=True) diff --git a/jac/jaclang/runtimelib/gins/ghost.py b/jac/jaclang/runtimelib/gins/ghost.py index b941e13aa6..9edd5769b1 100644 --- a/jac/jaclang/runtimelib/gins/ghost.py +++ b/jac/jaclang/runtimelib/gins/ghost.py @@ -1,4 +1,5 @@ """The Shell Ghost code for gins""" + import os import threading import time @@ -6,28 +7,31 @@ from jaclang.runtimelib.gins.tracer import CFGTracker + try: import google.generativeai as genai except Exception as e: - print("google.generativeai module not present. Please install using 'pip install google.generativeai'.") + print( + "google.generativeai module not present. Please install using 'pip install google.generativeai'." + ) + # Helper class to maintain a fixed deque size -class CfgDeque(): - def __init__(self, max_size:int=10): - self.__max_size = max_size - self.__deque = deque() +class CfgDeque: + def __init__(self, max_size: int = 10): + self.__max_size = max_size + self.__deque = deque() - def add_cfg(self, cfg_repr:str): - self.__deque.append(cfg_repr) - if len(self.__deque) > self.__max_size: - self.__deque.popleft() - - def display_cfgs(self): - print("CFG change over updates\n") - for cfg in self.__deque: - print("\n") - print(cfg) + def add_cfg(self, cfg_repr: str): + self.__deque.append(cfg_repr) + if len(self.__deque) > self.__max_size: + self.__deque.popleft() + def display_cfgs(self): + print("CFG change over updates\n") + for cfg in self.__deque: + print("\n") + print(cfg) class ShellGhost: @@ -36,7 +40,7 @@ def __init__(self): self.cfg_cv = threading.Condition() self.tracker = CFGTracker() self.sem_ir = None - + self.finished_exception_lock = threading.Lock() self.exception = None self.finished = False @@ -48,18 +52,17 @@ def __init__(self): self.deque_lock = threading.Lock() self.__cfg_deque = CfgDeque(2) - def set_cfgs(self, cfgs): self.cfg_cv.acquire() self.cfgs = cfgs self.cfg_cv.notify() self.cfg_cv.release() - def update_cfg_deque(self,cfg): + def update_cfg_deque(self, cfg): self.deque_lock.acquire() self.__cfg_deque.add_cfg(cfg) self.deque_lock.release() - + def get_cfg_deque_repr(self): return self.__cfg_deque.display_cfgs() @@ -72,7 +75,7 @@ def set_finished(self, exception: Exception = None): self.exception = exception self.finished = True self.finished_exception_lock.release() - + def prompt_llm(self, verbose: bool = False): prompt = """I have a program. CFGS: @@ -81,38 +84,40 @@ def prompt_llm(self, verbose: bool = False): {instructions} Semantic and Type information from source code: {sem_ir}""" - + cfg_string = "" - ins_string = "" + ins_string = "" for module, cfg in self.cfgs.items(): - cfg_string += f"Module: {module}\n{cfg}" + cfg_string += f"Module: {module}\n{cfg}" ins_string += f"Module: {module}\n{cfg.display_instructions()}" - - prompt = prompt.format(cfgs=cfg_string, instructions=ins_string, sem_ir=self.sem_ir) + + prompt = prompt.format( + cfgs=cfg_string, instructions=ins_string, sem_ir=self.sem_ir + ) if self.variable_values != None: prompt += "\nCurrent variable values at the specified bytecode offset:" - + for module, var_map in self.variable_values.items(): prompt += f"\nModule {module}: Offset: {var_map[0]}, Variables: {str(var_map[1])}" - + self.finished_exception_lock.acquire() - + if self.exception: prompt += f"\nException: {self.exception}" self.finished_exception_lock.release() - + prompt += "\nCan you identity bottlneck optimizations or where the code can error out?" prompt += "\n(Reason about the program using cfg, semantic and type information. Do not include python code fixes or bytecode in response.)" - + if verbose: print(prompt) - + response = self.model.generate_content(prompt) - + print(response.text) - + def worker(self): # get static cfgs self.cfg_cv.acquire() @@ -123,35 +128,54 @@ def worker(self): # for module_name, cfg in self.cfgs.items(): # print(f"Name: {module_name}\n{cfg.display_instructions()}") self.cfg_cv.release() - + # Once cv has been notifie, self.cfgs is no longer accessed across threads - current_executing_bbs = {} + current_executing_bbs = {} def update_cfg(): exec_insts = self.tracker.get_exec_inst() - + # don't prompt if there's nothing new if exec_insts == {}: return - + for module, offset_list in exec_insts.items(): - try: - cfg = self.cfgs[module] + try: + cfg = self.cfgs[module] - if module not in current_executing_bbs: # this means start at bb0, set exec count for bb0 to 1 + if ( + module not in current_executing_bbs + ): # this means start at bb0, set exec count for bb0 to 1 current_executing_bbs[module] = 0 cfg.block_map.idx_to_block[0].exec_count = 1 - - for offset in offset_list: - if offset not in cfg.block_map.idx_to_block[current_executing_bbs[module]].bytecode_offsets: + + for offset in offset_list: + if ( + offset + not in cfg.block_map.idx_to_block[ + current_executing_bbs[module] + ].bytecode_offsets + ): for next_bb in cfg.edges[current_executing_bbs[module]]: - if offset in cfg.block_map.idx_to_block[next_bb].bytecode_offsets: - cfg.edge_counts[(current_executing_bbs[module], next_bb)] += 1 - #do some deque op + if ( + offset + in cfg.block_map.idx_to_block[ + next_bb + ].bytecode_offsets + ): + cfg.edge_counts[ + (current_executing_bbs[module], next_bb) + ] += 1 + # do some deque op cfg.block_map.idx_to_block[next_bb].exec_count += 1 current_executing_bbs[module] = next_bb - break - assert(offset in cfg.block_map.idx_to_block[current_executing_bbs[module]].bytecode_offsets) + break + assert ( + offset + in cfg.block_map.idx_to_block[ + current_executing_bbs[module] + ].bytecode_offsets + ) except Exception as e: self.set_finished(e) print(e) @@ -160,22 +184,20 @@ def update_cfg(): self.variable_values = self.tracker.get_variable_values() self.update_cfg_deque(cfg.get_cfg_repr()) print(self.get_cfg_deque_repr()) - self.finished_exception_lock.acquire() - while (not self.finished): + while not self.finished: self.finished_exception_lock.release() - + time.sleep(1) - print('\nUpdating cfgs') + print("\nUpdating cfgs") update_cfg() # self.prompt_llm() self.finished_exception_lock.acquire() self.finished_exception_lock.release() - - print('\nUpdating cfgs at the end') + + print("\nUpdating cfgs at the end") update_cfg() # print(self.cfgs['hot_path'].display_instructions()) # self.prompt_llm() - \ No newline at end of file diff --git a/jac/jaclang/runtimelib/gins/tracer.py b/jac/jaclang/runtimelib/gins/tracer.py index 9d50012f74..358e7cd0a2 100644 --- a/jac/jaclang/runtimelib/gins/tracer.py +++ b/jac/jaclang/runtimelib/gins/tracer.py @@ -5,11 +5,12 @@ import copy import os + class CFGTracker: def __init__(self): self.executed_insts = {} self.inst_lock = threading.Lock() - + self.curr_variables_lock = threading.Lock() self.curr_variables = {} @@ -18,16 +19,17 @@ def start_tracking(self): frame = sys._getframe() frame.f_trace_opcodes = True sys.settrace(self.trace_callback) + def stop_tracking(self): """Stop tracking branch coverage""" sys.settrace(None) - + def get_exec_inst(self): self.inst_lock.acquire() cpy = copy.deepcopy(self.executed_insts) self.executed_insts = {} self.inst_lock.release() - + return cpy def get_variable_values(self): @@ -35,35 +37,40 @@ def get_variable_values(self): cpy = copy.deepcopy(self.curr_variables) print(cpy) self.curr_variables_lock.release() - + return cpy - - - def trace_callback(self, frame: types.FrameType, event: str, arg: any) -> Optional[Callable]: + + def trace_callback( + self, frame: types.FrameType, event: str, arg: any + ) -> Optional[Callable]: if event == "call": frame.f_trace_opcodes = True - - """Trace function to track executed branches""" + + """Trace function to track executed branches""" code = frame.f_code if ".jac" not in code.co_filename: return self.trace_callback - if event == 'opcode': - #edge case to handle executing code not within a function + if event == "opcode": + # edge case to handle executing code not within a function filename = os.path.basename(code.co_filename) - module = code.co_name if code.co_name != "" else os.path.splitext(filename)[0] - + module = ( + code.co_name + if code.co_name != "" + else os.path.splitext(filename)[0] + ) + self.inst_lock.acquire() if module not in self.executed_insts: self.executed_insts[module] = [] self.executed_insts[module].append(frame.f_lasti) self.inst_lock.release() variable_dict = {} - if '__annotations__' in frame.f_locals: + if "__annotations__" in frame.f_locals: self.curr_variables_lock.acquire() - for var_name in frame.f_locals['__annotations__']: + for var_name in frame.f_locals["__annotations__"]: variable_dict[var_name] = frame.f_locals[var_name] self.curr_variables[module] = (frame.f_lasti, variable_dict) self.curr_variables_lock.release() - return self.trace_callback \ No newline at end of file + return self.trace_callback From 0c733317078eb534a468d9951ee529969495836a Mon Sep 17 00:00:00 2001 From: Jayanaka-98 Date: Thu, 28 Nov 2024 00:08:54 -0500 Subject: [PATCH 60/84] deque braught into tracer --- jac/jaclang/runtimelib/gins/cfg.py | 39 ++++++++++++++------------- jac/jaclang/runtimelib/gins/ghost.py | 18 +------------ jac/jaclang/runtimelib/gins/tracer.py | 20 +++++++++++++- 3 files changed, 40 insertions(+), 37 deletions(-) diff --git a/jac/jaclang/runtimelib/gins/cfg.py b/jac/jaclang/runtimelib/gins/cfg.py index fa52ac7733..a6b516a171 100644 --- a/jac/jaclang/runtimelib/gins/cfg.py +++ b/jac/jaclang/runtimelib/gins/cfg.py @@ -267,7 +267,6 @@ def find_block_by_offset(block_map: BlockMap, offset: int) -> int: return None -# Function to visualize CFG using Graphviz def visualize_cfg(cfg: CFG): dot = Digraph(comment="Control Flow Graph") for node in cfg.nodes: @@ -278,21 +277,23 @@ def visualize_cfg(cfg: CFG): return dot -if __name__ == "__main__": - # Sample list of instructions for processing - ##simple= - # instructions = disassemble_bytecode(b'c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x01\xf3*\x00\x00\x00\x97\x00d\x00d\x01l\x00m\x01Z\x01\x01\x00d\x00Z\x02d\x00Z\x03e\x03d\x00k\\\x00\x00r\x02d\x02Z\x02d\x03Z\x02y\x04)\x05\xe9\x00\x00\x00\x00)\x01\xda\x0bannotations\xe9\x01\x00\x00\x00\xe9\xff\xff\xff\xffN)\x04\xda\n__future__r\x02\x00\x00\x00\xda\x01a\xda\x01x\xa9\x00\xf3\x00\x00\x00\x00\xfaP/Users/jakobtherkelsen/Documents/jaseci-ginS/jac/examples/ginsScripts/simple.jac\xfa\x08r\x0b\x00\x00\x00\x01\x00\x00\x00s%\x00\x00\x00\xf0\x03\x01\x01\x01\xf5\x02\x07\x02\x03\xd8\x05\x06\x801\xd8\x05\x06\x801\xd8\x06\x07\x881\x82f\xd8\x07\x08\x80Q\xe0\x05\x07\x811r\t\x00\x00\x00') - # hot path - instructions = disassemble_bytecode( - b"c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x01\xf3\xa4\x00\x00\x00\x97\x00U\x00d\x00d\x01l\x00m\x01Z\x01\x01\x00d\x00Z\x02d\x02e\x03d\x03<\x00\x00\x00d\x04Z\x04d\x02e\x03d\x05<\x00\x00\x00e\x02e\x04z\x00\x00\x00Z\x05d\x02e\x03d\x06<\x00\x00\x00\x02\x00e\x06d\x04\xab\x01\x00\x00\x00\x00\x00\x00D\x00]\x1c\x00\x00Z\x07e\x02d\x07z\x06\x00\x00r\ne\x04e\x02z\x00\x00\x00Z\x04e\x02e\x04z\x00\x00\x00Z\x05d\x08e\x07z\x05\x00\x00e\x04e\x05z\x05\x00\x00z\x00\x00\x00Z\x02\x8c\x1e\x04\x00d\tZ\x05e\x05d\tk(\x00\x00r\x03d\x08Z\x05y\ny\n)\x0b\xe9\x00\x00\x00\x00)\x01\xda\x0bannotations\xda\x03int\xda\x01x\xe9\x03\x00\x00\x00\xda\x01y\xda\x01z\xe9\x02\x00\x00\x00\xe9\x04\x00\x00\x00\xe9\n\x00\x00\x00N)\x08\xda\n__future__r\x02\x00\x00\x00r\x04\x00\x00\x00\xda\x0f__annotations__r\x06\x00\x00\x00r\x07\x00\x00\x00\xda\x05range\xda\x01i\xa9\x00\xf3\x00\x00\x00\x00\xfaU/Users/jakobtherkelsen/Documents/jaseci-ginS/jac/examples/gins_scripts/simple_for.jac\xda\x08r\x12\x00\x00\x00\x01\x00\x00\x00sy\x00\x00\x00\xf0\x03\x01\x01\x01\xf6\x02\x0f\x02\x03\xd8\r\x0e\x80Q\x80s\x83Z\xd8\r\x0e\x80Q\x80s\x83Z\xd8\r\x0e\x90\x11\x89U\x80Q\x80s\x83^\xd9\x0e\x13\x90A\x8eh\x88\x11\xd8\n\x0b\x88a\x8a%\xd8\r\x0e\x90\x11\x89U\x88\x11\xd8\r\x0e\x90\x11\x89U\x88\x11\xe0\x0b\x0c\x88q\x895\x901\x98\x01\x917\x89?\x81q\xf0\x0b\x00\x0f\x17\xf0\x0e\x00\n\x0c\x80Q\xd8\x08\t\x88R\x8a\x07\xd8\n\x0b\x81q\xf0\x03\x00\t\x10r\x10\x00\x00\x00" - ) - BBs = create_BBs(instructions) - print(BBs) - - cfg = create_cfg(BBs) - print("\nControl Flow Graph (CFG):") - print(cfg) - - # Visualize CFG - dot = visualize_cfg(cfg) - dot.render("cfg.gv", view=True) +# can use as a test + +# if __name__ == "__main__": +# # Sample list of instructions for processing +# ##simple= +# # instructions = disassemble_bytecode(b'c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x01\xf3*\x00\x00\x00\x97\x00d\x00d\x01l\x00m\x01Z\x01\x01\x00d\x00Z\x02d\x00Z\x03e\x03d\x00k\\\x00\x00r\x02d\x02Z\x02d\x03Z\x02y\x04)\x05\xe9\x00\x00\x00\x00)\x01\xda\x0bannotations\xe9\x01\x00\x00\x00\xe9\xff\xff\xff\xffN)\x04\xda\n__future__r\x02\x00\x00\x00\xda\x01a\xda\x01x\xa9\x00\xf3\x00\x00\x00\x00\xfaP/Users/jakobtherkelsen/Documents/jaseci-ginS/jac/examples/ginsScripts/simple.jac\xfa\x08r\x0b\x00\x00\x00\x01\x00\x00\x00s%\x00\x00\x00\xf0\x03\x01\x01\x01\xf5\x02\x07\x02\x03\xd8\x05\x06\x801\xd8\x05\x06\x801\xd8\x06\x07\x881\x82f\xd8\x07\x08\x80Q\xe0\x05\x07\x811r\t\x00\x00\x00') +# # hot path +# instructions = disassemble_bytecode( +# b"c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x01\xf3\xa4\x00\x00\x00\x97\x00U\x00d\x00d\x01l\x00m\x01Z\x01\x01\x00d\x00Z\x02d\x02e\x03d\x03<\x00\x00\x00d\x04Z\x04d\x02e\x03d\x05<\x00\x00\x00e\x02e\x04z\x00\x00\x00Z\x05d\x02e\x03d\x06<\x00\x00\x00\x02\x00e\x06d\x04\xab\x01\x00\x00\x00\x00\x00\x00D\x00]\x1c\x00\x00Z\x07e\x02d\x07z\x06\x00\x00r\ne\x04e\x02z\x00\x00\x00Z\x04e\x02e\x04z\x00\x00\x00Z\x05d\x08e\x07z\x05\x00\x00e\x04e\x05z\x05\x00\x00z\x00\x00\x00Z\x02\x8c\x1e\x04\x00d\tZ\x05e\x05d\tk(\x00\x00r\x03d\x08Z\x05y\ny\n)\x0b\xe9\x00\x00\x00\x00)\x01\xda\x0bannotations\xda\x03int\xda\x01x\xe9\x03\x00\x00\x00\xda\x01y\xda\x01z\xe9\x02\x00\x00\x00\xe9\x04\x00\x00\x00\xe9\n\x00\x00\x00N)\x08\xda\n__future__r\x02\x00\x00\x00r\x04\x00\x00\x00\xda\x0f__annotations__r\x06\x00\x00\x00r\x07\x00\x00\x00\xda\x05range\xda\x01i\xa9\x00\xf3\x00\x00\x00\x00\xfaU/Users/jakobtherkelsen/Documents/jaseci-ginS/jac/examples/gins_scripts/simple_for.jac\xda\x08r\x12\x00\x00\x00\x01\x00\x00\x00sy\x00\x00\x00\xf0\x03\x01\x01\x01\xf6\x02\x0f\x02\x03\xd8\r\x0e\x80Q\x80s\x83Z\xd8\r\x0e\x80Q\x80s\x83Z\xd8\r\x0e\x90\x11\x89U\x80Q\x80s\x83^\xd9\x0e\x13\x90A\x8eh\x88\x11\xd8\n\x0b\x88a\x8a%\xd8\r\x0e\x90\x11\x89U\x88\x11\xd8\r\x0e\x90\x11\x89U\x88\x11\xe0\x0b\x0c\x88q\x895\x901\x98\x01\x917\x89?\x81q\xf0\x0b\x00\x0f\x17\xf0\x0e\x00\n\x0c\x80Q\xd8\x08\t\x88R\x8a\x07\xd8\n\x0b\x81q\xf0\x03\x00\t\x10r\x10\x00\x00\x00" +# ) +# BBs = create_BBs(instructions) +# print(BBs) + +# cfg = create_cfg(BBs) +# print("\nControl Flow Graph (CFG):") +# print(cfg) + +# # Visualize CFG +# dot = visualize_cfg(cfg) +# dot.render("cfg.gv", view=True) diff --git a/jac/jaclang/runtimelib/gins/ghost.py b/jac/jaclang/runtimelib/gins/ghost.py index 9edd5769b1..562ddf12d3 100644 --- a/jac/jaclang/runtimelib/gins/ghost.py +++ b/jac/jaclang/runtimelib/gins/ghost.py @@ -3,10 +3,9 @@ import os import threading import time -from collections import deque -from jaclang.runtimelib.gins.tracer import CFGTracker +from jaclang.runtimelib.gins.tracer import CFGTracker, CfgDeque try: import google.generativeai as genai @@ -17,21 +16,6 @@ # Helper class to maintain a fixed deque size -class CfgDeque: - def __init__(self, max_size: int = 10): - self.__max_size = max_size - self.__deque = deque() - - def add_cfg(self, cfg_repr: str): - self.__deque.append(cfg_repr) - if len(self.__deque) > self.__max_size: - self.__deque.popleft() - - def display_cfgs(self): - print("CFG change over updates\n") - for cfg in self.__deque: - print("\n") - print(cfg) class ShellGhost: diff --git a/jac/jaclang/runtimelib/gins/tracer.py b/jac/jaclang/runtimelib/gins/tracer.py index 358e7cd0a2..48b63171d8 100644 --- a/jac/jaclang/runtimelib/gins/tracer.py +++ b/jac/jaclang/runtimelib/gins/tracer.py @@ -1,9 +1,27 @@ import types -from typing import Optional, Union, Callable +from typing import Optional, Callable import threading import sys import copy import os +from collections import deque + + +class CfgDeque: + def __init__(self, max_size: int = 10): + self.__max_size = max_size + self.__deque = deque() + + def add_cfg(self, cfg_repr: str): + self.__deque.append(cfg_repr) + if len(self.__deque) > self.__max_size: + self.__deque.popleft() + + def display_cfgs(self): + print("CFG change over updates\n") + for cfg in self.__deque: + print("\n") + print(cfg) class CFGTracker: From 110910970ab016dd4b2411bd9190496f1f2e1e1b Mon Sep 17 00:00:00 2001 From: Jayanaka-98 Date: Thu, 28 Nov 2024 01:18:27 -0500 Subject: [PATCH 61/84] made model modular and non breaking for import errors. --- jac/jaclang/runtimelib/gins/cfg.py | 26 +++++++++-------- jac/jaclang/runtimelib/gins/ghost.py | 21 +++++--------- jac/jaclang/runtimelib/gins/model.py | 41 +++++++++++++++++++++++++++ jac/jaclang/runtimelib/gins/tracer.py | 3 ++ jac/jaclang/runtimelib/importer.py | 2 ++ 5 files changed, 67 insertions(+), 26 deletions(-) create mode 100644 jac/jaclang/runtimelib/gins/model.py diff --git a/jac/jaclang/runtimelib/gins/cfg.py b/jac/jaclang/runtimelib/gins/cfg.py index a6b516a171..28dbf15118 100644 --- a/jac/jaclang/runtimelib/gins/cfg.py +++ b/jac/jaclang/runtimelib/gins/cfg.py @@ -1,14 +1,10 @@ -"""Genrate a control flow graph from genarated bytecode. - -This pass generates a control flow graph from the bytecode generated by the previous pass. +"""CFG generation primitives for generating a CFG in jaclang passes. """ import marshal import dis from collections import defaultdict from typing import List, Optional, Iterator -import graphviz -from graphviz import Digraph class BytecodeOp: @@ -268,13 +264,19 @@ def find_block_by_offset(block_map: BlockMap, offset: int) -> int: def visualize_cfg(cfg: CFG): - dot = Digraph(comment="Control Flow Graph") - for node in cfg.nodes: - dot.node(f"bb{node}", f"BB{node}") - for from_node, to_nodes in cfg.edges.items(): - for to_node in to_nodes: - dot.edge(f"bb{from_node}", f"bb{to_node}") - return dot + try: + from graphviz import Digraph + + dot = Digraph(comment="Control Flow Graph") + for node in cfg.nodes: + dot.node(f"bb{node}", f"BB{node}") + for from_node, to_nodes in cfg.edges.items(): + for to_node in to_nodes: + dot.edge(f"bb{from_node}", f"bb{to_node}") + return dot + except ImportError: + print("Graphviz not installed, can't visualize CFG") + return None # can use as a test diff --git a/jac/jaclang/runtimelib/gins/ghost.py b/jac/jaclang/runtimelib/gins/ghost.py index 562ddf12d3..ee43491977 100644 --- a/jac/jaclang/runtimelib/gins/ghost.py +++ b/jac/jaclang/runtimelib/gins/ghost.py @@ -1,19 +1,13 @@ -"""The Shell Ghost code for gins""" +"""The Shell Ghost code for gins +""" import os import threading import time - +from jaclang.runtimelib.gins.model import Gemini from jaclang.runtimelib.gins.tracer import CFGTracker, CfgDeque -try: - import google.generativeai as genai -except Exception as e: - print( - "google.generativeai module not present. Please install using 'pip install google.generativeai'." - ) - # Helper class to maintain a fixed deque size @@ -30,8 +24,7 @@ def __init__(self): self.finished = False self.variable_values = None - genai.configure(api_key=os.getenv("GEMINI_API_KEY")) - self.model = genai.GenerativeModel("gemini-1.5-flash") + self.model = Gemini() self.deque_lock = threading.Lock() self.__cfg_deque = CfgDeque(2) @@ -98,9 +91,9 @@ def prompt_llm(self, verbose: bool = False): if verbose: print(prompt) - response = self.model.generate_content(prompt) + response = self.model.generate(prompt) - print(response.text) + print(response) def worker(self): # get static cfgs @@ -176,7 +169,7 @@ def update_cfg(): time.sleep(1) print("\nUpdating cfgs") update_cfg() - # self.prompt_llm() + self.prompt_llm() self.finished_exception_lock.acquire() self.finished_exception_lock.release() diff --git a/jac/jaclang/runtimelib/gins/model.py b/jac/jaclang/runtimelib/gins/model.py new file mode 100644 index 0000000000..fca343f0aa --- /dev/null +++ b/jac/jaclang/runtimelib/gins/model.py @@ -0,0 +1,41 @@ +"""Generative AI model integration for GINS +""" + + +class BaseModel: + def __init__(self, model_name: str = "gemini-1.5-flash", **kwargs): + self.model_name = model_name + for key, value in kwargs.items(): + setattr(self, key, value) + self.config() + + def config(self): + raise NotImplementedError + + def generate(self, prompt: str): + raise NotImplementedError + + +class Gemini(BaseModel): + def config(self): + try: + import google.generativeai as genai + + if "api_key" in self.__dict__: + genai.configure(api_key=self.api_key) + else: + import os + + genai.configure(api_key=os.getenv("GEMINI_API_KEY")) + self.model = genai.GenerativeModel() + import os + except Exception as e: + print( + "google.generativeai module not present. Please install using 'pip install google.generativeai'." + ) + print("Warning:", e) + return None + + def generate(self, prompt: str): + response = self.model.generate_content(prompt) + return response.text diff --git a/jac/jaclang/runtimelib/gins/tracer.py b/jac/jaclang/runtimelib/gins/tracer.py index 48b63171d8..4b34b312fd 100644 --- a/jac/jaclang/runtimelib/gins/tracer.py +++ b/jac/jaclang/runtimelib/gins/tracer.py @@ -1,3 +1,6 @@ +"""Module to track executed branches and variables +""" + import types from typing import Optional, Callable import threading diff --git a/jac/jaclang/runtimelib/importer.py b/jac/jaclang/runtimelib/importer.py index 5ab2c87d43..64363a9b35 100644 --- a/jac/jaclang/runtimelib/importer.py +++ b/jac/jaclang/runtimelib/importer.py @@ -63,6 +63,7 @@ def get_caller_dir(self) -> str: chomp_target = chomp_target[1:] return path.join(caller_dir, self.dir_path) + class ImportReturn: """Import Return Object.""" @@ -348,6 +349,7 @@ def run_import( raise ImportError(f"No bytecode found for {spec.full_target}") from jaclang.runtimelib.machine import JacMachine + if JacMachine.get().gin: try: with sys_path_context(spec.caller_dir): From 72594aa9870f176976e5c2e4fdfab7980b0cdce7 Mon Sep 17 00:00:00 2001 From: jayanaka-98 Date: Sun, 1 Dec 2024 14:07:19 -0500 Subject: [PATCH 62/84] long running power program with gradual devide by zero --- jac/examples/gins_scripts/power.jac | 105 +++++++++++++++++--------- jac/jaclang/runtimelib/gins/ghost.py | 7 +- jac/jaclang/runtimelib/gins/tracer.py | 2 +- 3 files changed, 76 insertions(+), 38 deletions(-) diff --git a/jac/examples/gins_scripts/power.jac b/jac/examples/gins_scripts/power.jac index e9b2472ce0..a0f68a6a6d 100644 --- a/jac/examples/gins_scripts/power.jac +++ b/jac/examples/gins_scripts/power.jac @@ -1,44 +1,81 @@ -with entry { - +import:py from math { exp } +import:py from time { sleep } # Data structure representing system configuration -system_config = { - 'base_load': 1000, # Base power load in watts - 'min_duration': 5, # Minimum valid duration in minutes - 'mode': 'active' +glob system_config: Dict[str, Union[int, str, float]] = { + 'base_load': 1000, # Base power load in watts + 'min_duration': 10, # Minimum valid duration in minutes + 'mode': 'active', + 'time_step': 0, # Track progression of simulation + 'reference_delta': 200 # Reference power delta for normalization }; -# Input data representing power readings -power_readings = [880, 920, 950, 980, 1000]; # Last reading equals base_load -time_periods = [15, 20, 25, 30, 35]; +# Function to generate declining power readings +with entry { + # Create gradually converging power readings + base: float = system_config['base_load']; + power_readings: list[float] = []; + time_periods: list[int] = []; + reference_power: float = base + 200;# Reference power for normalization -# Initialize results storage -efficiency_metrics = []; -total_operational_time = 0; + # Generate 200 readings that gradually approach base_load + for i in range(200) { + # Power gradually approaches base_load (1000W) + delta: float = 200.0 * exp(-0.5 * i);# Slower decay for better visualization + current_power: float = base + delta; + power_readings.append(current_power); -# Process each power reading -for (idx, current_power) in enumerate(power_readings){ - if system_config['mode'] != 'active'{ - continue; + # Time periods increase linearly + time_periods.append(15 + i * 2); } - duration = time_periods[idx]; - if duration < system_config['min_duration']{ - continue; + + # Initialize results storage + + efficiency_metrics: list = []; + total_operational_time: int = 0; + + # Process each power reading with different execution paths + for (idx, current_power) in enumerate(power_readings) { + if system_config['mode'] != 'active' { + continue; + } + + duration: int = time_periods[idx]; + if duration < system_config['min_duration'] { + continue; + } + + # Track simulation progression + + system_config['time_step'] += 1; + + power_delta: float = current_power - system_config['base_load']; + + # Introduce different execution paths based on time_step + if system_config['time_step'] > 50 { + diminishing_reference: float = power_delta * 2; # Reference point approaches zero with power_delta + power_utilization: float = power_delta / diminishing_reference; # Approaches 0.5, then unstable + } else { + # Original calculation path for first 10 steps + power_utilization: float = power_delta / system_config['reference_delta']; + } + period_efficiency: float = power_utilization * (duration / max(time_periods)) * 100; + + efficiency_metrics.append(period_efficiency); + total_operational_time += duration; + + # Print current state + print( + f"Step {system_config['time_step']}: Power={current_power}W, " + f"Delta from base={current_power - system_config['base_load']}W" + ); + sleep(1); } - # This division will fail when current_power equals base_load (1000W) - # The error is hidden because it's part of a complex formula that looks valid - power_utilization = (current_power - system_config['base_load']) / (max(power_readings) - system_config['base_load']); - - # Complex metric calculation makes the division less obvious - period_efficiency = power_utilization * (duration / max(time_periods)) * 100; - - efficiency_metrics.append(period_efficiency); - total_operational_time += duration; -} -# Calculate final metrics -average_efficiency = sum(efficiency_metrics) / len(efficiency_metrics) if efficiency_metrics else 0; -operational_hours = total_operational_time / 60; + # Calculate final metrics if no error occurred -print(f"System Analysis Complete - Efficiency: {average_efficiency}%"); + average_efficiency: float = sum(efficiency_metrics) / len(efficiency_metrics) if efficiency_metrics else 0; + operational_hours: float = total_operational_time / 60; + print( + f"System Analysis Complete - Efficiency: {average_efficiency}%" + ); -} \ No newline at end of file +} diff --git a/jac/jaclang/runtimelib/gins/ghost.py b/jac/jaclang/runtimelib/gins/ghost.py index ee43491977..b5691090de 100644 --- a/jac/jaclang/runtimelib/gins/ghost.py +++ b/jac/jaclang/runtimelib/gins/ghost.py @@ -69,7 +69,7 @@ def prompt_llm(self, verbose: bool = False): ins_string += f"Module: {module}\n{cfg.display_instructions()}" prompt = prompt.format( - cfgs=cfg_string, instructions=ins_string, sem_ir=self.sem_ir + cfgs=cfg_string, instructions=ins_string, sem_ir=self.sem_ir.pp() ) if self.variable_values != None: @@ -93,7 +93,8 @@ def prompt_llm(self, verbose: bool = False): response = self.model.generate(prompt) - print(response) + print("\nGin tought:\n", response) + return response def worker(self): # get static cfgs @@ -160,7 +161,6 @@ def update_cfg(): self.variable_values = self.tracker.get_variable_values() self.update_cfg_deque(cfg.get_cfg_repr()) - print(self.get_cfg_deque_repr()) self.finished_exception_lock.acquire() while not self.finished: @@ -171,6 +171,7 @@ def update_cfg(): update_cfg() self.prompt_llm() self.finished_exception_lock.acquire() + time.sleep(5) self.finished_exception_lock.release() diff --git a/jac/jaclang/runtimelib/gins/tracer.py b/jac/jaclang/runtimelib/gins/tracer.py index 4b34b312fd..00b75155f4 100644 --- a/jac/jaclang/runtimelib/gins/tracer.py +++ b/jac/jaclang/runtimelib/gins/tracer.py @@ -56,7 +56,7 @@ def get_exec_inst(self): def get_variable_values(self): self.curr_variables_lock.acquire() cpy = copy.deepcopy(self.curr_variables) - print(cpy) + # print(cpy) self.curr_variables_lock.release() return cpy From 4713793d23416a02aa4e88bdc1ed9572cd2dc84c Mon Sep 17 00:00:00 2001 From: Jona Grodecki Date: Sun, 1 Dec 2024 15:16:01 -0500 Subject: [PATCH 63/84] adding phase switch program --- jac/examples/gins_scripts/phase_switch.jac | 34 ++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 jac/examples/gins_scripts/phase_switch.jac diff --git a/jac/examples/gins_scripts/phase_switch.jac b/jac/examples/gins_scripts/phase_switch.jac new file mode 100644 index 0000000000..3181c3dc78 --- /dev/null +++ b/jac/examples/gins_scripts/phase_switch.jac @@ -0,0 +1,34 @@ +import:py random; +import:py time; + +with entry { + bar:int = 1; + hot_path_switches:int = 10; + foo:int = 0; + ctr:int = 0; + itr:int = 0; + + while foo < hot_path_switches { + var = random.randint(1,12345); + if(var % 11111 == 0){ + ctr +=1; + time.sleep(0.1); + if (ctr == 100) { + print(itr); + itr = 0; + foo += 1; + ctr = 0; + print(foo); + } + #print(var) + } + itr += 1; + if foo % 2 == 0 { + bar = bar +3; + } else { + bar = bar -2; + } + } + + +} \ No newline at end of file From 01de803318b84b0a823ae68f3a01efec11f102d1 Mon Sep 17 00:00:00 2001 From: Jakob Louis Therkelsen Date: Sun, 1 Dec 2024 17:19:03 -0500 Subject: [PATCH 64/84] static code analysis for comparison --- jac/{ => examples/gins_scripts}/example.jac | 10 +++-- jac/jaclang/runtimelib/gins/ghost.py | 44 +++++++++++++++++++-- 2 files changed, 46 insertions(+), 8 deletions(-) rename jac/{ => examples/gins_scripts}/example.jac (82%) diff --git a/jac/example.jac b/jac/examples/gins_scripts/example.jac similarity index 82% rename from jac/example.jac rename to jac/examples/gins_scripts/example.jac index d657278edb..f174566507 100644 --- a/jac/example.jac +++ b/jac/examples/gins_scripts/example.jac @@ -20,14 +20,16 @@ with entry { x:int = 0; y:int = 3; z:int = x + y; - for i in range(100000) { + for i in range(49) { x = 4 * i + y * (z); if x % 2 { - y = y + x; - z = x + y; + y= 0; + } + else { + y = 4; } } - z = x/0; + z = x/y; print(y); print("hello"); } diff --git a/jac/jaclang/runtimelib/gins/ghost.py b/jac/jaclang/runtimelib/gins/ghost.py index b5691090de..7353e20f25 100644 --- a/jac/jaclang/runtimelib/gins/ghost.py +++ b/jac/jaclang/runtimelib/gins/ghost.py @@ -53,6 +53,38 @@ def set_finished(self, exception: Exception = None): self.finished = True self.finished_exception_lock.release() + def prompt_direct(self): + script = """ + with entry { + x:int = 0; + y:int = 3; + z:int = x + y; + for i in range(49) { + x = 4 * i + y * (z); + if x % 2 { + y= 0; + } + else { + y = 4; + } + } + z = x/y; + print(y); + print("hello"); + } + """ + prompt = f""" + I have the following script: + {script} + + Can you identity bottlneck optimizations or where the code can error out?" + Reason about the program using the provided information, reason about the program itself and what improvements could be made. + """ + + response = self.model.generate(prompt) + + print("\nGin Analysis(With static info):\n", response) + def prompt_llm(self, verbose: bool = False): prompt = """I have a program. CFGS: @@ -86,14 +118,15 @@ def prompt_llm(self, verbose: bool = False): self.finished_exception_lock.release() prompt += "\nCan you identity bottlneck optimizations or where the code can error out?" - prompt += "\n(Reason about the program using cfg, semantic and type information. Do not include python code fixes or bytecode in response.)" + prompt += "\n(Reason about the program using cfg, semantic and type information. Instead of saying what BB could be improved, reason about the program itself and what improvements could be made.)" + prompt += "\n If variable values are available, reason about at what point did a variable cause an issue" if verbose: print(prompt) response = self.model.generate(prompt) - print("\nGin tought:\n", response) + print("\nGin Analysis:\n", response) return response def worker(self): @@ -169,7 +202,7 @@ def update_cfg(): time.sleep(1) print("\nUpdating cfgs") update_cfg() - self.prompt_llm() + # self.prompt_llm() self.finished_exception_lock.acquire() time.sleep(5) @@ -178,4 +211,7 @@ def update_cfg(): print("\nUpdating cfgs at the end") update_cfg() # print(self.cfgs['hot_path'].display_instructions()) - # self.prompt_llm() + self.prompt_llm() + + print("STATIC RESULT") + self.prompt_direct() From ea4b5c65667b71dc5a85775a66713990cbf5f4f0 Mon Sep 17 00:00:00 2001 From: Jakob Louis Therkelsen Date: Sun, 1 Dec 2024 18:47:00 -0500 Subject: [PATCH 65/84] result example --- jac/examples/gins_scripts/power.jac | 2 +- jac/jaclang/runtimelib/gins/ghost.py | 101 ++++++++++++++++++++++----- 2 files changed, 84 insertions(+), 19 deletions(-) diff --git a/jac/examples/gins_scripts/power.jac b/jac/examples/gins_scripts/power.jac index a0f68a6a6d..398f22817e 100644 --- a/jac/examples/gins_scripts/power.jac +++ b/jac/examples/gins_scripts/power.jac @@ -67,7 +67,7 @@ with entry { print( f"Step {system_config['time_step']}: Power={current_power}W, " + f"Delta from base={current_power - system_config['base_load']}W" ); - sleep(1); + sleep(0.25); } # Calculate final metrics if no error occurred diff --git a/jac/jaclang/runtimelib/gins/ghost.py b/jac/jaclang/runtimelib/gins/ghost.py index 7353e20f25..ee7261a386 100644 --- a/jac/jaclang/runtimelib/gins/ghost.py +++ b/jac/jaclang/runtimelib/gins/ghost.py @@ -55,23 +55,87 @@ def set_finished(self, exception: Exception = None): def prompt_direct(self): script = """ - with entry { - x:int = 0; - y:int = 3; - z:int = x + y; - for i in range(49) { - x = 4 * i + y * (z); - if x % 2 { - y= 0; + import:py from math { exp } + import:py from time { sleep } + # Data structure representing system configuration + glob system_config: Dict[str, Union[int, str, float]] = { + 'base_load': 1000, # Base power load in watts + 'min_duration': 10, # Minimum valid duration in minutes + 'mode': 'active', + 'time_step': 0, # Track progression of simulation + 'reference_delta': 200 # Reference power delta for normalization + }; + + # Function to generate declining power readings + with entry { + # Create gradually converging power readings + base: float = system_config['base_load']; + power_readings: list[float] = []; + time_periods: list[int] = []; + reference_power: float = base + 200;# Reference power for normalization + + # Generate 200 readings that gradually approach base_load + for i in range(200) { + # Power gradually approaches base_load (1000W) + delta: float = 200.0 * exp(-0.5 * i);# Slower decay for better visualization + current_power: float = base + delta; + power_readings.append(current_power); + + # Time periods increase linearly + time_periods.append(15 + i * 2); + } + + # Initialize results storage + + efficiency_metrics: list = []; + total_operational_time: int = 0; + + # Process each power reading with different execution paths + for (idx, current_power) in enumerate(power_readings) { + if system_config['mode'] != 'active' { + continue; } - else { - y = 4; + + duration: int = time_periods[idx]; + if duration < system_config['min_duration'] { + continue; + } + + # Track simulation progression + + system_config['time_step'] += 1; + + power_delta: float = current_power - system_config['base_load']; + + # Introduce different execution paths based on time_step + if system_config['time_step'] > 50 { + diminishing_reference: float = power_delta * 2; # Reference point approaches zero with power_delta + power_utilization: float = power_delta / diminishing_reference; # Approaches 0.5, then unstable + } else { + # Original calculation path for first 10 steps + power_utilization: float = power_delta / system_config['reference_delta']; } + period_efficiency: float = power_utilization * (duration / max(time_periods)) * 100; + + efficiency_metrics.append(period_efficiency); + total_operational_time += duration; + + # Print current state + print( + f"Step {system_config['time_step']}: Power={current_power}W, " + f"Delta from base={current_power - system_config['base_load']}W" + ); } - z = x/y; - print(y); - print("hello"); + + # Calculate final metrics if no error occurred + + average_efficiency: float = sum(efficiency_metrics) / len(efficiency_metrics) if efficiency_metrics else 0; + operational_hours: float = total_operational_time / 60; + print( + f"System Analysis Complete - Efficiency: {average_efficiency}%" + ); + } + """ prompt = f""" I have the following script: @@ -135,7 +199,7 @@ def worker(self): if self.cfgs == None: print("waiting") self.cfg_cv.wait() - # print(self.cfgs) + print(self.cfgs) # for module_name, cfg in self.cfgs.items(): # print(f"Name: {module_name}\n{cfg.display_instructions()}") self.cfg_cv.release() @@ -202,7 +266,7 @@ def update_cfg(): time.sleep(1) print("\nUpdating cfgs") update_cfg() - # self.prompt_llm() + self.prompt_llm() self.finished_exception_lock.acquire() time.sleep(5) @@ -210,8 +274,9 @@ def update_cfg(): print("\nUpdating cfgs at the end") update_cfg() - # print(self.cfgs['hot_path'].display_instructions()) + print(self.cfgs['hot_path'].display_instructions()) self.prompt_llm() - print("STATIC RESULT") - self.prompt_direct() + # print("STATIC RESULT") + # self.prompt_direct() + From 220cc691dbf40a363a3f1fa88a5eed11d53c7d1c Mon Sep 17 00:00:00 2001 From: Jakob Louis Therkelsen Date: Sun, 1 Dec 2024 19:23:21 -0500 Subject: [PATCH 66/84] use history stuff as results example --- jac/jaclang/runtimelib/gins/ghost.py | 58 +++++++++++++++++++++++---- jac/jaclang/runtimelib/gins/tracer.py | 12 +++--- 2 files changed, 58 insertions(+), 12 deletions(-) diff --git a/jac/jaclang/runtimelib/gins/ghost.py b/jac/jaclang/runtimelib/gins/ghost.py index ee7261a386..ead3f67720 100644 --- a/jac/jaclang/runtimelib/gins/ghost.py +++ b/jac/jaclang/runtimelib/gins/ghost.py @@ -27,7 +27,7 @@ def __init__(self): self.model = Gemini() self.deque_lock = threading.Lock() - self.__cfg_deque = CfgDeque(2) + self.__cfg_deque = CfgDeque(5) def set_cfgs(self, cfgs): self.cfg_cv.acquire() @@ -193,13 +193,57 @@ def prompt_llm(self, verbose: bool = False): print("\nGin Analysis:\n", response) return response + def prompt_llm_with_history(self, verbose: bool = False): + prompt = """I have a program. + Up to last 5 CFGs recorded: + {cfgs}, + Instructions per basic block: + {instructions} + Semantic and Type information from source code: + {sem_ir}""" + + cfg_string = "" + ins_string = "" + for module, cfg in self.cfgs.items(): + cfg_string += f"Module: {module}\n{cfg}" + ins_string += f"Module: {module}\n{cfg.display_instructions()}" + + prompt = prompt.format( + cfgs=self.__cfg_deque.get_cfg_repr(), instructions=ins_string, sem_ir=self.sem_ir.pp() + ) + + if self.variable_values != None: + prompt += "\nCurrent variable values at the specified bytecode offset:" + + for module, var_map in self.variable_values.items(): + prompt += f"\nModule {module}: Offset: {var_map[0]}, Variables: {str(var_map[1])}" + + self.finished_exception_lock.acquire() + + if self.exception: + prompt += f"\nException: {self.exception}" + + self.finished_exception_lock.release() + + prompt += "\nCan you identity bottlneck optimizations or where the code can error out?" + prompt += "\n(Reason about the program using cfg history, semantic and type information. Users will not have access to BB information, so try to reason about the logic and frequencies of blocks instead.)" + prompt += "\n Additionally, look for any cases where the hot path of the code appears to change at some point in the program" + prompt += "\n If variable values are available, can you provide tracing information to help find the root cause of any issues?" + + if verbose: + print(prompt) + + response = self.model.generate(prompt) + + print("\nGin Analysis:\n", response) + return response + def worker(self): # get static cfgs self.cfg_cv.acquire() if self.cfgs == None: print("waiting") self.cfg_cv.wait() - print(self.cfgs) # for module_name, cfg in self.cfgs.items(): # print(f"Name: {module_name}\n{cfg.display_instructions()}") self.cfg_cv.release() @@ -251,6 +295,7 @@ def update_cfg(): current_executing_bbs[module] ].bytecode_offsets ) + self.__cfg_deque.add_cfg(cfg.get_cfg_repr()) except Exception as e: self.set_finished(e) print(e) @@ -266,7 +311,7 @@ def update_cfg(): time.sleep(1) print("\nUpdating cfgs") update_cfg() - self.prompt_llm() + self.prompt_llm_with_history() self.finished_exception_lock.acquire() time.sleep(5) @@ -274,9 +319,8 @@ def update_cfg(): print("\nUpdating cfgs at the end") update_cfg() - print(self.cfgs['hot_path'].display_instructions()) - self.prompt_llm() + self.prompt_llm_with_history() - # print("STATIC RESULT") - # self.prompt_direct() + print("STATIC RESULT") + self.prompt_direct() diff --git a/jac/jaclang/runtimelib/gins/tracer.py b/jac/jaclang/runtimelib/gins/tracer.py index 00b75155f4..a90a4322ce 100644 --- a/jac/jaclang/runtimelib/gins/tracer.py +++ b/jac/jaclang/runtimelib/gins/tracer.py @@ -20,11 +20,13 @@ def add_cfg(self, cfg_repr: str): if len(self.__deque) > self.__max_size: self.__deque.popleft() - def display_cfgs(self): - print("CFG change over updates\n") - for cfg in self.__deque: - print("\n") - print(cfg) + def get_cfg_repr(self): + res = [f"CFG Changes in last {len(self.__deque)} Updates:\n"] + for idx, cfg in enumerate(self.__deque): + res.append(f"\nCFG {idx+1} of {len(self.__deque)}\n") + res.append(cfg) + + return "".join(res) class CFGTracker: From 906a5ec4bd507e689bbd93502f1dd8f412e15b27 Mon Sep 17 00:00:00 2001 From: Jakob Louis Therkelsen Date: Tue, 3 Dec 2024 15:49:18 -0500 Subject: [PATCH 67/84] module based CFG history --- jac/jaclang/runtimelib/gins/ghost.py | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/jac/jaclang/runtimelib/gins/ghost.py b/jac/jaclang/runtimelib/gins/ghost.py index ead3f67720..9ed2e017ce 100644 --- a/jac/jaclang/runtimelib/gins/ghost.py +++ b/jac/jaclang/runtimelib/gins/ghost.py @@ -27,7 +27,8 @@ def __init__(self): self.model = Gemini() self.deque_lock = threading.Lock() - self.__cfg_deque = CfgDeque(5) + self.__cfg_deque_dict = dict() + self.__cfg_deque_size = 5 def set_cfgs(self, cfgs): self.cfg_cv.acquire() @@ -35,9 +36,11 @@ def set_cfgs(self, cfgs): self.cfg_cv.notify() self.cfg_cv.release() - def update_cfg_deque(self, cfg): + def update_cfg_deque(self, cfg, module): self.deque_lock.acquire() - self.__cfg_deque.add_cfg(cfg) + if module not in self.__cfg_deque_dict: + self.__cfg_deque_dict[module] = CfgDeque(self.__cfg_deque_size) + self.__cfg_deque_dict[module].add_cfg(cfg) self.deque_lock.release() def get_cfg_deque_repr(self): @@ -209,7 +212,7 @@ def prompt_llm_with_history(self, verbose: bool = False): ins_string += f"Module: {module}\n{cfg.display_instructions()}" prompt = prompt.format( - cfgs=self.__cfg_deque.get_cfg_repr(), instructions=ins_string, sem_ir=self.sem_ir.pp() + cfgs=self.__cfg_deque_dict['hot_path'].get_cfg_repr(), instructions=ins_string, sem_ir=self.sem_ir.pp() ) if self.variable_values != None: @@ -295,14 +298,15 @@ def update_cfg(): current_executing_bbs[module] ].bytecode_offsets ) - self.__cfg_deque.add_cfg(cfg.get_cfg_repr()) + # self.__cfg_deque.add_cfg(cfg.get_cfg_repr()) except Exception as e: self.set_finished(e) print(e) return self.variable_values = self.tracker.get_variable_values() - self.update_cfg_deque(cfg.get_cfg_repr()) + print("yeeee") + self.update_cfg_deque(cfg.get_cfg_repr(), module) self.finished_exception_lock.acquire() while not self.finished: @@ -310,6 +314,7 @@ def update_cfg(): time.sleep(1) print("\nUpdating cfgs") + print(self.__cfg_deque_dict) update_cfg() self.prompt_llm_with_history() self.finished_exception_lock.acquire() @@ -319,8 +324,5 @@ def update_cfg(): print("\nUpdating cfgs at the end") update_cfg() - self.prompt_llm_with_history() - - print("STATIC RESULT") - self.prompt_direct() + self.prompt_llm_with_history(verbose=True) From 90fff4a0501366f7ea90e74e18f42dbd79968b69 Mon Sep 17 00:00:00 2001 From: Jakob Louis Therkelsen Date: Tue, 3 Dec 2024 15:50:36 -0500 Subject: [PATCH 68/84] remove prints --- jac/jaclang/runtimelib/gins/ghost.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/jac/jaclang/runtimelib/gins/ghost.py b/jac/jaclang/runtimelib/gins/ghost.py index 9ed2e017ce..2df2cc1379 100644 --- a/jac/jaclang/runtimelib/gins/ghost.py +++ b/jac/jaclang/runtimelib/gins/ghost.py @@ -298,14 +298,12 @@ def update_cfg(): current_executing_bbs[module] ].bytecode_offsets ) - # self.__cfg_deque.add_cfg(cfg.get_cfg_repr()) except Exception as e: self.set_finished(e) print(e) return self.variable_values = self.tracker.get_variable_values() - print("yeeee") self.update_cfg_deque(cfg.get_cfg_repr(), module) self.finished_exception_lock.acquire() @@ -314,7 +312,6 @@ def update_cfg(): time.sleep(1) print("\nUpdating cfgs") - print(self.__cfg_deque_dict) update_cfg() self.prompt_llm_with_history() self.finished_exception_lock.acquire() From c7c2ef070feee34fdbbfb2fe416f9b2e4095b80b Mon Sep 17 00:00:00 2001 From: Jakob Louis Therkelsen Date: Tue, 3 Dec 2024 17:34:57 -0500 Subject: [PATCH 69/84] final changes --- jac/jaclang/runtimelib/gins/ghost.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/jac/jaclang/runtimelib/gins/ghost.py b/jac/jaclang/runtimelib/gins/ghost.py index 2df2cc1379..40b1b54f79 100644 --- a/jac/jaclang/runtimelib/gins/ghost.py +++ b/jac/jaclang/runtimelib/gins/ghost.py @@ -154,7 +154,6 @@ def prompt_direct(self): def prompt_llm(self, verbose: bool = False): prompt = """I have a program. - CFGS: {cfgs}, Instructions per basic block: {instructions} @@ -198,7 +197,7 @@ def prompt_llm(self, verbose: bool = False): def prompt_llm_with_history(self, verbose: bool = False): prompt = """I have a program. - Up to last 5 CFGs recorded: + Up to last {history_size} CFGs recorded: {cfgs}, Instructions per basic block: {instructions} @@ -208,11 +207,14 @@ def prompt_llm_with_history(self, verbose: bool = False): cfg_string = "" ins_string = "" for module, cfg in self.cfgs.items(): - cfg_string += f"Module: {module}\n{cfg}" + cfg_string += f"Module: {module}\n{self.__cfg_deque_dict[module].get_cfg_repr()}" ins_string += f"Module: {module}\n{cfg.display_instructions()}" prompt = prompt.format( - cfgs=self.__cfg_deque_dict['hot_path'].get_cfg_repr(), instructions=ins_string, sem_ir=self.sem_ir.pp() + history_size=self.__cfg_deque_size, + cfgs=cfg_string, + instructions=ins_string, + sem_ir=self.sem_ir.pp() ) if self.variable_values != None: From e02ddd30fe18929ab7c0d5e56bdedc01c9a6a10e Mon Sep 17 00:00:00 2001 From: Jakob Louis Therkelsen Date: Tue, 3 Dec 2024 18:32:39 -0500 Subject: [PATCH 70/84] test json output --- jac/jaclang/runtimelib/gins/cfg.py | 16 ++++++++++++++++ jac/jaclang/runtimelib/gins/ghost.py | 10 ++++++---- jac/jaclang/runtimelib/gins/model.py | 4 ++-- 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/jac/jaclang/runtimelib/gins/cfg.py b/jac/jaclang/runtimelib/gins/cfg.py index 28dbf15118..6fb4df6911 100644 --- a/jac/jaclang/runtimelib/gins/cfg.py +++ b/jac/jaclang/runtimelib/gins/cfg.py @@ -200,6 +200,22 @@ def display_instructions(self): def get_cfg_repr(self): return self.__repr__() + def to_json(self): + obj = {'timestamp':0,'cfg_bbs':[]} + for node in self.nodes: + bb_obj = { + 'bb_id': node, + 'freq':self.block_map.idx_to_block[node].exec_count, + 'edges':[] + } + if node in self.edges and self.edges[node]: + for succ in self.edges[node]: + edge_obj = {'edge_to':succ,'freq': self.edge_counts[(node, succ)]} + bb_obj['edges'].append(edge_obj) + bb_obj['edges'].append(edge_obj) + obj['cfg_bbs'].append(bb_obj) + return obj + def __repr__(self): result = [] for node in self.nodes: diff --git a/jac/jaclang/runtimelib/gins/ghost.py b/jac/jaclang/runtimelib/gins/ghost.py index 40b1b54f79..9a39de6adb 100644 --- a/jac/jaclang/runtimelib/gins/ghost.py +++ b/jac/jaclang/runtimelib/gins/ghost.py @@ -240,7 +240,7 @@ def prompt_llm_with_history(self, verbose: bool = False): response = self.model.generate(prompt) - print("\nGin Analysis:\n", response) + return response def worker(self): @@ -315,13 +315,15 @@ def update_cfg(): time.sleep(1) print("\nUpdating cfgs") update_cfg() - self.prompt_llm_with_history() + # self.prompt_llm_with_history() self.finished_exception_lock.acquire() - time.sleep(5) + # time.sleep(5) self.finished_exception_lock.release() print("\nUpdating cfgs at the end") update_cfg() - self.prompt_llm_with_history(verbose=True) + # self.prompt_llm_with_history(verbose=True) + for module in self.cfgs.keys(): + print(self.cfgs[module].to_json()) diff --git a/jac/jaclang/runtimelib/gins/model.py b/jac/jaclang/runtimelib/gins/model.py index fca343f0aa..a4918c233d 100644 --- a/jac/jaclang/runtimelib/gins/model.py +++ b/jac/jaclang/runtimelib/gins/model.py @@ -1,7 +1,7 @@ +import typing_extensions as typing + """Generative AI model integration for GINS """ - - class BaseModel: def __init__(self, model_name: str = "gemini-1.5-flash", **kwargs): self.model_name = model_name From d1772ee8c0c7962ce2e7af43e804fe81a884ee27 Mon Sep 17 00:00:00 2001 From: Jakob Louis Therkelsen Date: Tue, 3 Dec 2024 18:34:02 -0500 Subject: [PATCH 71/84] more clear id name --- jac/jaclang/runtimelib/gins/cfg.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jac/jaclang/runtimelib/gins/cfg.py b/jac/jaclang/runtimelib/gins/cfg.py index 6fb4df6911..29ffa4cdbe 100644 --- a/jac/jaclang/runtimelib/gins/cfg.py +++ b/jac/jaclang/runtimelib/gins/cfg.py @@ -210,7 +210,7 @@ def to_json(self): } if node in self.edges and self.edges[node]: for succ in self.edges[node]: - edge_obj = {'edge_to':succ,'freq': self.edge_counts[(node, succ)]} + edge_obj = {'edge_to_bb_id':succ,'freq': self.edge_counts[(node, succ)]} bb_obj['edges'].append(edge_obj) bb_obj['edges'].append(edge_obj) obj['cfg_bbs'].append(bb_obj) From e497598bb544d1aa165c321d1febddd3aa9c3bb7 Mon Sep 17 00:00:00 2001 From: Johnson He Date: Wed, 4 Dec 2024 02:53:20 -0500 Subject: [PATCH 72/84] some bike shedding w/ settrace --- jac/test-tracer.py | 112 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 jac/test-tracer.py diff --git a/jac/test-tracer.py b/jac/test-tracer.py new file mode 100644 index 0000000000..e46bdca421 --- /dev/null +++ b/jac/test-tracer.py @@ -0,0 +1,112 @@ +import sys +import dis +import traceback +import types +from typing import Optional, Callable +import inspect +import ast +import ctypes +import warnings + +program_input = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22] + +def foo(x): + PROGRAM_INPUT = program_input + x = x + x + for i in PROGRAM_INPUT: + SPECIAL_VARIABLE = i + print("foo: SPECIAL_VARIABLE = ", i) + y = 2 * x + x += y + print("foo: x = ", x) + print("foo: y = ", y) + return x + +def trace(frame: types.FrameType, event: str, arg: any) -> Optional[Callable]: + if event == 'call': + # TODO: this example itself doesn't need opcode events + frame.f_trace_opcodes = True + # keep using this function as the local tracer for this function + frame.f_trace = trace + return trace + elif event == 'opcode': + #print(dis.opname[frame.f_code.co_code[frame.f_lasti]]) + #print((frame.f_code.co_code[frame.f_lasti])) + return trace + elif event == 'line': + #skip_line: Bool = getattr(trace, 'skip_line', False) + #if skip_line: + # #print(f"Skipped {frame.f_lineno}") + # return trace + ### + # this is really circumlocutious, but is also how + # [watchpoints](https://github.com/gaogaotiantian/watchpoints/tree/master) + # works + ### + s = inspect.getsource(frame.f_code) + #print(s) + o = frame.f_lineno - frame.f_code.co_firstlineno + l = s.split('\n')[o].lstrip() + try: + a = ast.parse(l) + except SyntaxError: + return trace + #print(ast.dump(a)) + assert len(a.body) == 1 # we only parsed one line + line_ast = a.body[0] + if isinstance(line_ast, ast.Assign) or isinstance(line_ast, ast.AugAssign): + # yes, I know this isn't strictly necessary in python + lhs_ast = None + rhs_ast = None + if isinstance(line_ast, ast.Assign): + assert len(line_ast.targets) == 1, "Only handling single targets right now" + lhs_ast = line_ast.targets[0] + elif isinstance(line_ast, ast.AugAssign): + lhs_ast = line_ast.target + lhs_var = lhs_ast.id + rhs_ast = line_ast.value + # NOTE: for some reason, eval(ast.Expression(rhs_ast)) doesn't work + rhs_value = eval(ast.unparse(rhs_ast), frame.f_globals, frame.f_locals) + #frame.f_locals[lhs_var] = rhs_value + #ctypes.pythonapi.PyFrame_LocalsToFast(ctypes.py_object(frame), ctypes.c_int(0)) + #if lhs_var in frame.f_locals: + # frame.f_locals[lhs_var] = rhs_value + #elif lhs_var in frame.f_globals: + # frame.f_globals[lhs_var] = rhs_value + #else: + # assert False, "I'm pretty sure this doesn't handle closures correctly, but we don't need that for this hack anyways" + # evaluating rhs again (after trace returns) would duplicate any + # side effects, so let's "skip" this line in the user program + #print("uhoh ", frame.f_lineno) + #trace.skip_line = True + #frame.f_lineno += 1 + if isinstance(line_ast, ast.Assign): + exec(f"{lhs_var} = {rhs_value}\n", frame.f_globals, frame.f_locals) + print(f"{lhs_var} = {rhs_value}") + elif isinstance(line_ast, ast.AugAssign): + exec(f"{lhs_var} += {rhs_value}\n", frame.f_globals, frame.f_locals) + print(f"{lhs_var} (+)= {rhs_value}") + #print(frame.f_locals) + if lhs_var == 'PROGRAM_INPUT': + if isinstance(line_ast, ast.AugAssign): + assert False, "Unimplemented" + print("tracer: PROGRAM_INPUT = ", rhs_value) + # this only silences some of the + # "RuntimeWarning: assigning None to unbound local" warnings + with warnings.catch_warnings(action="ignore"): + frame.f_lineno += 1 + return trace + elif event == 'return': + return None + else: + assert False + +print("Starting") +# TODO use sys.monitoring instead? +# needs to be set before settrace due to python 3.12 bug +# https://github.com/python/cpython/issues/114480#issuecomment-1906518084 +inspect.currentframe().f_trace_opcodes = True +sys.settrace(trace) +foo(1) +foo(2) +print("Finished") From 59a135cdf2834a9eed52ccdd53d837c379c01b46 Mon Sep 17 00:00:00 2001 From: Johnson He Date: Wed, 4 Dec 2024 03:28:24 -0500 Subject: [PATCH 73/84] really stupid and hacked way to "pass" program input to gins I lost track of what I should've been doing and did a bunch of random stuff that isn't very useful TODO: there's a weird bug where adding newlines around the PROGRAM_INPUT assignment can either cause - total_operational_time to not be initialized - the print("tracer: PROGRAM_INPUT...") line in the tracer to not print right now, it seems to "work" by reinitializing total_operational_time again... Presumably this has something to do with how we skip lines (frame.f_lineno += 1) in the tracer to avoid evaluating a (potentially side-effectful) assignment twice. After all the trouble this caused, we should've just set a flag when we assign to PROGRAM_INPUT and grabbed the value on the next breakpoint. --- jac/examples/gins_scripts/power.jac | 2 + jac/jaclang/runtimelib/gins/tracer.py | 66 +++++++++++++++++++++++++-- 2 files changed, 63 insertions(+), 5 deletions(-) diff --git a/jac/examples/gins_scripts/power.jac b/jac/examples/gins_scripts/power.jac index 398f22817e..dc8ba53920 100644 --- a/jac/examples/gins_scripts/power.jac +++ b/jac/examples/gins_scripts/power.jac @@ -32,6 +32,8 @@ with entry { efficiency_metrics: list = []; total_operational_time: int = 0; + PROGRAM_INPUT = power_readings; + total_operational_time: int = 0; # Process each power reading with different execution paths for (idx, current_power) in enumerate(power_readings) { diff --git a/jac/jaclang/runtimelib/gins/tracer.py b/jac/jaclang/runtimelib/gins/tracer.py index a90a4322ce..8d44eb61de 100644 --- a/jac/jaclang/runtimelib/gins/tracer.py +++ b/jac/jaclang/runtimelib/gins/tracer.py @@ -7,7 +7,12 @@ import sys import copy import os +import traceback +import dis from collections import deque +import inspect +import warnings +import ast class CfgDeque: @@ -66,15 +71,14 @@ def get_variable_values(self): def trace_callback( self, frame: types.FrameType, event: str, arg: any ) -> Optional[Callable]: - if event == "call": - frame.f_trace_opcodes = True - """Trace function to track executed branches""" code = frame.f_code if ".jac" not in code.co_filename: return self.trace_callback - if event == "opcode": + if event == "call": + frame.f_trace_opcodes = True + elif event == "opcode": # edge case to handle executing code not within a function filename = os.path.basename(code.co_filename) module = ( @@ -95,5 +99,57 @@ def trace_callback( variable_dict[var_name] = frame.f_locals[var_name] self.curr_variables[module] = (frame.f_lasti, variable_dict) self.curr_variables_lock.release() - + elif event == "line": + ### + # this is really circumlocutious, but is also how + # [watchpoints](https://github.com/gaogaotiantian/watchpoints/tree/master) + # works + ### + try: + #print(inspect.getsourcefile(frame.f_code)) + #print(frame.f_lineno) + # TODO: super inefficient but just for now + # inspect.getsource doesn't seem to work like it does for + # regular python (see test_tracer.py) + # NOTE: we're parsing jac lines as python, fingers crossed + with open(inspect.getsourcefile(frame.f_code)) as file: + l = [line.lstrip() for line in file][frame.f_lineno] + #print(" ", l) + l.rstrip(';') + a = ast.parse(l) + line_ast = a.body[0] + #print(" ", ast.unparse(line_ast)) + except (IndexError, SyntaxError): + return self.trace_callback + #print(ast.dump(a)) + #print(len(a.body)) + assert len(a.body) == 1 # we only parsed one line + if isinstance(line_ast, ast.Assign) or isinstance(line_ast, ast.AugAssign): + # yes, I know this isn't strictly necessary in python + lhs_ast = None + rhs_ast = None + if isinstance(line_ast, ast.Assign): + assert len(line_ast.targets) == 1, "Only handling single targets right now" + lhs_ast = line_ast.targets[0] + elif isinstance(line_ast, ast.AugAssign): + lhs_ast = line_ast.target + lhs_var = lhs_ast.id + rhs_ast = line_ast.value + # NOTE: for some reason, eval(ast.Expression(rhs_ast)) doesn't work + rhs_value = eval(ast.unparse(rhs_ast), frame.f_globals, frame.f_locals) + if isinstance(line_ast, ast.Assign): + exec(f"{lhs_var} = {rhs_value}\n", frame.f_globals, frame.f_locals) + print(f"{lhs_var} = {rhs_value}") + elif isinstance(line_ast, ast.AugAssign): + exec(f"{lhs_var} += {rhs_value}\n", frame.f_globals, frame.f_locals) + print(f"{lhs_var} (+)= {rhs_value}") + #print(frame.f_locals) + if lhs_var == 'PROGRAM_INPUT': + if isinstance(line_ast, ast.AugAssign): + assert False, "Unimplemented" + print("tracer: PROGRAM_INPUT = ", rhs_value) + # this only silences some of the + # "RuntimeWarning: assigning None to unbound local" warnings + with warnings.catch_warnings(action="ignore"): + frame.f_lineno += 1 return self.trace_callback From a716b9535e700ae61fb85cef634d0a80f7ea1591 Mon Sep 17 00:00:00 2001 From: Johnson He Date: Wed, 4 Dec 2024 10:04:36 -0500 Subject: [PATCH 74/84] off by 1 --- jac/jaclang/runtimelib/gins/tracer.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/jac/jaclang/runtimelib/gins/tracer.py b/jac/jaclang/runtimelib/gins/tracer.py index 8d44eb61de..7b9883f065 100644 --- a/jac/jaclang/runtimelib/gins/tracer.py +++ b/jac/jaclang/runtimelib/gins/tracer.py @@ -113,12 +113,12 @@ def trace_callback( # regular python (see test_tracer.py) # NOTE: we're parsing jac lines as python, fingers crossed with open(inspect.getsourcefile(frame.f_code)) as file: - l = [line.lstrip() for line in file][frame.f_lineno] + l = [line.lstrip() for line in file][frame.f_lineno - 1] #print(" ", l) l.rstrip(';') a = ast.parse(l) line_ast = a.body[0] - #print(" ", ast.unparse(line_ast)) + #print(" ", frame.f_lineno, ast.unparse(line_ast)) except (IndexError, SyntaxError): return self.trace_callback #print(ast.dump(a)) @@ -133,7 +133,7 @@ def trace_callback( lhs_ast = line_ast.targets[0] elif isinstance(line_ast, ast.AugAssign): lhs_ast = line_ast.target - lhs_var = lhs_ast.id + lhs_var = ast.unparse(lhs_ast) rhs_ast = line_ast.value # NOTE: for some reason, eval(ast.Expression(rhs_ast)) doesn't work rhs_value = eval(ast.unparse(rhs_ast), frame.f_globals, frame.f_locals) From 6cb108f662c8f98fdd2194956f24200361e42efd Mon Sep 17 00:00:00 2001 From: Johnson He Date: Wed, 4 Dec 2024 10:20:12 -0500 Subject: [PATCH 75/84] this and the last commit should fix the TODOs in 59a135c --- jac/examples/gins_scripts/power.jac | 2 +- jac/jaclang/runtimelib/gins/tracer.py | 9 +++------ 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/jac/examples/gins_scripts/power.jac b/jac/examples/gins_scripts/power.jac index dc8ba53920..8c1e4a5236 100644 --- a/jac/examples/gins_scripts/power.jac +++ b/jac/examples/gins_scripts/power.jac @@ -32,8 +32,8 @@ with entry { efficiency_metrics: list = []; total_operational_time: int = 0; + PROGRAM_INPUT = power_readings; - total_operational_time: int = 0; # Process each power reading with different execution paths for (idx, current_power) in enumerate(power_readings) { diff --git a/jac/jaclang/runtimelib/gins/tracer.py b/jac/jaclang/runtimelib/gins/tracer.py index 7b9883f065..6adae714ac 100644 --- a/jac/jaclang/runtimelib/gins/tracer.py +++ b/jac/jaclang/runtimelib/gins/tracer.py @@ -113,17 +113,14 @@ def trace_callback( # regular python (see test_tracer.py) # NOTE: we're parsing jac lines as python, fingers crossed with open(inspect.getsourcefile(frame.f_code)) as file: - l = [line.lstrip() for line in file][frame.f_lineno - 1] - #print(" ", l) - l.rstrip(';') - a = ast.parse(l) - line_ast = a.body[0] + line_asts = ast.parse(file.readlines()[frame.f_lineno - 1].lstrip().rstrip(';')) #print(" ", frame.f_lineno, ast.unparse(line_ast)) except (IndexError, SyntaxError): return self.trace_callback #print(ast.dump(a)) #print(len(a.body)) - assert len(a.body) == 1 # we only parsed one line + assert len(line_asts.body) == 1 # we only parsed one line + line_ast = line_asts.body[0] if isinstance(line_ast, ast.Assign) or isinstance(line_ast, ast.AugAssign): # yes, I know this isn't strictly necessary in python lhs_ast = None From 9a1a0c59c2fb6d8e8faf216d1a9204037e591667 Mon Sep 17 00:00:00 2001 From: Jakob Louis Therkelsen Date: Wed, 4 Dec 2024 15:40:09 -0500 Subject: [PATCH 76/84] example with input --- jac/examples/gins_scripts/cfg.gv | 15 +++++++++++---- jac/examples/gins_scripts/cfg.gv.pdf | Bin 12051 -> 13248 bytes jac/examples/gins_scripts/hot_path.jac | 16 ++++++++++++++++ jac/examples/gins_scripts/inputs/test.txt | 5 +++++ jac/examples/gins_scripts/test.jac | 12 ++++++++++++ 5 files changed, 44 insertions(+), 4 deletions(-) create mode 100644 jac/examples/gins_scripts/inputs/test.txt create mode 100644 jac/examples/gins_scripts/test.jac diff --git a/jac/examples/gins_scripts/cfg.gv b/jac/examples/gins_scripts/cfg.gv index 677f5b02e7..54fec36365 100644 --- a/jac/examples/gins_scripts/cfg.gv +++ b/jac/examples/gins_scripts/cfg.gv @@ -8,14 +8,21 @@ digraph { bb5 [label=BB5] bb6 [label=BB6] bb7 [label=BB7] - bb0 -> bb7 + bb8 [label=BB8] + bb9 [label=BB9] + bb10 [label=BB10] + bb0 -> bb2 bb0 -> bb1 bb1 -> bb3 - bb1 -> bb2 - bb2 -> bb4 + bb2 -> bb3 + bb3 -> bb10 bb3 -> bb4 bb4 -> bb6 bb4 -> bb5 - bb5 -> bb1 + bb5 -> bb7 bb6 -> bb7 + bb7 -> bb9 + bb7 -> bb8 + bb8 -> bb4 + bb9 -> bb10 } diff --git a/jac/examples/gins_scripts/cfg.gv.pdf b/jac/examples/gins_scripts/cfg.gv.pdf index 9e44a974bdd78a2f83a0441e9dd70d3de98e06bc..9bf344a9cec12e0e563fae4706fbc81563f1f636 100644 GIT binary patch delta 11912 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

17rFXYHM?ws_T{en%lxozpT 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

^|}^!T}xR_Ka6HspT%or(CdG;csw4COUsg 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 NI508_B_%~qMhY^Q+O+@x diff --git a/jac/examples/gins_scripts/hot_path.jac b/jac/examples/gins_scripts/hot_path.jac index c852db6877..d0d0a1a560 100644 --- a/jac/examples/gins_scripts/hot_path.jac +++ b/jac/examples/gins_scripts/hot_path.jac @@ -1,7 +1,23 @@ +import:py os; + +can getInput() -> list[int] { + current_directory = os.path.dirname(os.path.abspath(__file__)); + input_dir = os.path.join(current_directory,'inputs/test.txt'); + print(input_dir); + with open(input_dir, 'r') as file{ + for line in file{ + # Process each line here + print(line.strip()); # .strip() removes trailing newlines + } + } + return [4,3,2,1]; +} + with entry { a:int = 0; b:int = 0; c:int = 0; + in_vals:list[int] = getInput(); while a < 30000 { if a % 2 == 0{ c = a+b+7; diff --git a/jac/examples/gins_scripts/inputs/test.txt b/jac/examples/gins_scripts/inputs/test.txt new file mode 100644 index 0000000000..ed41ba1336 --- /dev/null +++ b/jac/examples/gins_scripts/inputs/test.txt @@ -0,0 +1,5 @@ +1 +2 +3 +4 +"ye" \ No newline at end of file diff --git a/jac/examples/gins_scripts/test.jac b/jac/examples/gins_scripts/test.jac new file mode 100644 index 0000000000..6f6d124a54 --- /dev/null +++ b/jac/examples/gins_scripts/test.jac @@ -0,0 +1,12 @@ +import:py os; +with entry { + current_directory = os.path.dirname(os.path.abspath(__file__)); + input_dir = os.path.join(current_directory,'inputs/test.txt'); + print(input_dir); + with open(input_dir, 'r') as file{ + for line in file{ + # Process each line here + print(line.strip()); # .strip() removes trailing newlines + } + } +} \ No newline at end of file From 56387f3643a63803c37388ae3d5b4eb4423819fc Mon Sep 17 00:00:00 2001 From: Jakob Louis Therkelsen Date: Wed, 4 Dec 2024 16:43:32 -0500 Subject: [PATCH 77/84] example of modules not working :/ --- jac/examples/gins_scripts/hot_path.jac | 11 +++++----- .../{test.jac => import_helper.jac} | 9 ++++---- jac/examples/gins_scripts/import_helper.py | 9 ++++++++ jac/examples/gins_scripts/inputs/test.txt | 3 +-- .../compiler/passes/main/cfg_gen_pass.py | 6 ++--- jac/jaclang/runtimelib/gins/ghost.py | 22 ++++++++++++++----- 6 files changed, 38 insertions(+), 22 deletions(-) rename jac/examples/gins_scripts/{test.jac => import_helper.jac} (73%) create mode 100644 jac/examples/gins_scripts/import_helper.py diff --git a/jac/examples/gins_scripts/hot_path.jac b/jac/examples/gins_scripts/hot_path.jac index d0d0a1a560..06967760dd 100644 --- a/jac/examples/gins_scripts/hot_path.jac +++ b/jac/examples/gins_scripts/hot_path.jac @@ -1,23 +1,22 @@ import:py os; -can getInput() -> list[int] { +can import_inputs() { current_directory = os.path.dirname(os.path.abspath(__file__)); input_dir = os.path.join(current_directory,'inputs/test.txt'); - print(input_dir); - with open(input_dir, 'r') as file{ - for line in file{ + with open(input_dir, 'r') as file { + for line in file { # Process each line here print(line.strip()); # .strip() removes trailing newlines } } - return [4,3,2,1]; } + with entry { a:int = 0; b:int = 0; c:int = 0; - in_vals:list[int] = getInput(); + in_vals:list[int] = import_inputs(); while a < 30000 { if a % 2 == 0{ c = a+b+7; diff --git a/jac/examples/gins_scripts/test.jac b/jac/examples/gins_scripts/import_helper.jac similarity index 73% rename from jac/examples/gins_scripts/test.jac rename to jac/examples/gins_scripts/import_helper.jac index 6f6d124a54..11d4255ae6 100644 --- a/jac/examples/gins_scripts/test.jac +++ b/jac/examples/gins_scripts/import_helper.jac @@ -1,12 +1,11 @@ import:py os; -with entry { +can import_inputs() { current_directory = os.path.dirname(os.path.abspath(__file__)); input_dir = os.path.join(current_directory,'inputs/test.txt'); - print(input_dir); - with open(input_dir, 'r') as file{ - for line in file{ + with open(input_dir, 'r') as file { + for line in file { # Process each line here print(line.strip()); # .strip() removes trailing newlines } } -} \ No newline at end of file +} diff --git a/jac/examples/gins_scripts/import_helper.py b/jac/examples/gins_scripts/import_helper.py new file mode 100644 index 0000000000..3b2dcaaa6a --- /dev/null +++ b/jac/examples/gins_scripts/import_helper.py @@ -0,0 +1,9 @@ +import os +def import_inputs(): + current_directory = os.path.dirname(os.path.abspath(__file__)) + input_dir = os.path.join(current_directory,'inputs/test.txt') + print(input_dir) + with open(input_dir, 'r') as file: + for line in file: + # Process each line here + print(line.strip()) # .strip() removes trailing newlines \ No newline at end of file diff --git a/jac/examples/gins_scripts/inputs/test.txt b/jac/examples/gins_scripts/inputs/test.txt index ed41ba1336..b17865743d 100644 --- a/jac/examples/gins_scripts/inputs/test.txt +++ b/jac/examples/gins_scripts/inputs/test.txt @@ -1,5 +1,4 @@ 1 2 3 -4 -"ye" \ No newline at end of file +4 \ No newline at end of file diff --git a/jac/jaclang/compiler/passes/main/cfg_gen_pass.py b/jac/jaclang/compiler/passes/main/cfg_gen_pass.py index e10f9ba90c..fb1df7942f 100644 --- a/jac/jaclang/compiler/passes/main/cfg_gen_pass.py +++ b/jac/jaclang/compiler/passes/main/cfg_gen_pass.py @@ -37,9 +37,9 @@ def enter_module(self, node: ast.Module) -> None: BBs = create_BBs(instructions) cfg = create_cfg(BBs) module_cfgs[mod.name] = cfg - # for cfg in module_cfgs.values(): - # dot = visualize_cfg(cfg) - # dot.render('cfg.gv', view=True) + # for cfg in module_cfgs.values(): + # dot = visualize_cfg(cfg) + # dot.render(f'cfg_{mod.name}.gv', view=True) if JacMachine.get().gin: try: JacMachine.get().gin.set_cfgs(cfgs=module_cfgs) diff --git a/jac/jaclang/runtimelib/gins/ghost.py b/jac/jaclang/runtimelib/gins/ghost.py index 40b1b54f79..c92712a15b 100644 --- a/jac/jaclang/runtimelib/gins/ghost.py +++ b/jac/jaclang/runtimelib/gins/ghost.py @@ -207,7 +207,10 @@ def prompt_llm_with_history(self, verbose: bool = False): cfg_string = "" ins_string = "" for module, cfg in self.cfgs.items(): - cfg_string += f"Module: {module}\n{self.__cfg_deque_dict[module].get_cfg_repr()}" + cfg_history = "None at this time" + if module in self.__cfg_deque_dict: + cfg_history = self.__cfg_deque_dict[module].get_cfg_repr() + cfg_string += f"Module: {module}\n{cfg_history}" ins_string += f"Module: {module}\n{cfg.display_instructions()}" prompt = prompt.format( @@ -249,9 +252,12 @@ def worker(self): if self.cfgs == None: print("waiting") self.cfg_cv.wait() - # for module_name, cfg in self.cfgs.items(): - # print(f"Name: {module_name}\n{cfg.display_instructions()}") + for module_name, cfg in self.cfgs.items(): + print(f"Name: {module_name}") self.cfg_cv.release() + print("CFG INFO") + print(self.cfgs) + print("EO CFG INFO") # Once cv has been notifie, self.cfgs is no longer accessed across threads current_executing_bbs = {} @@ -315,13 +321,17 @@ def update_cfg(): time.sleep(1) print("\nUpdating cfgs") update_cfg() - self.prompt_llm_with_history() + # self.prompt_llm_with_history() self.finished_exception_lock.acquire() - time.sleep(5) + time.sleep(1) self.finished_exception_lock.release() print("\nUpdating cfgs at the end") update_cfg() - self.prompt_llm_with_history(verbose=True) + print("CCURRRENT CFG STUFFFFFF") + for module, cfg in self.cfgs.items(): + print(module) + print(cfg) + # self.prompt_llm_with_history(verbose=True) From a43118f7c04f3ca948c402f80c691b8ab07e7f2a Mon Sep 17 00:00:00 2001 From: Jakob Louis Therkelsen Date: Wed, 4 Dec 2024 18:37:26 -0500 Subject: [PATCH 78/84] inlining inputs --- jac/examples/gins_scripts/hot_path.jac | 16 ++++++---------- jac/examples/gins_scripts/import_helper.jac | 4 +++- jac/examples/gins_scripts/import_helper.py | 5 +++-- 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/jac/examples/gins_scripts/hot_path.jac b/jac/examples/gins_scripts/hot_path.jac index 06967760dd..b26ca3f08d 100644 --- a/jac/examples/gins_scripts/hot_path.jac +++ b/jac/examples/gins_scripts/hot_path.jac @@ -1,22 +1,18 @@ import:py os; -can import_inputs() { +with entry { + a:int = 0; + b:int = 0; + c:int = 0; current_directory = os.path.dirname(os.path.abspath(__file__)); input_dir = os.path.join(current_directory,'inputs/test.txt'); + var = []; with open(input_dir, 'r') as file { for line in file { # Process each line here - print(line.strip()); # .strip() removes trailing newlines + var.append(int(line.strip())); # .strip() removes trailing newlines } } -} - - -with entry { - a:int = 0; - b:int = 0; - c:int = 0; - in_vals:list[int] = import_inputs(); while a < 30000 { if a % 2 == 0{ c = a+b+7; diff --git a/jac/examples/gins_scripts/import_helper.jac b/jac/examples/gins_scripts/import_helper.jac index 11d4255ae6..e4b1092196 100644 --- a/jac/examples/gins_scripts/import_helper.jac +++ b/jac/examples/gins_scripts/import_helper.jac @@ -2,10 +2,12 @@ import:py os; can import_inputs() { current_directory = os.path.dirname(os.path.abspath(__file__)); input_dir = os.path.join(current_directory,'inputs/test.txt'); + var = []; with open(input_dir, 'r') as file { for line in file { # Process each line here - print(line.strip()); # .strip() removes trailing newlines + var.append(int(line.strip())); # .strip() removes trailing newlines } } + return var; } diff --git a/jac/examples/gins_scripts/import_helper.py b/jac/examples/gins_scripts/import_helper.py index 3b2dcaaa6a..df86376ad2 100644 --- a/jac/examples/gins_scripts/import_helper.py +++ b/jac/examples/gins_scripts/import_helper.py @@ -2,8 +2,9 @@ def import_inputs(): current_directory = os.path.dirname(os.path.abspath(__file__)) input_dir = os.path.join(current_directory,'inputs/test.txt') - print(input_dir) + inputs = [] with open(input_dir, 'r') as file: for line in file: # Process each line here - print(line.strip()) # .strip() removes trailing newlines \ No newline at end of file + inputs.append[int(line.strip())] # .strip() removes trailing newlines + return inputs \ No newline at end of file From 0710ce00da840d68dec504afe98cf4ae127f39fb Mon Sep 17 00:00:00 2001 From: Jakob Louis Therkelsen Date: Wed, 4 Dec 2024 19:50:41 -0500 Subject: [PATCH 79/84] random, but stable json output from llm --- jac/examples/gins_scripts/hot_path.jac | 5 +- jac/examples/gins_scripts/test.txt | 143 +++++++++++++++++++++++++ jac/jaclang/runtimelib/gins/cfg.py | 10 +- jac/jaclang/runtimelib/gins/ghost.py | 42 +++++--- jac/jaclang/runtimelib/gins/model.py | 25 ++++- jac/jaclang/runtimelib/gins/tracer.py | 106 +++++++++--------- 6 files changed, 257 insertions(+), 74 deletions(-) create mode 100644 jac/examples/gins_scripts/test.txt diff --git a/jac/examples/gins_scripts/hot_path.jac b/jac/examples/gins_scripts/hot_path.jac index b26ca3f08d..239a1f194e 100644 --- a/jac/examples/gins_scripts/hot_path.jac +++ b/jac/examples/gins_scripts/hot_path.jac @@ -21,6 +21,9 @@ with entry { else { b = 2 + c; } - a += 1; + a = a+ 1; + if a == 0{ + print("nothing"); + } } } \ No newline at end of file diff --git a/jac/examples/gins_scripts/test.txt b/jac/examples/gins_scripts/test.txt new file mode 100644 index 0000000000..98e903505b --- /dev/null +++ b/jac/examples/gins_scripts/test.txt @@ -0,0 +1,143 @@ +2024-12-04 19:15:21 - {'timestamp': 0, 'cfg_bbs': [{'bb_id': 0, 'freq': 1, 'edges': [{'edge_to_bb_id': 2, 'freq': 1}, {'edge_to_bb_id': 1, 'freq': 0}, {'edge_to_bb_id': 1, 'freq': 0}]}, {'bb_id': 1, 'freq': 0, 'edges': [{'edge_to_bb_id': 3, 'freq': 0}, {'edge_to_bb_id': 3, 'freq': 0}]}, {'bb_id': 2, 'freq': 1, 'edges': [{'edge_to_bb_id': 3, 'freq': 1}, {'edge_to_bb_id': 3, 'freq': 1}]}, {'bb_id': 3, 'freq': 1, 'edges': [{'edge_to_bb_id': 4, 'freq': 1}, {'edge_to_bb_id': 4, 'freq': 1}]}, {'bb_id': 4, 'freq': 1, 'edges': [{'edge_to_bb_id': 5, 'freq': 1}, {'edge_to_bb_id': 4, 'freq': 0}, {'edge_to_bb_id': 4, 'freq': 0}]}, {'bb_id': 5, 'freq': 1, 'edges': [{'edge_to_bb_id': 6, 'freq': 1}, {'edge_to_bb_id': 6, 'freq': 1}]}, {'bb_id': 6, 'freq': 1, 'edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 7, 'freq': 1}, {'edge_to_bb_id': 7, 'freq': 1}]}, {'bb_id': 7, 'freq': 12678, 'edges': [{'edge_to_bb_id': 9, 'freq': 6339}, {'edge_to_bb_id': 8, 'freq': 6339}, {'edge_to_bb_id': 8, 'freq': 6339}]}, {'bb_id': 8, 'freq': 6339, 'edges': [{'edge_to_bb_id': 10, 'freq': 6339}, {'edge_to_bb_id': 10, 'freq': 6339}]}, {'bb_id': 9, 'freq': 6339, 'edges': [{'edge_to_bb_id': 10, 'freq': 6339}, {'edge_to_bb_id': 10, 'freq': 6339}]}, {'bb_id': 10, 'freq': 12678, 'edges': [{'edge_to_bb_id': 12, 'freq': 12677}, {'edge_to_bb_id': 11, 'freq': 0}, {'edge_to_bb_id': 11, 'freq': 0}]}, {'bb_id': 11, 'freq': 0, 'edges': [{'edge_to_bb_id': 12, 'freq': 0}, {'edge_to_bb_id': 12, 'freq': 0}]}, {'bb_id': 12, 'freq': 12677, 'edges': [{'edge_to_bb_id': 14, 'freq': 0}, {'edge_to_bb_id': 13, 'freq': 12677}, {'edge_to_bb_id': 13, 'freq': 12677}]}, {'bb_id': 13, 'freq': 12677, 'edges': [{'edge_to_bb_id': 7, 'freq': 12677}, {'edge_to_bb_id': 7, 'freq': 12677}]}, {'bb_id': 14, 'freq': 0, 'edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 15, 'freq': 0}]}, {'bb_id': 15, 'freq': 0, 'edges': [{'edge_to_bb_id': 17, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}]}, {'bb_id': 16, 'freq': 0, 'edges': [{'edge_to_bb_id': 17, 'freq': 0}, {'edge_to_bb_id': 17, 'freq': 0}]}, {'bb_id': 17, 'freq': 0, 'edges': [{'edge_to_bb_id': 6, 'freq': 0}, {'edge_to_bb_id': 6, 'freq': 0}]}, {'bb_id': 18, 'freq': 0, 'edges': [{'edge_to_bb_id': 6, 'freq': 0}]}]} +2024-12-04 19:15:22 - {'timestamp': 0, 'cfg_bbs': [{'bb_id': 0, 'freq': 1, 'edges': [{'edge_to_bb_id': 2, 'freq': 1}, {'edge_to_bb_id': 1, 'freq': 0}, {'edge_to_bb_id': 1, 'freq': 0}]}, {'bb_id': 1, 'freq': 0, 'edges': [{'edge_to_bb_id': 3, 'freq': 0}, {'edge_to_bb_id': 3, 'freq': 0}]}, {'bb_id': 2, 'freq': 1, 'edges': [{'edge_to_bb_id': 3, 'freq': 1}, {'edge_to_bb_id': 3, 'freq': 1}]}, {'bb_id': 3, 'freq': 1, 'edges': [{'edge_to_bb_id': 4, 'freq': 1}, {'edge_to_bb_id': 4, 'freq': 1}]}, {'bb_id': 4, 'freq': 1, 'edges': [{'edge_to_bb_id': 5, 'freq': 1}, {'edge_to_bb_id': 4, 'freq': 0}, {'edge_to_bb_id': 4, 'freq': 0}]}, {'bb_id': 5, 'freq': 1, 'edges': [{'edge_to_bb_id': 6, 'freq': 1}, {'edge_to_bb_id': 6, 'freq': 1}]}, {'bb_id': 6, 'freq': 1, 'edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 7, 'freq': 1}, {'edge_to_bb_id': 7, 'freq': 1}]}, {'bb_id': 7, 'freq': 30000, 'edges': [{'edge_to_bb_id': 9, 'freq': 15000}, {'edge_to_bb_id': 8, 'freq': 15000}, {'edge_to_bb_id': 8, 'freq': 15000}]}, {'bb_id': 8, 'freq': 15000, 'edges': [{'edge_to_bb_id': 10, 'freq': 15000}, {'edge_to_bb_id': 10, 'freq': 15000}]}, {'bb_id': 9, 'freq': 15000, 'edges': [{'edge_to_bb_id': 10, 'freq': 15000}, {'edge_to_bb_id': 10, 'freq': 15000}]}, {'bb_id': 10, 'freq': 30000, 'edges': [{'edge_to_bb_id': 12, 'freq': 30000}, {'edge_to_bb_id': 11, 'freq': 0}, {'edge_to_bb_id': 11, 'freq': 0}]}, {'bb_id': 11, 'freq': 0, 'edges': [{'edge_to_bb_id': 12, 'freq': 0}, {'edge_to_bb_id': 12, 'freq': 0}]}, {'bb_id': 12, 'freq': 30000, 'edges': [{'edge_to_bb_id': 14, 'freq': 1}, {'edge_to_bb_id': 13, 'freq': 29999}, {'edge_to_bb_id': 13, 'freq': 29999}]}, {'bb_id': 13, 'freq': 29999, 'edges': [{'edge_to_bb_id': 7, 'freq': 29999}, {'edge_to_bb_id': 7, 'freq': 29999}]}, {'bb_id': 14, 'freq': 1, 'edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 15, 'freq': 0}]}, {'bb_id': 15, 'freq': 0, 'edges': [{'edge_to_bb_id': 17, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}]}, {'bb_id': 16, 'freq': 0, 'edges': [{'edge_to_bb_id': 17, 'freq': 0}, {'edge_to_bb_id': 17, 'freq': 0}]}, {'bb_id': 17, 'freq': 0, 'edges': [{'edge_to_bb_id': 6, 'freq': 0}, {'edge_to_bb_id': 6, 'freq': 0}]}, {'bb_id': 18, 'freq': 0, 'edges': [{'edge_to_bb_id': 6, 'freq': 0}]}]} +2024-12-04 19:15:22 - yo +2024-12-04 19:24:47 - {'timestamp': 0, 'cfg_bbs': [{'bb_id': 0, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 2, 'freq': 0}, {'edge_to_bb_id': 1, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 2, 'freq': 1}, {'edge_to_bb_id': 1, 'freq': 0}]}, {'bb_id': 1, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 0}]}, {'bb_id': 2, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 1}]}, {'bb_id': 3, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 4, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 4, 'freq': 1}]}, {'bb_id': 4, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 5, 'freq': 0}, {'edge_to_bb_id': 4, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 5, 'freq': 1}, {'edge_to_bb_id': 4, 'freq': 0}]}, {'bb_id': 5, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 1}]}, {'bb_id': 6, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 7, 'freq': 1}]}, {'bb_id': 7, 'freq': 10994, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}, {'edge_to_bb_id': 8, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 5496}, {'edge_to_bb_id': 8, 'freq': 5497}]}, {'bb_id': 8, 'freq': 5497, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 5497}]}, {'bb_id': 9, 'freq': 5496, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 5496}]}, {'bb_id': 10, 'freq': 10993, 'predicted_edges': [{'edge_to_bb_id': 12, 'freq': 0}, {'edge_to_bb_id': 11, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 12, 'freq': 10993}, {'edge_to_bb_id': 11, 'freq': 0}]}, {'bb_id': 11, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 12, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 12, 'freq': 0}]}, {'bb_id': 12, 'freq': 10993, 'predicted_edges': [{'edge_to_bb_id': 14, 'freq': 0}, {'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 14, 'freq': 0}, {'edge_to_bb_id': 13, 'freq': 10993}]}, {'bb_id': 13, 'freq': 10993, 'predicted_edges': [{'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 7, 'freq': 10993}]}, {'bb_id': 14, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 15, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 15, 'freq': 0}]}, {'bb_id': 15, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 17, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 17, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}]}, {'bb_id': 16, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 17, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 17, 'freq': 0}]}, {'bb_id': 17, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 0}]}, {'bb_id': 18, 'freq': 0, 'predicted_edges': [], 'actual_edges': []}]} +2024-12-04 19:24:49 - {'timestamp': 0, 'cfg_bbs': [{'bb_id': 0, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 2, 'freq': 0}, {'edge_to_bb_id': 1, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 2, 'freq': 1}, {'edge_to_bb_id': 1, 'freq': 0}]}, {'bb_id': 1, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 0}]}, {'bb_id': 2, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 1}]}, {'bb_id': 3, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 4, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 4, 'freq': 1}]}, {'bb_id': 4, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 5, 'freq': 0}, {'edge_to_bb_id': 4, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 5, 'freq': 1}, {'edge_to_bb_id': 4, 'freq': 0}]}, {'bb_id': 5, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 1}]}, {'bb_id': 6, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 7, 'freq': 1}]}, {'bb_id': 7, 'freq': 28050, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}, {'edge_to_bb_id': 8, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 14024}, {'edge_to_bb_id': 8, 'freq': 14025}]}, {'bb_id': 8, 'freq': 14025, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 14025}]}, {'bb_id': 9, 'freq': 14024, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 14024}]}, {'bb_id': 10, 'freq': 28049, 'predicted_edges': [{'edge_to_bb_id': 12, 'freq': 0}, {'edge_to_bb_id': 11, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 12, 'freq': 28049}, {'edge_to_bb_id': 11, 'freq': 0}]}, {'bb_id': 11, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 12, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 12, 'freq': 0}]}, {'bb_id': 12, 'freq': 28049, 'predicted_edges': [{'edge_to_bb_id': 14, 'freq': 0}, {'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 14, 'freq': 0}, {'edge_to_bb_id': 13, 'freq': 28049}]}, {'bb_id': 13, 'freq': 28049, 'predicted_edges': [{'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 7, 'freq': 28049}]}, {'bb_id': 14, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 15, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 15, 'freq': 0}]}, {'bb_id': 15, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 17, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 17, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}]}, {'bb_id': 16, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 17, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 17, 'freq': 0}]}, {'bb_id': 17, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 0}]}, {'bb_id': 18, 'freq': 0, 'predicted_edges': [], 'actual_edges': []}]} +2024-12-04 19:24:49 - {'timestamp': 0, 'cfg_bbs': [{'bb_id': 0, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 2, 'freq': 0}, {'edge_to_bb_id': 1, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 2, 'freq': 1}, {'edge_to_bb_id': 1, 'freq': 0}]}, {'bb_id': 1, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 0}]}, {'bb_id': 2, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 1}]}, {'bb_id': 3, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 4, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 4, 'freq': 1}]}, {'bb_id': 4, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 5, 'freq': 0}, {'edge_to_bb_id': 4, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 5, 'freq': 1}, {'edge_to_bb_id': 4, 'freq': 0}]}, {'bb_id': 5, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 1}]}, {'bb_id': 6, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 7, 'freq': 1}]}, {'bb_id': 7, 'freq': 30000, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}, {'edge_to_bb_id': 8, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 15000}, {'edge_to_bb_id': 8, 'freq': 15000}]}, {'bb_id': 8, 'freq': 15000, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 15000}]}, {'bb_id': 9, 'freq': 15000, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 15000}]}, {'bb_id': 10, 'freq': 30000, 'predicted_edges': [{'edge_to_bb_id': 12, 'freq': 0}, {'edge_to_bb_id': 11, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 12, 'freq': 30000}, {'edge_to_bb_id': 11, 'freq': 0}]}, {'bb_id': 11, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 12, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 12, 'freq': 0}]}, {'bb_id': 12, 'freq': 30000, 'predicted_edges': [{'edge_to_bb_id': 14, 'freq': 0}, {'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 14, 'freq': 1}, {'edge_to_bb_id': 13, 'freq': 29999}]}, {'bb_id': 13, 'freq': 29999, 'predicted_edges': [{'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 7, 'freq': 29999}]}, {'bb_id': 14, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 15, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 15, 'freq': 0}]}, {'bb_id': 15, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 17, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 17, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}]}, {'bb_id': 16, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 17, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 17, 'freq': 0}]}, {'bb_id': 17, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 0}]}, {'bb_id': 18, 'freq': 0, 'predicted_edges': [], 'actual_edges': []}]} +2024-12-04 19:24:49 - yo +2024-12-04 19:27:08 - {'cfg_bbs': [{'bb_id': 0, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 2, 'freq': 0}, {'edge_to_bb_id': 1, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 2, 'freq': 1}, {'edge_to_bb_id': 1, 'freq': 0}]}, {'bb_id': 1, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 0}]}, {'bb_id': 2, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 1}]}, {'bb_id': 3, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 4, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 4, 'freq': 1}]}, {'bb_id': 4, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 5, 'freq': 0}, {'edge_to_bb_id': 4, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 5, 'freq': 1}, {'edge_to_bb_id': 4, 'freq': 0}]}, {'bb_id': 5, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 1}]}, {'bb_id': 6, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 7, 'freq': 1}]}, {'bb_id': 7, 'freq': 10517, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}, {'edge_to_bb_id': 8, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 5258}, {'edge_to_bb_id': 8, 'freq': 5259}]}, {'bb_id': 8, 'freq': 5259, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 5259}]}, {'bb_id': 9, 'freq': 5258, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 5258}]}, {'bb_id': 10, 'freq': 10517, 'predicted_edges': [{'edge_to_bb_id': 12, 'freq': 0}, {'edge_to_bb_id': 11, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 12, 'freq': 10516}, {'edge_to_bb_id': 11, 'freq': 0}]}, {'bb_id': 11, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 12, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 12, 'freq': 0}]}, {'bb_id': 12, 'freq': 10516, 'predicted_edges': [{'edge_to_bb_id': 14, 'freq': 0}, {'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 14, 'freq': 0}, {'edge_to_bb_id': 13, 'freq': 10516}]}, {'bb_id': 13, 'freq': 10516, 'predicted_edges': [{'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 7, 'freq': 10516}]}, {'bb_id': 14, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 15, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 15, 'freq': 0}]}, {'bb_id': 15, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 17, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 17, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}]}, {'bb_id': 16, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 17, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 17, 'freq': 0}]}, {'bb_id': 17, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 0}]}, {'bb_id': 18, 'freq': 0, 'predicted_edges': [], 'actual_edges': []}]} +2024-12-04 19:27:10 - {'cfg_bbs': [{'bb_id': 0, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 2, 'freq': 0}, {'edge_to_bb_id': 1, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 2, 'freq': 1}, {'edge_to_bb_id': 1, 'freq': 0}]}, {'bb_id': 1, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 0}]}, {'bb_id': 2, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 1}]}, {'bb_id': 3, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 4, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 4, 'freq': 1}]}, {'bb_id': 4, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 5, 'freq': 0}, {'edge_to_bb_id': 4, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 5, 'freq': 1}, {'edge_to_bb_id': 4, 'freq': 0}]}, {'bb_id': 5, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 1}]}, {'bb_id': 6, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 7, 'freq': 1}]}, {'bb_id': 7, 'freq': 26337, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}, {'edge_to_bb_id': 8, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 13168}, {'edge_to_bb_id': 8, 'freq': 13169}]}, {'bb_id': 8, 'freq': 13169, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 13168}]}, {'bb_id': 9, 'freq': 13168, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 13168}]}, {'bb_id': 10, 'freq': 26336, 'predicted_edges': [{'edge_to_bb_id': 12, 'freq': 0}, {'edge_to_bb_id': 11, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 12, 'freq': 26336}, {'edge_to_bb_id': 11, 'freq': 0}]}, {'bb_id': 11, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 12, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 12, 'freq': 0}]}, {'bb_id': 12, 'freq': 26336, 'predicted_edges': [{'edge_to_bb_id': 14, 'freq': 0}, {'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 14, 'freq': 0}, {'edge_to_bb_id': 13, 'freq': 26336}]}, {'bb_id': 13, 'freq': 26336, 'predicted_edges': [{'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 7, 'freq': 26336}]}, {'bb_id': 14, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 15, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 15, 'freq': 0}]}, {'bb_id': 15, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 17, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 17, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}]}, {'bb_id': 16, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 17, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 17, 'freq': 0}]}, {'bb_id': 17, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 0}]}, {'bb_id': 18, 'freq': 0, 'predicted_edges': [], 'actual_edges': []}]} +2024-12-04 19:27:10 - {'cfg_bbs': [{'bb_id': 0, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 2, 'freq': 0}, {'edge_to_bb_id': 1, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 2, 'freq': 1}, {'edge_to_bb_id': 1, 'freq': 0}]}, {'bb_id': 1, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 0}]}, {'bb_id': 2, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 1}]}, {'bb_id': 3, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 4, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 4, 'freq': 1}]}, {'bb_id': 4, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 5, 'freq': 0}, {'edge_to_bb_id': 4, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 5, 'freq': 1}, {'edge_to_bb_id': 4, 'freq': 0}]}, {'bb_id': 5, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 1}]}, {'bb_id': 6, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 7, 'freq': 1}]}, {'bb_id': 7, 'freq': 30000, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}, {'edge_to_bb_id': 8, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 15000}, {'edge_to_bb_id': 8, 'freq': 15000}]}, {'bb_id': 8, 'freq': 15000, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 15000}]}, {'bb_id': 9, 'freq': 15000, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 15000}]}, {'bb_id': 10, 'freq': 30000, 'predicted_edges': [{'edge_to_bb_id': 12, 'freq': 0}, {'edge_to_bb_id': 11, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 12, 'freq': 30000}, {'edge_to_bb_id': 11, 'freq': 0}]}, {'bb_id': 11, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 12, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 12, 'freq': 0}]}, {'bb_id': 12, 'freq': 30000, 'predicted_edges': [{'edge_to_bb_id': 14, 'freq': 0}, {'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 14, 'freq': 1}, {'edge_to_bb_id': 13, 'freq': 29999}]}, {'bb_id': 13, 'freq': 29999, 'predicted_edges': [{'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 7, 'freq': 29999}]}, {'bb_id': 14, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 15, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 15, 'freq': 0}]}, {'bb_id': 15, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 17, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 17, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}]}, {'bb_id': 16, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 17, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 17, 'freq': 0}]}, {'bb_id': 17, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 0}]}, {'bb_id': 18, 'freq': 0, 'predicted_edges': [], 'actual_edges': []}]} +2024-12-04 19:27:10 - yo +2024-12-04 19:35:07 - {'cfg_bbs': [{'bb_id': 0, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 2, 'freq': 0}, {'edge_to_bb_id': 1, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 2, 'freq': 1}, {'edge_to_bb_id': 1, 'freq': 0}]}, {'bb_id': 1, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 0}]}, {'bb_id': 2, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 1}]}, {'bb_id': 3, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 4, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 4, 'freq': 1}]}, {'bb_id': 4, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 5, 'freq': 0}, {'edge_to_bb_id': 4, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 5, 'freq': 1}, {'edge_to_bb_id': 4, 'freq': 0}]}, {'bb_id': 5, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 1}]}, {'bb_id': 6, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 7, 'freq': 1}]}, {'bb_id': 7, 'freq': 12538, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}, {'edge_to_bb_id': 8, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 6269}, {'edge_to_bb_id': 8, 'freq': 6269}]}, {'bb_id': 8, 'freq': 6269, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 6269}]}, {'bb_id': 9, 'freq': 6269, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 6269}]}, {'bb_id': 10, 'freq': 12538, 'predicted_edges': [{'edge_to_bb_id': 12, 'freq': 0}, {'edge_to_bb_id': 11, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 12, 'freq': 12538}, {'edge_to_bb_id': 11, 'freq': 0}]}, {'bb_id': 11, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 12, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 12, 'freq': 0}]}, {'bb_id': 12, 'freq': 12538, 'predicted_edges': [{'edge_to_bb_id': 14, 'freq': 0}, {'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 14, 'freq': 0}, {'edge_to_bb_id': 13, 'freq': 12537}]}, {'bb_id': 13, 'freq': 12537, 'predicted_edges': [{'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 7, 'freq': 12537}]}, {'bb_id': 14, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 15, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 15, 'freq': 0}]}, {'bb_id': 15, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 17, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 17, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}]}, {'bb_id': 16, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 17, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 17, 'freq': 0}]}, {'bb_id': 17, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 0}]}, {'bb_id': 18, 'freq': 0, 'predicted_edges': [], 'actual_edges': []}]} +2024-12-04 19:36:12 - {'cfg_bbs': [{'bb_id': 0, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 2, 'freq': 0}, {'edge_to_bb_id': 1, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 2, 'freq': 1}, {'edge_to_bb_id': 1, 'freq': 0}]}, {'bb_id': 1, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 0}]}, {'bb_id': 2, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 1}]}, {'bb_id': 3, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 4, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 4, 'freq': 1}]}, {'bb_id': 4, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 5, 'freq': 0}, {'edge_to_bb_id': 4, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 5, 'freq': 1}, {'edge_to_bb_id': 4, 'freq': 0}]}, {'bb_id': 5, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 1}]}, {'bb_id': 6, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 7, 'freq': 1}]}, {'bb_id': 7, 'freq': 12676, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}, {'edge_to_bb_id': 8, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 6338}, {'edge_to_bb_id': 8, 'freq': 6338}]}, {'bb_id': 8, 'freq': 6338, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 6338}]}, {'bb_id': 9, 'freq': 6338, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 6338}]}, {'bb_id': 10, 'freq': 12676, 'predicted_edges': [{'edge_to_bb_id': 12, 'freq': 0}, {'edge_to_bb_id': 11, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 12, 'freq': 12676}, {'edge_to_bb_id': 11, 'freq': 0}]}, {'bb_id': 11, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 12, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 12, 'freq': 0}]}, {'bb_id': 12, 'freq': 12676, 'predicted_edges': [{'edge_to_bb_id': 14, 'freq': 0}, {'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 14, 'freq': 0}, {'edge_to_bb_id': 13, 'freq': 12675}]}, {'bb_id': 13, 'freq': 12675, 'predicted_edges': [{'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 7, 'freq': 12675}]}, {'bb_id': 14, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 15, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 15, 'freq': 0}]}, {'bb_id': 15, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 17, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 17, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}]}, {'bb_id': 16, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 17, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 17, 'freq': 0}]}, {'bb_id': 17, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 0}]}, {'bb_id': 18, 'freq': 0, 'predicted_edges': [], 'actual_edges': []}]} +2024-12-04 19:36:42 - {'cfg_bbs': [{'bb_id': 0, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 2, 'freq': 0}, {'edge_to_bb_id': 1, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 2, 'freq': 1}, {'edge_to_bb_id': 1, 'freq': 0}]}, {'bb_id': 1, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 0}]}, {'bb_id': 2, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 1}]}, {'bb_id': 3, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 4, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 4, 'freq': 1}]}, {'bb_id': 4, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 5, 'freq': 0}, {'edge_to_bb_id': 4, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 5, 'freq': 1}, {'edge_to_bb_id': 4, 'freq': 0}]}, {'bb_id': 5, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 1}]}, {'bb_id': 6, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 7, 'freq': 1}]}, {'bb_id': 7, 'freq': 12682, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}, {'edge_to_bb_id': 8, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 6340}, {'edge_to_bb_id': 8, 'freq': 6341}]}, {'bb_id': 8, 'freq': 6341, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 6341}]}, {'bb_id': 9, 'freq': 6340, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 6340}]}, {'bb_id': 10, 'freq': 12681, 'predicted_edges': [{'edge_to_bb_id': 12, 'freq': 0}, {'edge_to_bb_id': 11, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 12, 'freq': 12681}, {'edge_to_bb_id': 11, 'freq': 0}]}, {'bb_id': 11, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 12, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 12, 'freq': 0}]}, {'bb_id': 12, 'freq': 12681, 'predicted_edges': [{'edge_to_bb_id': 14, 'freq': 0}, {'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 14, 'freq': 0}, {'edge_to_bb_id': 13, 'freq': 12681}]}, {'bb_id': 13, 'freq': 12681, 'predicted_edges': [{'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 7, 'freq': 12681}]}, {'bb_id': 14, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 15, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 15, 'freq': 0}]}, {'bb_id': 15, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 17, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 17, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}]}, {'bb_id': 16, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 17, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 17, 'freq': 0}]}, {'bb_id': 17, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 0}]}, {'bb_id': 18, 'freq': 0, 'predicted_edges': [], 'actual_edges': []}]} +2024-12-04 19:40:05 - {'cfg_bbs': [{'bb_id': 0, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 2, 'freq': 0}, {'edge_to_bb_id': 1, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 2, 'freq': 1}, {'edge_to_bb_id': 1, 'freq': 0}]}, {'bb_id': 1, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 0}]}, {'bb_id': 2, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 1}]}, {'bb_id': 3, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 4, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 4, 'freq': 1}]}, {'bb_id': 4, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 5, 'freq': 0}, {'edge_to_bb_id': 4, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 5, 'freq': 1}, {'edge_to_bb_id': 4, 'freq': 0}]}, {'bb_id': 5, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 1}]}, {'bb_id': 6, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 7, 'freq': 1}]}, {'bb_id': 7, 'freq': 12282, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}, {'edge_to_bb_id': 8, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 6140}, {'edge_to_bb_id': 8, 'freq': 6141}]}, {'bb_id': 8, 'freq': 6141, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 6141}]}, {'bb_id': 9, 'freq': 6140, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 6140}]}, {'bb_id': 10, 'freq': 12281, 'predicted_edges': [{'edge_to_bb_id': 12, 'freq': 0}, {'edge_to_bb_id': 11, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 12, 'freq': 12281}, {'edge_to_bb_id': 11, 'freq': 0}]}, {'bb_id': 11, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 12, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 12, 'freq': 0}]}, {'bb_id': 12, 'freq': 12281, 'predicted_edges': [{'edge_to_bb_id': 14, 'freq': 0}, {'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 14, 'freq': 0}, {'edge_to_bb_id': 13, 'freq': 12281}]}, {'bb_id': 13, 'freq': 12281, 'predicted_edges': [{'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 7, 'freq': 12281}]}, {'bb_id': 14, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 15, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 15, 'freq': 0}]}, {'bb_id': 15, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 17, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 17, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}]}, {'bb_id': 16, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 17, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 17, 'freq': 0}]}, {'bb_id': 17, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 0}]}, {'bb_id': 18, 'freq': 0, 'predicted_edges': [], 'actual_edges': []}]} +2024-12-04 19:40:20 - {"cfg_bbs": [{"actual_edges": [{"edge_to_bb_id": 2, "freq": 1}, {"edge_to_bb_id": 1, "freq": 0}], "bb_id": 0, "freq": 1, "predicted_edges": [{"edge_to_bb_id": 2, "freq": 1}, {"edge_to_bb_id": 1, "freq": 0}]}, {"actual_edges": [{"edge_to_bb_id": 3, "freq": 0}], "bb_id": 1, "freq": 0, "predicted_edges": [{"edge_to_bb_id": 3, "freq": 0}]}, {"actual_edges": [{"edge_to_bb_id": 3, "freq": 1}], "bb_id": 2, "freq": 1, "predicted_edges": [{"edge_to_bb_id": 3, "freq": 1}]}, {"actual_edges": [{"edge_to_bb_id": 4, "freq": 1}], "bb_id": 3, "freq": 1, "predicted_edges": [{"edge_to_bb_id": 4, "freq": 1}]}, {"actual_edges": [{"edge_to_bb_id": 5, "freq": 1}, {"edge_to_bb_id": 4, "freq": 0}], "bb_id": 4, "freq": 1, "predicted_edges": [{"edge_to_bb_id": 5, "freq": 1}, {"edge_to_bb_id": 4, "freq": 0}]}, {"actual_edges": [{"edge_to_bb_id": 6, "freq": 1}], "bb_id": 5, "freq": 1, "predicted_edges": [{"edge_to_bb_id": 6, "freq": 1}]}, {"actual_edges": [{"edge_to_bb_id": 15, "freq": 0}, {"edge_to_bb_id": 7, "freq": 1}], "bb_id": 6, "freq": 1, "predicted_edges": [{"edge_to_bb_id": 15, "freq": 0}, {"edge_to_bb_id": 7, "freq": 1}]}, {"actual_edges": [{"edge_to_bb_id": 9, "freq": 6140}, {"edge_to_bb_id": 8, "freq": 6141}], "bb_id": 7, "freq": 12282, "predicted_edges": [{"edge_to_bb_id": 9, "freq": 6140}, {"edge_to_bb_id": 8, "freq": 6141}]}, {"actual_edges": [{"edge_to_bb_id": 10, "freq": 6141}], "bb_id": 8, "freq": 6141, "predicted_edges": [{"edge_to_bb_id": 10, "freq": 6141}]}, {"actual_edges": [{"edge_to_bb_id": 10, "freq": 6140}], "bb_id": 9, "freq": 6140, "predicted_edges": [{"edge_to_bb_id": 10, "freq": 6140}]}, {"actual_edges": [{"edge_to_bb_id": 12, "freq": 12281}, {"edge_to_bb_id": 11, "freq": 0}], "bb_id": 10, "freq": 12281, "predicted_edges": [{"edge_to_bb_id": 12, "freq": 12281}, {"edge_to_bb_id": 11, "freq": 0}]}, {"actual_edges": [{"edge_to_bb_id": 12, "freq": 0}], "bb_id": 11, "freq": 0, "predicted_edges": [{"edge_to_bb_id": 12, "freq": 0}]}, {"actual_edges": [{"edge_to_bb_id": 14, "freq": 0}, {"edge_to_bb_id": 13, "freq": 12281}], "bb_id": 12, "freq": 12281, "predicted_edges": [{"edge_to_bb_id": 14, "freq": 0}, {"edge_to_bb_id": 13, "freq": 12281}]}, {"actual_edges": [{"edge_to_bb_id": 7, "freq": 12281}], "bb_id": 13, "freq": 12281, "predicted_edges": [{"edge_to_bb_id": 7, "freq": 12281}]}, {"actual_edges": [{"edge_to_bb_id": 15, "freq": 0}], "bb_id": 14, "freq": 0, "predicted_edges": [{"edge_to_bb_id": 15, "freq": 0}]}, {"actual_edges": [{"edge_to_bb_id": 17, "freq": 0}, {"edge_to_bb_id": 16, "freq": 0}], "bb_id": 15, "freq": 0, "predicted_edges": [{"edge_to_bb_id": 17, "freq": 0}, {"edge_to_bb_id": 16, "freq": 0}]}, {"actual_edges": [{"edge_to_bb_id": 17, "freq": 0}], "bb_id": 16, "freq": 0, "predicted_edges": [{"edge_to_bb_id": 17, "freq": 0}]}, {"actual_edges": [{"edge_to_bb_id": 6, "freq": 0}], "bb_id": 17, "freq": 0, "predicted_edges": [{"edge_to_bb_id": 6, "freq": 0}]}, {"actual_edges": [], "bb_id": 18, "freq": 0, "predicted_edges": []}]} +2024-12-04 19:40:20 - {'cfg_bbs': [{'bb_id': 0, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 2, 'freq': 0}, {'edge_to_bb_id': 1, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 2, 'freq': 1}, {'edge_to_bb_id': 1, 'freq': 0}]}, {'bb_id': 1, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 0}]}, {'bb_id': 2, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 1}]}, {'bb_id': 3, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 4, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 4, 'freq': 1}]}, {'bb_id': 4, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 5, 'freq': 0}, {'edge_to_bb_id': 4, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 5, 'freq': 1}, {'edge_to_bb_id': 4, 'freq': 0}]}, {'bb_id': 5, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 1}]}, {'bb_id': 6, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 7, 'freq': 1}]}, {'bb_id': 7, 'freq': 30000, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}, {'edge_to_bb_id': 8, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 15000}, {'edge_to_bb_id': 8, 'freq': 15000}]}, {'bb_id': 8, 'freq': 15000, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 15000}]}, {'bb_id': 9, 'freq': 15000, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 15000}]}, {'bb_id': 10, 'freq': 30000, 'predicted_edges': [{'edge_to_bb_id': 12, 'freq': 0}, {'edge_to_bb_id': 11, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 12, 'freq': 30000}, {'edge_to_bb_id': 11, 'freq': 0}]}, {'bb_id': 11, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 12, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 12, 'freq': 0}]}, {'bb_id': 12, 'freq': 30000, 'predicted_edges': [{'edge_to_bb_id': 14, 'freq': 0}, {'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 14, 'freq': 1}, {'edge_to_bb_id': 13, 'freq': 29999}]}, {'bb_id': 13, 'freq': 29999, 'predicted_edges': [{'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 7, 'freq': 29999}]}, {'bb_id': 14, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 15, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 15, 'freq': 0}]}, {'bb_id': 15, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 17, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 17, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}]}, {'bb_id': 16, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 17, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 17, 'freq': 0}]}, {'bb_id': 17, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 0}]}, {'bb_id': 18, 'freq': 0, 'predicted_edges': [], 'actual_edges': []}]} +2024-12-04 19:40:33 - {"cfg_bbs": [{"actual_edges": [{"edge_to_bb_id": 2, "freq": 1}, {"edge_to_bb_id": 1, "freq": 0}], "bb_id": 0, "freq": 1, "predicted_edges": [{"edge_to_bb_id": 2, "freq": 1}, {"edge_to_bb_id": 1, "freq": 0}]}, {"actual_edges": [{"edge_to_bb_id": 3, "freq": 0}], "bb_id": 1, "freq": 0, "predicted_edges": [{"edge_to_bb_id": 3, "freq": 0}]}, {"actual_edges": [{"edge_to_bb_id": 3, "freq": 1}], "bb_id": 2, "freq": 1, "predicted_edges": [{"edge_to_bb_id": 3, "freq": 1}]}, {"actual_edges": [{"edge_to_bb_id": 4, "freq": 1}], "bb_id": 3, "freq": 1, "predicted_edges": [{"edge_to_bb_id": 4, "freq": 1}]}, {"actual_edges": [{"edge_to_bb_id": 5, "freq": 1}, {"edge_to_bb_id": 4, "freq": 0}], "bb_id": 4, "freq": 1, "predicted_edges": [{"edge_to_bb_id": 5, "freq": 1}, {"edge_to_bb_id": 4, "freq": 0}]}, {"actual_edges": [{"edge_to_bb_id": 6, "freq": 1}], "bb_id": 5, "freq": 1, "predicted_edges": [{"edge_to_bb_id": 6, "freq": 1}]}, {"actual_edges": [{"edge_to_bb_id": 15, "freq": 0}, {"edge_to_bb_id": 7, "freq": 1}], "bb_id": 6, "freq": 1, "predicted_edges": [{"edge_to_bb_id": 15, "freq": 0}, {"edge_to_bb_id": 7, "freq": 1}]}, {"actual_edges": [{"edge_to_bb_id": 9, "freq": 15000}, {"edge_to_bb_id": 8, "freq": 15000}], "bb_id": 7, "freq": 30000, "predicted_edges": [{"edge_to_bb_id": 9, "freq": 15000}, {"edge_to_bb_id": 8, "freq": 15000}]}, {"actual_edges": [{"edge_to_bb_id": 10, "freq": 15000}], "bb_id": 8, "freq": 15000, "predicted_edges": [{"edge_to_bb_id": 10, "freq": 15000}]}, {"actual_edges": [{"edge_to_bb_id": 10, "freq": 15000}], "bb_id": 9, "freq": 15000, "predicted_edges": [{"edge_to_bb_id": 10, "freq": 15000}]}, {"actual_edges": [{"edge_to_bb_id": 12, "freq": 30000}, {"edge_to_bb_id": 11, "freq": 0}], "bb_id": 10, "freq": 30000, "predicted_edges": [{"edge_to_bb_id": 12, "freq": 30000}, {"edge_to_bb_id": 11, "freq": 0}]}, {"actual_edges": [{"edge_to_bb_id": 12, "freq": 0}], "bb_id": 11, "freq": 0, "predicted_edges": [{"edge_to_bb_id": 12, "freq": 0}]}, {"actual_edges": [{"edge_to_bb_id": 14, "freq": 1}, {"edge_to_bb_id": 13, "freq": 29999}], "bb_id": 12, "freq": 30000, "predicted_edges": [{"edge_to_bb_id": 14, "freq": 1}, {"edge_to_bb_id": 13, "freq": 29999}]}, {"actual_edges": [{"edge_to_bb_id": 7, "freq": 29999}], "bb_id": 13, "freq": 29999, "predicted_edges": [{"edge_to_bb_id": 7, "freq": 29999}]}, {"actual_edges": [{"edge_to_bb_id": 15, "freq": 0}], "bb_id": 14, "freq": 1, "predicted_edges": [{"edge_to_bb_id": 15, "freq": 0}]}, {"actual_edges": [{"edge_to_bb_id": 17, "freq": 0}, {"edge_to_bb_id": 16, "freq": 0}], "bb_id": 15, "freq": 0, "predicted_edges": [{"edge_to_bb_id": 17, "freq": 0}, {"edge_to_bb_id": 16, "freq": 0}]}, {"actual_edges": [{"edge_to_bb_id": 17, "freq": 0}], "bb_id": 16, "freq": 0, "predicted_edges": [{"edge_to_bb_id": 17, "freq": 0}]}, {"actual_edges": [{"edge_to_bb_id": 6, "freq": 0}], "bb_id": 17, "freq": 0, "predicted_edges": [{"edge_to_bb_id": 6, "freq": 0}]}, {"actual_edges": [], "bb_id": 18, "freq": 0, "predicted_edges": []}]} +2024-12-04 19:42:14 - {'cfg_bbs': [{'bb_id': 0, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 2, 'freq': 0}, {'edge_to_bb_id': 1, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 2, 'freq': 1}, {'edge_to_bb_id': 1, 'freq': 0}]}, {'bb_id': 1, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 0}]}, {'bb_id': 2, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 1}]}, {'bb_id': 3, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 4, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 4, 'freq': 1}]}, {'bb_id': 4, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 5, 'freq': 0}, {'edge_to_bb_id': 4, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 5, 'freq': 1}, {'edge_to_bb_id': 4, 'freq': 0}]}, {'bb_id': 5, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 1}]}, {'bb_id': 6, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 7, 'freq': 1}]}, {'bb_id': 7, 'freq': 3699, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}, {'edge_to_bb_id': 8, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 1849}, {'edge_to_bb_id': 8, 'freq': 1850}]}, {'bb_id': 8, 'freq': 1850, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 1849}]}, {'bb_id': 9, 'freq': 1849, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 1849}]}, {'bb_id': 10, 'freq': 3698, 'predicted_edges': [{'edge_to_bb_id': 12, 'freq': 0}, {'edge_to_bb_id': 11, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 12, 'freq': 3698}, {'edge_to_bb_id': 11, 'freq': 0}]}, {'bb_id': 11, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 12, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 12, 'freq': 0}]}, {'bb_id': 12, 'freq': 3698, 'predicted_edges': [{'edge_to_bb_id': 14, 'freq': 0}, {'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 14, 'freq': 0}, {'edge_to_bb_id': 13, 'freq': 3698}]}, {'bb_id': 13, 'freq': 3698, 'predicted_edges': [{'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 7, 'freq': 3698}]}, {'bb_id': 14, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 15, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 15, 'freq': 0}]}, {'bb_id': 15, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 17, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 17, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}]}, {'bb_id': 16, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 17, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 17, 'freq': 0}]}, {'bb_id': 17, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 0}]}, {'bb_id': 18, 'freq': 0, 'predicted_edges': [], 'actual_edges': []}]} +2024-12-04 19:42:29 - {"cfg_bbs": [{"actual_edges": [{"edge_to_bb_id": 2, "freq": 1}, {"edge_to_bb_id": 1, "freq": 0}], "bb_id": 0, "freq": 1, "predicted_edges": [{"edge_to_bb_id": 2, "freq": 1}, {"edge_to_bb_id": 1, "freq": 0}]}, {"actual_edges": [{"edge_to_bb_id": 3, "freq": 0}], "bb_id": 1, "freq": 0, "predicted_edges": [{"edge_to_bb_id": 3, "freq": 0}]}, {"actual_edges": [{"edge_to_bb_id": 3, "freq": 1}], "bb_id": 2, "freq": 1, "predicted_edges": [{"edge_to_bb_id": 3, "freq": 1}]}, {"actual_edges": [{"edge_to_bb_id": 4, "freq": 1}], "bb_id": 3, "freq": 1, "predicted_edges": [{"edge_to_bb_id": 4, "freq": 1}]}, {"actual_edges": [{"edge_to_bb_id": 5, "freq": 1}, {"edge_to_bb_id": 4, "freq": 0}], "bb_id": 4, "freq": 1, "predicted_edges": [{"edge_to_bb_id": 5, "freq": 1}, {"edge_to_bb_id": 4, "freq": 0}]}, {"actual_edges": [{"edge_to_bb_id": 6, "freq": 1}], "bb_id": 5, "freq": 1, "predicted_edges": [{"edge_to_bb_id": 6, "freq": 1}]}, {"actual_edges": [{"edge_to_bb_id": 15, "freq": 0}, {"edge_to_bb_id": 7, "freq": 1}], "bb_id": 6, "freq": 1, "predicted_edges": [{"edge_to_bb_id": 15, "freq": 0}, {"edge_to_bb_id": 7, "freq": 1}]}, {"actual_edges": [{"edge_to_bb_id": 9, "freq": 1849}, {"edge_to_bb_id": 8, "freq": 1850}], "bb_id": 7, "freq": 3699, "predicted_edges": [{"edge_to_bb_id": 9, "freq": 1849}, {"edge_to_bb_id": 8, "freq": 1850}]}, {"actual_edges": [{"edge_to_bb_id": 10, "freq": 1849}], "bb_id": 8, "freq": 1850, "predicted_edges": [{"edge_to_bb_id": 10, "freq": 1849}]}, {"actual_edges": [{"edge_to_bb_id": 10, "freq": 1849}], "bb_id": 9, "freq": 1849, "predicted_edges": [{"edge_to_bb_id": 10, "freq": 1849}]}, {"actual_edges": [{"edge_to_bb_id": 12, "freq": 3698}, {"edge_to_bb_id": 11, "freq": 0}], "bb_id": 10, "freq": 3698, "predicted_edges": [{"edge_to_bb_id": 12, "freq": 3698}, {"edge_to_bb_id": 11, "freq": 0}]}, {"actual_edges": [{"edge_to_bb_id": 12, "freq": 0}], "bb_id": 11, "freq": 0, "predicted_edges": [{"edge_to_bb_id": 12, "freq": 0}]}, {"actual_edges": [{"edge_to_bb_id": 14, "freq": 0}, {"edge_to_bb_id": 13, "freq": 3698}], "bb_id": 12, "freq": 3698, "predicted_edges": [{"edge_to_bb_id": 14, "freq": 0}, {"edge_to_bb_id": 13, "freq": 3698}]}, {"actual_edges": [{"edge_to_bb_id": 7, "freq": 3698}], "bb_id": 13, "freq": 3698, "predicted_edges": [{"edge_to_bb_id": 7, "freq": 3698}]}, {"actual_edges": [{"edge_to_bb_id": 15, "freq": 0}], "bb_id": 14, "freq": 0, "predicted_edges": [{"edge_to_bb_id": 15, "freq": 0}]}, {"actual_edges": [{"edge_to_bb_id": 17, "freq": 0}, {"edge_to_bb_id": 16, "freq": 0}], "bb_id": 15, "freq": 0, "predicted_edges": [{"edge_to_bb_id": 17, "freq": 0}, {"edge_to_bb_id": 16, "freq": 0}]}, {"actual_edges": [{"edge_to_bb_id": 17, "freq": 0}], "bb_id": 16, "freq": 0, "predicted_edges": [{"edge_to_bb_id": 17, "freq": 0}]}, {"actual_edges": [{"edge_to_bb_id": 6, "freq": 0}], "bb_id": 17, "freq": 0, "predicted_edges": [{"edge_to_bb_id": 6, "freq": 0}]}]} +2024-12-04 19:42:29 - {'cfg_bbs': [{'bb_id': 0, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 2, 'freq': 0}, {'edge_to_bb_id': 1, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 2, 'freq': 1}, {'edge_to_bb_id': 1, 'freq': 0}]}, {'bb_id': 1, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 0}]}, {'bb_id': 2, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 1}]}, {'bb_id': 3, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 4, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 4, 'freq': 1}]}, {'bb_id': 4, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 5, 'freq': 0}, {'edge_to_bb_id': 4, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 5, 'freq': 1}, {'edge_to_bb_id': 4, 'freq': 0}]}, {'bb_id': 5, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 1}]}, {'bb_id': 6, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 7, 'freq': 1}]}, {'bb_id': 7, 'freq': 30000, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}, {'edge_to_bb_id': 8, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 15000}, {'edge_to_bb_id': 8, 'freq': 15000}]}, {'bb_id': 8, 'freq': 15000, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 15000}]}, {'bb_id': 9, 'freq': 15000, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 15000}]}, {'bb_id': 10, 'freq': 30000, 'predicted_edges': [{'edge_to_bb_id': 12, 'freq': 0}, {'edge_to_bb_id': 11, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 12, 'freq': 30000}, {'edge_to_bb_id': 11, 'freq': 0}]}, {'bb_id': 11, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 12, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 12, 'freq': 0}]}, {'bb_id': 12, 'freq': 30000, 'predicted_edges': [{'edge_to_bb_id': 14, 'freq': 0}, {'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 14, 'freq': 1}, {'edge_to_bb_id': 13, 'freq': 29999}]}, {'bb_id': 13, 'freq': 29999, 'predicted_edges': [{'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 7, 'freq': 29999}]}, {'bb_id': 14, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 15, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 15, 'freq': 0}]}, {'bb_id': 15, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 17, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 17, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}]}, {'bb_id': 16, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 17, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 17, 'freq': 0}]}, {'bb_id': 17, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 0}]}, {'bb_id': 18, 'freq': 0, 'predicted_edges': [], 'actual_edges': []}]} +2024-12-04 19:42:42 - {"cfg_bbs": [{"actual_edges": [{"edge_to_bb_id": 2, "freq": 1}, {"edge_to_bb_id": 1, "freq": 0}], "bb_id": 0, "freq": 1, "predicted_edges": [{"edge_to_bb_id": 2, "freq": 1}, {"edge_to_bb_id": 1, "freq": 0}]}, {"actual_edges": [{"edge_to_bb_id": 3, "freq": 0}], "bb_id": 1, "freq": 0, "predicted_edges": [{"edge_to_bb_id": 3, "freq": 0}]}, {"actual_edges": [{"edge_to_bb_id": 3, "freq": 1}], "bb_id": 2, "freq": 1, "predicted_edges": [{"edge_to_bb_id": 3, "freq": 1}]}, {"actual_edges": [{"edge_to_bb_id": 4, "freq": 1}], "bb_id": 3, "freq": 1, "predicted_edges": [{"edge_to_bb_id": 4, "freq": 1}]}, {"actual_edges": [{"edge_to_bb_id": 5, "freq": 1}, {"edge_to_bb_id": 4, "freq": 0}], "bb_id": 4, "freq": 1, "predicted_edges": [{"edge_to_bb_id": 5, "freq": 1}, {"edge_to_bb_id": 4, "freq": 0}]}, {"actual_edges": [{"edge_to_bb_id": 6, "freq": 1}], "bb_id": 5, "freq": 1, "predicted_edges": [{"edge_to_bb_id": 6, "freq": 1}]}, {"actual_edges": [{"edge_to_bb_id": 15, "freq": 0}, {"edge_to_bb_id": 7, "freq": 1}], "bb_id": 6, "freq": 1, "predicted_edges": [{"edge_to_bb_id": 15, "freq": 0}, {"edge_to_bb_id": 7, "freq": 1}]}, {"actual_edges": [{"edge_to_bb_id": 9, "freq": 15000}, {"edge_to_bb_id": 8, "freq": 15000}], "bb_id": 7, "freq": 30000, "predicted_edges": [{"edge_to_bb_id": 9, "freq": 15000}, {"edge_to_bb_id": 8, "freq": 15000}]}, {"actual_edges": [{"edge_to_bb_id": 10, "freq": 15000}], "bb_id": 8, "freq": 15000, "predicted_edges": [{"edge_to_bb_id": 10, "freq": 15000}]}, {"actual_edges": [{"edge_to_bb_id": 10, "freq": 15000}], "bb_id": 9, "freq": 15000, "predicted_edges": [{"edge_to_bb_id": 10, "freq": 15000}]}, {"actual_edges": [{"edge_to_bb_id": 12, "freq": 30000}, {"edge_to_bb_id": 11, "freq": 0}], "bb_id": 10, "freq": 30000, "predicted_edges": [{"edge_to_bb_id": 12, "freq": 30000}, {"edge_to_bb_id": 11, "freq": 0}]}, {"actual_edges": [{"edge_to_bb_id": 12, "freq": 0}], "bb_id": 11, "freq": 0, "predicted_edges": [{"edge_to_bb_id": 12, "freq": 0}]}, {"actual_edges": [{"edge_to_bb_id": 14, "freq": 1}, {"edge_to_bb_id": 13, "freq": 29999}], "bb_id": 12, "freq": 30000, "predicted_edges": [{"edge_to_bb_id": 14, "freq": 1}, {"edge_to_bb_id": 13, "freq": 29999}]}, {"actual_edges": [{"edge_to_bb_id": 7, "freq": 29999}], "bb_id": 13, "freq": 29999, "predicted_edges": [{"edge_to_bb_id": 7, "freq": 29999}]}, {"actual_edges": [{"edge_to_bb_id": 15, "freq": 0}], "bb_id": 14, "freq": 1, "predicted_edges": [{"edge_to_bb_id": 15, "freq": 0}]}, {"actual_edges": [{"edge_to_bb_id": 17, "freq": 0}, {"edge_to_bb_id": 16, "freq": 0}], "bb_id": 15, "freq": 0, "predicted_edges": [{"edge_to_bb_id": 17, "freq": 0}, {"edge_to_bb_id": 16, "freq": 0}]}, {"actual_edges": [{"edge_to_bb_id": 17, "freq": 0}], "bb_id": 16, "freq": 0, "predicted_edges": [{"edge_to_bb_id": 17, "freq": 0}]}, {"actual_edges": [{"edge_to_bb_id": 6, "freq": 0}], "bb_id": 17, "freq": 0, "predicted_edges": [{"edge_to_bb_id": 6, "freq": 0}]}, {"actual_edges": [], "bb_id": 18, "freq": 0, "predicted_edges": []}]} +2024-12-04 19:43:55 - {'cfg_bbs': [{'bb_id': 0, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 2, 'freq': 0}, {'edge_to_bb_id': 1, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 2, 'freq': 1}, {'edge_to_bb_id': 1, 'freq': 0}]}, {'bb_id': 1, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 0}]}, {'bb_id': 2, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 1}]}, {'bb_id': 3, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 4, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 4, 'freq': 1}]}, {'bb_id': 4, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 5, 'freq': 0}, {'edge_to_bb_id': 4, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 5, 'freq': 1}, {'edge_to_bb_id': 4, 'freq': 0}]}, {'bb_id': 5, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 1}]}, {'bb_id': 6, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 7, 'freq': 1}]}, {'bb_id': 7, 'freq': 11293, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}, {'edge_to_bb_id': 8, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 5646}, {'edge_to_bb_id': 8, 'freq': 5647}]}, {'bb_id': 8, 'freq': 5647, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 5647}]}, {'bb_id': 9, 'freq': 5646, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 5646}]}, {'bb_id': 10, 'freq': 11293, 'predicted_edges': [{'edge_to_bb_id': 12, 'freq': 0}, {'edge_to_bb_id': 11, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 12, 'freq': 11292}, {'edge_to_bb_id': 11, 'freq': 0}]}, {'bb_id': 11, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 12, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 12, 'freq': 0}]}, {'bb_id': 12, 'freq': 11292, 'predicted_edges': [{'edge_to_bb_id': 14, 'freq': 0}, {'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 14, 'freq': 0}, {'edge_to_bb_id': 13, 'freq': 11292}]}, {'bb_id': 13, 'freq': 11292, 'predicted_edges': [{'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 7, 'freq': 11292}]}, {'bb_id': 14, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 15, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 15, 'freq': 0}]}, {'bb_id': 15, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 17, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 17, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}]}, {'bb_id': 16, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 17, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 17, 'freq': 0}]}, {'bb_id': 17, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 0}]}, {'bb_id': 18, 'freq': 0, 'predicted_edges': [], 'actual_edges': []}]} +2024-12-04 19:44:09 - {"cfg_bbs": [{"actual_edges": [{"edge_to_bb_id": 2, "freq": 1}, {"edge_to_bb_id": 1, "freq": 0}], "bb_id": 0, "freq": 1, "predicted_edges": [{"edge_to_bb_id": 2, "freq": 1}, {"edge_to_bb_id": 1, "freq": 0}]}, {"actual_edges": [{"edge_to_bb_id": 3, "freq": 0}], "bb_id": 1, "freq": 0, "predicted_edges": [{"edge_to_bb_id": 3, "freq": 0}]}, {"actual_edges": [{"edge_to_bb_id": 3, "freq": 1}], "bb_id": 2, "freq": 1, "predicted_edges": [{"edge_to_bb_id": 3, "freq": 1}]}, {"actual_edges": [{"edge_to_bb_id": 4, "freq": 1}], "bb_id": 3, "freq": 1, "predicted_edges": [{"edge_to_bb_id": 4, "freq": 1}]}, {"actual_edges": [{"edge_to_bb_id": 5, "freq": 1}, {"edge_to_bb_id": 4, "freq": 0}], "bb_id": 4, "freq": 1, "predicted_edges": [{"edge_to_bb_id": 5, "freq": 1}, {"edge_to_bb_id": 4, "freq": 0}]}, {"actual_edges": [{"edge_to_bb_id": 6, "freq": 1}], "bb_id": 5, "freq": 1, "predicted_edges": [{"edge_to_bb_id": 6, "freq": 1}]}, {"actual_edges": [{"edge_to_bb_id": 15, "freq": 0}, {"edge_to_bb_id": 7, "freq": 1}], "bb_id": 6, "freq": 1, "predicted_edges": [{"edge_to_bb_id": 15, "freq": 0}, {"edge_to_bb_id": 7, "freq": 1}]}, {"actual_edges": [{"edge_to_bb_id": 9, "freq": 5646}, {"edge_to_bb_id": 8, "freq": 5647}], "bb_id": 7, "freq": 11293, "predicted_edges": [{"edge_to_bb_id": 9, "freq": 5646}, {"edge_to_bb_id": 8, "freq": 5647}]}, {"actual_edges": [{"edge_to_bb_id": 10, "freq": 5647}], "bb_id": 8, "freq": 5647, "predicted_edges": [{"edge_to_bb_id": 10, "freq": 5647}]}, {"actual_edges": [{"edge_to_bb_id": 10, "freq": 5646}], "bb_id": 9, "freq": 5646, "predicted_edges": [{"edge_to_bb_id": 10, "freq": 5646}]}, {"actual_edges": [{"edge_to_bb_id": 12, "freq": 11292}, {"edge_to_bb_id": 11, "freq": 0}], "bb_id": 10, "freq": 11293, "predicted_edges": [{"edge_to_bb_id": 12, "freq": 11292}, {"edge_to_bb_id": 11, "freq": 0}]}, {"actual_edges": [{"edge_to_bb_id": 12, "freq": 0}], "bb_id": 11, "freq": 0, "predicted_edges": [{"edge_to_bb_id": 12, "freq": 0}]}, {"actual_edges": [{"edge_to_bb_id": 14, "freq": 0}, {"edge_to_bb_id": 13, "freq": 11292}], "bb_id": 12, "freq": 11292, "predicted_edges": [{"edge_to_bb_id": 14, "freq": 0}, {"edge_to_bb_id": 13, "freq": 11292}]}, {"actual_edges": [{"edge_to_bb_id": 7, "freq": 11292}], "bb_id": 13, "freq": 11292, "predicted_edges": [{"edge_to_bb_id": 7, "freq": 11292}]}, {"actual_edges": [{"edge_to_bb_id": 15, "freq": 0}], "bb_id": 14, "freq": 0, "predicted_edges": [{"edge_to_bb_id": 15, "freq": 0}]}, {"actual_edges": [{"edge_to_bb_id": 17, "freq": 0}, {"edge_to_bb_id": 16, "freq": 0}], "bb_id": 15, "freq": 0, "predicted_edges": [{"edge_to_bb_id": 17, "freq": 0}, {"edge_to_bb_id": 16, "freq": 0}]}, {"actual_edges": [{"edge_to_bb_id": 17, "freq": 0}], "bb_id": 16, "freq": 0, "predicted_edges": [{"edge_to_bb_id": 17, "freq": 0}]}, {"actual_edges": [{"edge_to_bb_id": 6, "freq": 0}], "bb_id": 17, "freq": 0, "predicted_edges": [{"edge_to_bb_id": 6, "freq": 0}]}]} +2024-12-04 19:44:09 - {'cfg_bbs': [{'bb_id': 0, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 2, 'freq': 0}, {'edge_to_bb_id': 1, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 2, 'freq': 1}, {'edge_to_bb_id': 1, 'freq': 0}]}, {'bb_id': 1, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 0}]}, {'bb_id': 2, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 1}]}, {'bb_id': 3, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 4, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 4, 'freq': 1}]}, {'bb_id': 4, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 5, 'freq': 0}, {'edge_to_bb_id': 4, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 5, 'freq': 1}, {'edge_to_bb_id': 4, 'freq': 0}]}, {'bb_id': 5, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 1}]}, {'bb_id': 6, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 7, 'freq': 1}]}, {'bb_id': 7, 'freq': 30000, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}, {'edge_to_bb_id': 8, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 15000}, {'edge_to_bb_id': 8, 'freq': 15000}]}, {'bb_id': 8, 'freq': 15000, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 15000}]}, {'bb_id': 9, 'freq': 15000, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 15000}]}, {'bb_id': 10, 'freq': 30000, 'predicted_edges': [{'edge_to_bb_id': 12, 'freq': 0}, {'edge_to_bb_id': 11, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 12, 'freq': 30000}, {'edge_to_bb_id': 11, 'freq': 0}]}, {'bb_id': 11, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 12, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 12, 'freq': 0}]}, {'bb_id': 12, 'freq': 30000, 'predicted_edges': [{'edge_to_bb_id': 14, 'freq': 0}, {'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 14, 'freq': 1}, {'edge_to_bb_id': 13, 'freq': 29999}]}, {'bb_id': 13, 'freq': 29999, 'predicted_edges': [{'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 7, 'freq': 29999}]}, {'bb_id': 14, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 15, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 15, 'freq': 0}]}, {'bb_id': 15, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 17, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 17, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}]}, {'bb_id': 16, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 17, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 17, 'freq': 0}]}, {'bb_id': 17, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 0}]}, {'bb_id': 18, 'freq': 0, 'predicted_edges': [], 'actual_edges': []}]} +2024-12-04 19:44:22 - {"cfg_bbs": [{"actual_edges": [{"edge_to_bb_id": 2, "freq": 1}, {"edge_to_bb_id": 1, "freq": 0}], "bb_id": 0, "freq": 1, "predicted_edges": [{"edge_to_bb_id": 2, "freq": 1}, {"edge_to_bb_id": 1, "freq": 0}]}, {"actual_edges": [{"edge_to_bb_id": 3, "freq": 0}], "bb_id": 1, "freq": 0, "predicted_edges": [{"edge_to_bb_id": 3, "freq": 0}]}, {"actual_edges": [{"edge_to_bb_id": 3, "freq": 1}], "bb_id": 2, "freq": 1, "predicted_edges": [{"edge_to_bb_id": 3, "freq": 1}]}, {"actual_edges": [{"edge_to_bb_id": 4, "freq": 1}], "bb_id": 3, "freq": 1, "predicted_edges": [{"edge_to_bb_id": 4, "freq": 1}]}, {"actual_edges": [{"edge_to_bb_id": 5, "freq": 1}, {"edge_to_bb_id": 4, "freq": 0}], "bb_id": 4, "freq": 1, "predicted_edges": [{"edge_to_bb_id": 5, "freq": 1}, {"edge_to_bb_id": 4, "freq": 0}]}, {"actual_edges": [{"edge_to_bb_id": 6, "freq": 1}], "bb_id": 5, "freq": 1, "predicted_edges": [{"edge_to_bb_id": 6, "freq": 1}]}, {"actual_edges": [{"edge_to_bb_id": 15, "freq": 0}, {"edge_to_bb_id": 7, "freq": 1}], "bb_id": 6, "freq": 1, "predicted_edges": [{"edge_to_bb_id": 15, "freq": 0}, {"edge_to_bb_id": 7, "freq": 1}]}, {"actual_edges": [{"edge_to_bb_id": 9, "freq": 15000}, {"edge_to_bb_id": 8, "freq": 15000}], "bb_id": 7, "freq": 30000, "predicted_edges": [{"edge_to_bb_id": 9, "freq": 15000}, {"edge_to_bb_id": 8, "freq": 15000}]}, {"actual_edges": [{"edge_to_bb_id": 10, "freq": 15000}], "bb_id": 8, "freq": 15000, "predicted_edges": [{"edge_to_bb_id": 10, "freq": 15000}]}, {"actual_edges": [{"edge_to_bb_id": 10, "freq": 15000}], "bb_id": 9, "freq": 15000, "predicted_edges": [{"edge_to_bb_id": 10, "freq": 15000}]}, {"actual_edges": [{"edge_to_bb_id": 12, "freq": 30000}, {"edge_to_bb_id": 11, "freq": 0}], "bb_id": 10, "freq": 30000, "predicted_edges": [{"edge_to_bb_id": 12, "freq": 30000}, {"edge_to_bb_id": 11, "freq": 0}]}, {"actual_edges": [{"edge_to_bb_id": 12, "freq": 0}], "bb_id": 11, "freq": 0, "predicted_edges": [{"edge_to_bb_id": 12, "freq": 0}]}, {"actual_edges": [{"edge_to_bb_id": 14, "freq": 1}, {"edge_to_bb_id": 13, "freq": 29999}], "bb_id": 12, "freq": 30000, "predicted_edges": [{"edge_to_bb_id": 14, "freq": 1}, {"edge_to_bb_id": 13, "freq": 29999}]}, {"actual_edges": [{"edge_to_bb_id": 7, "freq": 29999}], "bb_id": 13, "freq": 29999, "predicted_edges": [{"edge_to_bb_id": 7, "freq": 29999}]}, {"actual_edges": [{"edge_to_bb_id": 15, "freq": 0}], "bb_id": 14, "freq": 1, "predicted_edges": [{"edge_to_bb_id": 15, "freq": 0}]}, {"actual_edges": [{"edge_to_bb_id": 17, "freq": 0}, {"edge_to_bb_id": 16, "freq": 0}], "bb_id": 15, "freq": 0, "predicted_edges": [{"edge_to_bb_id": 17, "freq": 0}, {"edge_to_bb_id": 16, "freq": 0}]}, {"actual_edges": [{"edge_to_bb_id": 17, "freq": 0}], "bb_id": 16, "freq": 0, "predicted_edges": [{"edge_to_bb_id": 17, "freq": 0}]}, {"actual_edges": [{"edge_to_bb_id": 6, "freq": 0}], "bb_id": 17, "freq": 0, "predicted_edges": [{"edge_to_bb_id": 6, "freq": 0}]}]} +2024-12-04 19:45:38 - {'cfg_bbs': [{'bb_id': 0, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 2, 'freq': 0}, {'edge_to_bb_id': 1, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 2, 'freq': 1}, {'edge_to_bb_id': 1, 'freq': 0}]}, {'bb_id': 1, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 0}]}, {'bb_id': 2, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 1}]}, {'bb_id': 3, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 4, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 4, 'freq': 1}]}, {'bb_id': 4, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 5, 'freq': 0}, {'edge_to_bb_id': 4, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 5, 'freq': 1}, {'edge_to_bb_id': 4, 'freq': 0}]}, {'bb_id': 5, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 1}]}, {'bb_id': 6, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 7, 'freq': 1}]}, {'bb_id': 7, 'freq': 11432, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}, {'edge_to_bb_id': 8, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 5716}, {'edge_to_bb_id': 8, 'freq': 5716}]}, {'bb_id': 8, 'freq': 5716, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 5716}]}, {'bb_id': 9, 'freq': 5716, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 5716}]}, {'bb_id': 10, 'freq': 11432, 'predicted_edges': [{'edge_to_bb_id': 12, 'freq': 0}, {'edge_to_bb_id': 11, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 12, 'freq': 11431}, {'edge_to_bb_id': 11, 'freq': 0}]}, {'bb_id': 11, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 12, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 12, 'freq': 0}]}, {'bb_id': 12, 'freq': 11431, 'predicted_edges': [{'edge_to_bb_id': 14, 'freq': 0}, {'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 14, 'freq': 0}, {'edge_to_bb_id': 13, 'freq': 11431}]}, {'bb_id': 13, 'freq': 11431, 'predicted_edges': [{'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 7, 'freq': 11431}]}, {'bb_id': 14, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 15, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 15, 'freq': 0}]}, {'bb_id': 15, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 17, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 17, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}]}, {'bb_id': 16, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 17, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 17, 'freq': 0}]}, {'bb_id': 17, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 0}]}, {'bb_id': 18, 'freq': 0, 'predicted_edges': [], 'actual_edges': []}]} +2024-12-04 19:45:50 - {"cfg_bbs": [{"actual_edges": [{"edge_to_bb_id": 2, "freq": 1}, {"edge_to_bb_id": 1, "freq": 0}], "bb_id": 0, "freq": 1, "predicted_edges": [{"edge_to_bb_id": 2, "freq": 1}]}, {"actual_edges": [{"edge_to_bb_id": 3, "freq": 0}], "bb_id": 1, "freq": 0, "predicted_edges": []}, {"actual_edges": [{"edge_to_bb_id": 3, "freq": 1}], "bb_id": 2, "freq": 1, "predicted_edges": [{"edge_to_bb_id": 3, "freq": 1}]}, {"actual_edges": [{"edge_to_bb_id": 4, "freq": 1}], "bb_id": 3, "freq": 1, "predicted_edges": [{"edge_to_bb_id": 4, "freq": 1}]}, {"actual_edges": [{"edge_to_bb_id": 5, "freq": 1}, {"edge_to_bb_id": 4, "freq": 0}], "bb_id": 4, "freq": 1, "predicted_edges": [{"edge_to_bb_id": 5, "freq": 1}]}, {"actual_edges": [{"edge_to_bb_id": 6, "freq": 1}], "bb_id": 5, "freq": 1, "predicted_edges": [{"edge_to_bb_id": 6, "freq": 1}]}, {"actual_edges": [{"edge_to_bb_id": 15, "freq": 0}, {"edge_to_bb_id": 7, "freq": 1}], "bb_id": 6, "freq": 1, "predicted_edges": [{"edge_to_bb_id": 7, "freq": 1}]}, {"actual_edges": [{"edge_to_bb_id": 9, "freq": 5716}, {"edge_to_bb_id": 8, "freq": 5716}], "bb_id": 7, "freq": 11432, "predicted_edges": [{"edge_to_bb_id": 9, "freq": 5716}, {"edge_to_bb_id": 8, "freq": 5716}]}, {"actual_edges": [{"edge_to_bb_id": 10, "freq": 5716}], "bb_id": 8, "freq": 5716, "predicted_edges": [{"edge_to_bb_id": 10, "freq": 5716}]}, {"actual_edges": [{"edge_to_bb_id": 10, "freq": 5716}], "bb_id": 9, "freq": 5716, "predicted_edges": [{"edge_to_bb_id": 10, "freq": 5716}]}, {"actual_edges": [{"edge_to_bb_id": 12, "freq": 11431}, {"edge_to_bb_id": 11, "freq": 0}], "bb_id": 10, "freq": 11432, "predicted_edges": [{"edge_to_bb_id": 12, "freq": 11431}]}, {"actual_edges": [{"edge_to_bb_id": 12, "freq": 0}], "bb_id": 11, "freq": 0, "predicted_edges": []}, {"actual_edges": [{"edge_to_bb_id": 14, "freq": 0}, {"edge_to_bb_id": 13, "freq": 11431}], "bb_id": 12, "freq": 11431, "predicted_edges": [{"edge_to_bb_id": 13, "freq": 11431}]}, {"actual_edges": [{"edge_to_bb_id": 7, "freq": 11431}], "bb_id": 13, "freq": 11431, "predicted_edges": [{"edge_to_bb_id": 7, "freq": 11431}]}, {"actual_edges": [{"edge_to_bb_id": 15, "freq": 0}], "bb_id": 14, "freq": 0, "predicted_edges": []}, {"actual_edges": [{"edge_to_bb_id": 17, "freq": 0}, {"edge_to_bb_id": 16, "freq": 0}], "bb_id": 15, "freq": 0, "predicted_edges": []}, {"actual_edges": [{"edge_to_bb_id": 17, "freq": 0}], "bb_id": 16, "freq": 0, "predicted_edges": []}, {"actual_edges": [{"edge_to_bb_id": 6, "freq": 0}], "bb_id": 17, "freq": 0, "predicted_edges": []}, {"actual_edges": [], "bb_id": 18, "freq": 0, "predicted_edges": []}]} +2024-12-04 19:45:50 - {'cfg_bbs': [{'bb_id': 0, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 2, 'freq': 0}, {'edge_to_bb_id': 1, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 2, 'freq': 1}, {'edge_to_bb_id': 1, 'freq': 0}]}, {'bb_id': 1, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 0}]}, {'bb_id': 2, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 1}]}, {'bb_id': 3, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 4, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 4, 'freq': 1}]}, {'bb_id': 4, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 5, 'freq': 0}, {'edge_to_bb_id': 4, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 5, 'freq': 1}, {'edge_to_bb_id': 4, 'freq': 0}]}, {'bb_id': 5, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 1}]}, {'bb_id': 6, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 7, 'freq': 1}]}, {'bb_id': 7, 'freq': 30000, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}, {'edge_to_bb_id': 8, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 15000}, {'edge_to_bb_id': 8, 'freq': 15000}]}, {'bb_id': 8, 'freq': 15000, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 15000}]}, {'bb_id': 9, 'freq': 15000, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 15000}]}, {'bb_id': 10, 'freq': 30000, 'predicted_edges': [{'edge_to_bb_id': 12, 'freq': 0}, {'edge_to_bb_id': 11, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 12, 'freq': 30000}, {'edge_to_bb_id': 11, 'freq': 0}]}, {'bb_id': 11, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 12, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 12, 'freq': 0}]}, {'bb_id': 12, 'freq': 30000, 'predicted_edges': [{'edge_to_bb_id': 14, 'freq': 0}, {'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 14, 'freq': 1}, {'edge_to_bb_id': 13, 'freq': 29999}]}, {'bb_id': 13, 'freq': 29999, 'predicted_edges': [{'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 7, 'freq': 29999}]}, {'bb_id': 14, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 15, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 15, 'freq': 0}]}, {'bb_id': 15, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 17, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 17, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}]}, {'bb_id': 16, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 17, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 17, 'freq': 0}]}, {'bb_id': 17, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 0}]}, {'bb_id': 18, 'freq': 0, 'predicted_edges': [], 'actual_edges': []}]} +2024-12-04 19:46:03 - {"cfg_bbs": [{"actual_edges": [{"edge_to_bb_id": 2, "freq": 1}, {"edge_to_bb_id": 1, "freq": 0}], "bb_id": 0, "freq": 1, "predicted_edges": [{"edge_to_bb_id": 2, "freq": 1}, {"edge_to_bb_id": 1, "freq": 0}]}, {"actual_edges": [{"edge_to_bb_id": 3, "freq": 0}], "bb_id": 1, "freq": 0, "predicted_edges": [{"edge_to_bb_id": 3, "freq": 0}]}, {"actual_edges": [{"edge_to_bb_id": 3, "freq": 1}], "bb_id": 2, "freq": 1, "predicted_edges": [{"edge_to_bb_id": 3, "freq": 1}]}, {"actual_edges": [{"edge_to_bb_id": 4, "freq": 1}], "bb_id": 3, "freq": 1, "predicted_edges": [{"edge_to_bb_id": 4, "freq": 1}]}, {"actual_edges": [{"edge_to_bb_id": 5, "freq": 1}, {"edge_to_bb_id": 4, "freq": 0}], "bb_id": 4, "freq": 1, "predicted_edges": [{"edge_to_bb_id": 5, "freq": 1}, {"edge_to_bb_id": 4, "freq": 0}]}, {"actual_edges": [{"edge_to_bb_id": 6, "freq": 1}], "bb_id": 5, "freq": 1, "predicted_edges": [{"edge_to_bb_id": 6, "freq": 1}]}, {"actual_edges": [{"edge_to_bb_id": 15, "freq": 0}, {"edge_to_bb_id": 7, "freq": 1}], "bb_id": 6, "freq": 1, "predicted_edges": [{"edge_to_bb_id": 15, "freq": 0}, {"edge_to_bb_id": 7, "freq": 1}]}, {"actual_edges": [{"edge_to_bb_id": 9, "freq": 15000}, {"edge_to_bb_id": 8, "freq": 15000}], "bb_id": 7, "freq": 30000, "predicted_edges": [{"edge_to_bb_id": 9, "freq": 15000}, {"edge_to_bb_id": 8, "freq": 15000}]}, {"actual_edges": [{"edge_to_bb_id": 10, "freq": 15000}], "bb_id": 8, "freq": 15000, "predicted_edges": [{"edge_to_bb_id": 10, "freq": 15000}]}, {"actual_edges": [{"edge_to_bb_id": 10, "freq": 15000}], "bb_id": 9, "freq": 15000, "predicted_edges": [{"edge_to_bb_id": 10, "freq": 15000}]}, {"actual_edges": [{"edge_to_bb_id": 12, "freq": 30000}, {"edge_to_bb_id": 11, "freq": 0}], "bb_id": 10, "freq": 30000, "predicted_edges": [{"edge_to_bb_id": 12, "freq": 30000}, {"edge_to_bb_id": 11, "freq": 0}]}, {"actual_edges": [{"edge_to_bb_id": 12, "freq": 0}], "bb_id": 11, "freq": 0, "predicted_edges": [{"edge_to_bb_id": 12, "freq": 0}]}, {"actual_edges": [{"edge_to_bb_id": 14, "freq": 1}, {"edge_to_bb_id": 13, "freq": 29999}], "bb_id": 12, "freq": 30000, "predicted_edges": [{"edge_to_bb_id": 14, "freq": 1}, {"edge_to_bb_id": 13, "freq": 29999}]}, {"actual_edges": [{"edge_to_bb_id": 7, "freq": 29999}], "bb_id": 13, "freq": 29999, "predicted_edges": [{"edge_to_bb_id": 7, "freq": 29999}]}, {"actual_edges": [{"edge_to_bb_id": 15, "freq": 0}], "bb_id": 14, "freq": 1, "predicted_edges": [{"edge_to_bb_id": 15, "freq": 0}]}, {"actual_edges": [{"edge_to_bb_id": 17, "freq": 0}, {"edge_to_bb_id": 16, "freq": 0}], "bb_id": 15, "freq": 0, "predicted_edges": [{"edge_to_bb_id": 17, "freq": 0}, {"edge_to_bb_id": 16, "freq": 0}]}, {"actual_edges": [{"edge_to_bb_id": 17, "freq": 0}], "bb_id": 16, "freq": 0, "predicted_edges": [{"edge_to_bb_id": 17, "freq": 0}]}, {"actual_edges": [{"edge_to_bb_id": 6, "freq": 0}], "bb_id": 17, "freq": 0, "predicted_edges": [{"edge_to_bb_id": 6, "freq": 0}]}]} +2024-12-04 19:47:02 - {'cfg_bbs': [{'bb_id': 0, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 2, 'freq': 0}, {'edge_to_bb_id': 1, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 2, 'freq': 1}, {'edge_to_bb_id': 1, 'freq': 0}]}, {'bb_id': 1, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 0}]}, {'bb_id': 2, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 1}]}, {'bb_id': 3, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 4, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 4, 'freq': 1}]}, {'bb_id': 4, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 5, 'freq': 0}, {'edge_to_bb_id': 4, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 5, 'freq': 1}, {'edge_to_bb_id': 4, 'freq': 0}]}, {'bb_id': 5, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 1}]}, {'bb_id': 6, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 7, 'freq': 1}]}, {'bb_id': 7, 'freq': 12672, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}, {'edge_to_bb_id': 8, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 6336}, {'edge_to_bb_id': 8, 'freq': 6336}]}, {'bb_id': 8, 'freq': 6336, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 6336}]}, {'bb_id': 9, 'freq': 6336, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 6336}]}, {'bb_id': 10, 'freq': 12672, 'predicted_edges': [{'edge_to_bb_id': 12, 'freq': 0}, {'edge_to_bb_id': 11, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 12, 'freq': 12672}, {'edge_to_bb_id': 11, 'freq': 0}]}, {'bb_id': 11, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 12, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 12, 'freq': 0}]}, {'bb_id': 12, 'freq': 12672, 'predicted_edges': [{'edge_to_bb_id': 14, 'freq': 0}, {'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 14, 'freq': 0}, {'edge_to_bb_id': 13, 'freq': 12671}]}, {'bb_id': 13, 'freq': 12671, 'predicted_edges': [{'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 7, 'freq': 12671}]}, {'bb_id': 14, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 15, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 15, 'freq': 0}]}, {'bb_id': 15, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 17, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 17, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}]}, {'bb_id': 16, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 17, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 17, 'freq': 0}]}, {'bb_id': 17, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 0}]}, {'bb_id': 18, 'freq': 0, 'predicted_edges': [], 'actual_edges': []}]} +2024-12-04 19:47:08 - Based on the provided bytecode and execution trace, here's a prediction of the control flow graph edges at iteration 4. The key is understanding the loop involving `bb7`, `bb8`, `bb9`, `bb10`, `bb12`, and `bb13`. + +**Understanding the Loop:** + +The loop continues as long as `a < 30000`. Inside the loop: + +* `bb7` checks if `a % 2 == 0`. +* `bb8` (if even) adds `a + b + 7` and stores it in `c`. +* `bb9` (if odd) adds `2 + c` and stores it in `b`. +* `bb10` increments `a` ( `a += 1`). +* `bb12` checks again if `a < 30000`. +* `bb13` jumps back to `bb7`. + +**Iteration 4 Prediction:** + +At offset 490, we have `a = 18960`, `b = 89946240`, `c = 89965207`. Let's trace iteration 4: + +1. **bb7:** `a % 2 == 0` (true) +2. **bb8:** `c = 18960 + 89946240 + 7 = 90000207` +3. **bb10:** `a = 18961` +4. **bb12:** `a < 30000` (true) +5. **bb13:** Jumps back to `bb7` + +**Therefore, the predicted edges at iteration 4 are:** + +* `bb7 -> bb8` (because a is even) +* `bb8 -> bb10` +* `bb10 -> bb12` +* `bb12 -> bb13` (because a < 30000) +* `bb13 -> bb7` + + +**predicted_edges:** + +``` +bb7 -> bb8 +bb8 -> bb10 +bb10 -> bb12 +bb12 -> bb13 +bb13 -> bb7 +``` + +2024-12-04 19:47:08 - {'cfg_bbs': [{'bb_id': 0, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 2, 'freq': 0}, {'edge_to_bb_id': 1, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 2, 'freq': 1}, {'edge_to_bb_id': 1, 'freq': 0}]}, {'bb_id': 1, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 0}]}, {'bb_id': 2, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 1}]}, {'bb_id': 3, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 4, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 4, 'freq': 1}]}, {'bb_id': 4, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 5, 'freq': 0}, {'edge_to_bb_id': 4, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 5, 'freq': 1}, {'edge_to_bb_id': 4, 'freq': 0}]}, {'bb_id': 5, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 1}]}, {'bb_id': 6, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 7, 'freq': 1}]}, {'bb_id': 7, 'freq': 30000, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}, {'edge_to_bb_id': 8, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 15000}, {'edge_to_bb_id': 8, 'freq': 15000}]}, {'bb_id': 8, 'freq': 15000, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 15000}]}, {'bb_id': 9, 'freq': 15000, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 15000}]}, {'bb_id': 10, 'freq': 30000, 'predicted_edges': [{'edge_to_bb_id': 12, 'freq': 0}, {'edge_to_bb_id': 11, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 12, 'freq': 30000}, {'edge_to_bb_id': 11, 'freq': 0}]}, {'bb_id': 11, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 12, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 12, 'freq': 0}]}, {'bb_id': 12, 'freq': 30000, 'predicted_edges': [{'edge_to_bb_id': 14, 'freq': 0}, {'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 14, 'freq': 1}, {'edge_to_bb_id': 13, 'freq': 29999}]}, {'bb_id': 13, 'freq': 29999, 'predicted_edges': [{'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 7, 'freq': 29999}]}, {'bb_id': 14, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 15, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 15, 'freq': 0}]}, {'bb_id': 15, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 17, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 17, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}]}, {'bb_id': 16, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 17, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 17, 'freq': 0}]}, {'bb_id': 17, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 0}]}, {'bb_id': 18, 'freq': 0, 'predicted_edges': [], 'actual_edges': []}]} +2024-12-04 19:47:17 - Based on the provided program structure, frequencies, and instruction details, here's a prediction of the `predicted_edges` at iteration 4. The key is understanding the loop between bb7, bb8, bb9, bb10, bb12, and bb13. + +**Understanding the Loop:** + +The core loop iterates based on the value of `a`. It continues as long as `a < 30000`. Inside the loop, `a` is incremented by 1 each time (bb10), and `b` and `c` are updated based on conditional logic (bb8 and bb9). The loop terminates when `a` reaches 30000. + +**Iteration Prediction:** + +Let's trace the iterations: + +* **Iteration 1:** `a` starts at 0. The loop executes. +* **Iteration 2:** `a` becomes 1. The loop executes. +* **Iteration 3:** `a` becomes 2. The loop executes. +* **Iteration 4:** `a` becomes 3. The loop continues to execute. + +**Predicted Edges (Iteration 4):** + +To accurately predict edges, we need to know the exact path taken within the loop at each iteration. Given that the loop's behavior depends on `a % 2 == 0`, let's assume the values of `a` modulo 2 to predict the path taken: + + +* **bb6:** (freq=1) -> bb7 (Always true at the beginning) +* **bb7:** (freq=n) -> bb8 (if a % 2 == 0, n=15000; else n=15000 at iteration 4) +* **bb7:** (freq=n) -> bb9 (if a % 2 != 0, n=15000; else n=0 at iteration 4) +* **bb8:** (freq=n) -> bb10 (Always true) +* **bb9:** (freq=n) -> bb10 (Always true) +* **bb10:** (freq=n) -> bb12 (Always true) +* **bb12:** (freq=n) -> bb13 (because 29999 > 1) +* **bb13:** (freq=n) -> bb7 (Always true) + + +Given that `a` is 3 (odd) at iteration 4, the predicted frequencies would be: + +* **bb7:** (freq=1) -> bb9 (freq=1) +* **bb9:** (freq=1) -> bb10 (freq=1) + + +**The other edges:** + +* **bb0:** (freq=1) -> bb2 (freq=1) +* **bb2:** (freq=1) -> bb3 (freq=1) +* **bb3:** (freq=1) -> bb4 (freq=1) +* **bb4:** (freq=1) -> bb5 (freq=1) +* **bb5:** (freq=1) -> bb6 (freq=1) +* **bb6:** (freq=1) -> bb7 (freq=1) (at least once, maybe more) +* **bb10:** (freq=1) -> bb12 (freq=1) +* **bb12:** (freq=1) -> bb13 (freq=1) +* **bb13:** (freq=1) -> bb7 (freq=1) +* **bb12:** (freq=1)-> bb14 (freq=0, this path is not followed) +* **bb14:** (freq=0)-> bb15 (freq=0, this path is not followed) +* **bb15:** (freq=0)-> bb17 (freq=0, this path is not followed) +* **bb15:** (freq=0)-> bb16 (freq=0, this path is not followed) +* **bb16:** (freq=0)-> bb17 (freq=0, this path is not followed) +* **bb17:** (freq=0)-> bb6 (freq=0, this path is not followed) +* **bb1:** (freq=0)-> bb3 (freq=0, this path is not followed) + + +The exact frequencies for bb7, bb8, bb9, bb10, bb12 and bb13 depend on how many times the loop has run, and the condition a%2==0 + + +**In summary:** A precise prediction requires running the code or simulating the loop execution up to iteration 4 to determine exactly how many times each branch within the loop is taken. However, the above analysis provides a structured approach to making that prediction. + +2024-12-04 19:47:59 - {'cfg_bbs': [{'bb_id': 0, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 2, 'freq': 0}, {'edge_to_bb_id': 1, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 2, 'freq': 1}, {'edge_to_bb_id': 1, 'freq': 0}]}, {'bb_id': 1, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 0}]}, {'bb_id': 2, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 1}]}, {'bb_id': 3, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 4, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 4, 'freq': 1}]}, {'bb_id': 4, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 5, 'freq': 0}, {'edge_to_bb_id': 4, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 5, 'freq': 1}, {'edge_to_bb_id': 4, 'freq': 0}]}, {'bb_id': 5, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 1}]}, {'bb_id': 6, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 7, 'freq': 1}]}, {'bb_id': 7, 'freq': 12832, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}, {'edge_to_bb_id': 8, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 6416}, {'edge_to_bb_id': 8, 'freq': 6416}]}, {'bb_id': 8, 'freq': 6416, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 6416}]}, {'bb_id': 9, 'freq': 6416, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 6416}]}, {'bb_id': 10, 'freq': 12832, 'predicted_edges': [{'edge_to_bb_id': 12, 'freq': 0}, {'edge_to_bb_id': 11, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 12, 'freq': 12832}, {'edge_to_bb_id': 11, 'freq': 0}]}, {'bb_id': 11, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 12, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 12, 'freq': 0}]}, {'bb_id': 12, 'freq': 12832, 'predicted_edges': [{'edge_to_bb_id': 14, 'freq': 0}, {'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 14, 'freq': 0}, {'edge_to_bb_id': 13, 'freq': 12831}]}, {'bb_id': 13, 'freq': 12831, 'predicted_edges': [{'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 7, 'freq': 12831}]}, {'bb_id': 14, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 15, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 15, 'freq': 0}]}, {'bb_id': 15, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 17, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 17, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}]}, {'bb_id': 16, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 17, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 17, 'freq': 0}]}, {'bb_id': 17, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 0}]}, {'bb_id': 18, 'freq': 0, 'predicted_edges': [], 'actual_edges': []}]} +2024-12-04 19:48:12 - {"cfg_bbs": [{"actual_edges": [{"edge_to_bb_id": 2, "freq": 1}, {"edge_to_bb_id": 1, "freq": 0}], "bb_id": 0, "freq": 1, "predicted_edges": [{"edge_to_bb_id": 2, "freq": 87}, {"edge_to_bb_id": 1, "freq": 12}]}, {"actual_edges": [{"edge_to_bb_id": 3, "freq": 0}], "bb_id": 1, "freq": 0, "predicted_edges": [{"edge_to_bb_id": 3, "freq": 54}]}, {"actual_edges": [{"edge_to_bb_id": 3, "freq": 1}], "bb_id": 2, "freq": 1, "predicted_edges": [{"edge_to_bb_id": 3, "freq": 92}]}, {"actual_edges": [{"edge_to_bb_id": 4, "freq": 1}], "bb_id": 3, "freq": 1, "predicted_edges": [{"edge_to_bb_id": 4, "freq": 26}]}, {"actual_edges": [{"edge_to_bb_id": 5, "freq": 1}, {"edge_to_bb_id": 4, "freq": 0}], "bb_id": 4, "freq": 1, "predicted_edges": [{"edge_to_bb_id": 5, "freq": 33}, {"edge_to_bb_id": 4, "freq": 75}]}, {"actual_edges": [{"edge_to_bb_id": 6, "freq": 1}], "bb_id": 5, "freq": 1, "predicted_edges": [{"edge_to_bb_id": 6, "freq": 17}]}, {"actual_edges": [{"edge_to_bb_id": 15, "freq": 0}, {"edge_to_bb_id": 7, "freq": 1}], "bb_id": 6, "freq": 1, "predicted_edges": [{"edge_to_bb_id": 15, "freq": 61}, {"edge_to_bb_id": 7, "freq": 44}]}, {"actual_edges": [{"edge_to_bb_id": 9, "freq": 6416}, {"edge_to_bb_id": 8, "freq": 6416}], "bb_id": 7, "freq": 12832, "predicted_edges": [{"edge_to_bb_id": 9, "freq": 81}, {"edge_to_bb_id": 8, "freq": 58}]}, {"actual_edges": [{"edge_to_bb_id": 10, "freq": 6416}], "bb_id": 8, "freq": 6416, "predicted_edges": [{"edge_to_bb_id": 10, "freq": 84}]}, {"actual_edges": [{"edge_to_bb_id": 10, "freq": 6416}], "bb_id": 9, "freq": 6416, "predicted_edges": [{"edge_to_bb_id": 10, "freq": 19}]}, {"actual_edges": [{"edge_to_bb_id": 12, "freq": 12832}, {"edge_to_bb_id": 11, "freq": 0}], "bb_id": 10, "freq": 12832, "predicted_edges": [{"edge_to_bb_id": 12, "freq": 50}, {"edge_to_bb_id": 11, "freq": 59}]}, {"actual_edges": [{"edge_to_bb_id": 12, "freq": 0}], "bb_id": 11, "freq": 0, "predicted_edges": [{"edge_to_bb_id": 12, "freq": 97}]}, {"actual_edges": [{"edge_to_bb_id": 14, "freq": 0}, {"edge_to_bb_id": 13, "freq": 12831}], "bb_id": 12, "freq": 12832, "predicted_edges": [{"edge_to_bb_id": 14, "freq": 21}, {"edge_to_bb_id": 13, "freq": 37}]}, {"actual_edges": [{"edge_to_bb_id": 7, "freq": 12831}], "bb_id": 13, "freq": 12831, "predicted_edges": [{"edge_to_bb_id": 7, "freq": 71}]}, {"actual_edges": [{"edge_to_bb_id": 15, "freq": 0}], "bb_id": 14, "freq": 0, "predicted_edges": [{"edge_to_bb_id": 15, "freq": 6}]}, {"actual_edges": [{"edge_to_bb_id": 17, "freq": 0}, {"edge_to_bb_id": 16, "freq": 0}], "bb_id": 15, "freq": 0, "predicted_edges": [{"edge_to_bb_id": 17, "freq": 28}, {"edge_to_bb_id": 16, "freq": 41}]}, {"actual_edges": [{"edge_to_bb_id": 17, "freq": 0}], "bb_id": 16, "freq": 0, "predicted_edges": [{"edge_to_bb_id": 17, "freq": 77}]}, {"actual_edges": [{"edge_to_bb_id": 6, "freq": 0}], "bb_id": 17, "freq": 0, "predicted_edges": [{"edge_to_bb_id": 6, "freq": 2}]}]} +2024-12-04 19:48:13 - {'cfg_bbs': [{'bb_id': 0, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 2, 'freq': 0}, {'edge_to_bb_id': 1, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 2, 'freq': 1}, {'edge_to_bb_id': 1, 'freq': 0}]}, {'bb_id': 1, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 0}]}, {'bb_id': 2, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 1}]}, {'bb_id': 3, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 4, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 4, 'freq': 1}]}, {'bb_id': 4, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 5, 'freq': 0}, {'edge_to_bb_id': 4, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 5, 'freq': 1}, {'edge_to_bb_id': 4, 'freq': 0}]}, {'bb_id': 5, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 1}]}, {'bb_id': 6, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 7, 'freq': 1}]}, {'bb_id': 7, 'freq': 30000, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}, {'edge_to_bb_id': 8, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 15000}, {'edge_to_bb_id': 8, 'freq': 15000}]}, {'bb_id': 8, 'freq': 15000, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 15000}]}, {'bb_id': 9, 'freq': 15000, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 15000}]}, {'bb_id': 10, 'freq': 30000, 'predicted_edges': [{'edge_to_bb_id': 12, 'freq': 0}, {'edge_to_bb_id': 11, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 12, 'freq': 30000}, {'edge_to_bb_id': 11, 'freq': 0}]}, {'bb_id': 11, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 12, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 12, 'freq': 0}]}, {'bb_id': 12, 'freq': 30000, 'predicted_edges': [{'edge_to_bb_id': 14, 'freq': 0}, {'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 14, 'freq': 1}, {'edge_to_bb_id': 13, 'freq': 29999}]}, {'bb_id': 13, 'freq': 29999, 'predicted_edges': [{'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 7, 'freq': 29999}]}, {'bb_id': 14, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 15, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 15, 'freq': 0}]}, {'bb_id': 15, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 17, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 17, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}]}, {'bb_id': 16, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 17, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 17, 'freq': 0}]}, {'bb_id': 17, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 0}]}, {'bb_id': 18, 'freq': 0, 'predicted_edges': [], 'actual_edges': []}]} +2024-12-04 19:48:25 - {"cfg_bbs": [{"actual_edges": [{"edge_to_bb_id": 2, "freq": 1}, {"edge_to_bb_id": 1, "freq": 0}], "bb_id": 0, "freq": 1, "predicted_edges": [{"edge_to_bb_id": 2, "freq": 87}, {"edge_to_bb_id": 1, "freq": 23}]}, {"actual_edges": [{"edge_to_bb_id": 3, "freq": 0}], "bb_id": 1, "freq": 0, "predicted_edges": [{"edge_to_bb_id": 3, "freq": 56}]}, {"actual_edges": [{"edge_to_bb_id": 3, "freq": 1}], "bb_id": 2, "freq": 1, "predicted_edges": [{"edge_to_bb_id": 3, "freq": 12}]}, {"actual_edges": [{"edge_to_bb_id": 4, "freq": 1}], "bb_id": 3, "freq": 1, "predicted_edges": [{"edge_to_bb_id": 4, "freq": 94}]}, {"actual_edges": [{"edge_to_bb_id": 5, "freq": 1}, {"edge_to_bb_id": 4, "freq": 0}], "bb_id": 4, "freq": 1, "predicted_edges": [{"edge_to_bb_id": 5, "freq": 73}, {"edge_to_bb_id": 4, "freq": 18}]}, {"actual_edges": [{"edge_to_bb_id": 6, "freq": 1}], "bb_id": 5, "freq": 1, "predicted_edges": [{"edge_to_bb_id": 6, "freq": 34}]}, {"actual_edges": [{"edge_to_bb_id": 15, "freq": 0}, {"edge_to_bb_id": 7, "freq": 1}], "bb_id": 6, "freq": 1, "predicted_edges": [{"edge_to_bb_id": 15, "freq": 65}, {"edge_to_bb_id": 7, "freq": 41}]}, {"actual_edges": [{"edge_to_bb_id": 9, "freq": 15000}, {"edge_to_bb_id": 8, "freq": 15000}], "bb_id": 7, "freq": 30000, "predicted_edges": [{"edge_to_bb_id": 9, "freq": 23}, {"edge_to_bb_id": 8, "freq": 57}]}, {"actual_edges": [{"edge_to_bb_id": 10, "freq": 15000}], "bb_id": 8, "freq": 15000, "predicted_edges": [{"edge_to_bb_id": 10, "freq": 83}]}, {"actual_edges": [{"edge_to_bb_id": 10, "freq": 15000}], "bb_id": 9, "freq": 15000, "predicted_edges": [{"edge_to_bb_id": 10, "freq": 15}]}, {"actual_edges": [{"edge_to_bb_id": 12, "freq": 30000}, {"edge_to_bb_id": 11, "freq": 0}], "bb_id": 10, "freq": 30000, "predicted_edges": [{"edge_to_bb_id": 12, "freq": 51}, {"edge_to_bb_id": 11, "freq": 92}]}, {"actual_edges": [{"edge_to_bb_id": 12, "freq": 0}], "bb_id": 11, "freq": 0, "predicted_edges": [{"edge_to_bb_id": 12, "freq": 6}]}, {"actual_edges": [{"edge_to_bb_id": 14, "freq": 1}, {"edge_to_bb_id": 13, "freq": 29999}], "bb_id": 12, "freq": 30000, "predicted_edges": [{"edge_to_bb_id": 14, "freq": 27}, {"edge_to_bb_id": 13, "freq": 89}]}, {"actual_edges": [{"edge_to_bb_id": 7, "freq": 29999}], "bb_id": 13, "freq": 29999, "predicted_edges": [{"edge_to_bb_id": 7, "freq": 44}]}, {"actual_edges": [{"edge_to_bb_id": 15, "freq": 0}], "bb_id": 14, "freq": 1, "predicted_edges": [{"edge_to_bb_id": 15, "freq": 11}]}, {"actual_edges": [{"edge_to_bb_id": 17, "freq": 0}, {"edge_to_bb_id": 16, "freq": 0}], "bb_id": 15, "freq": 0, "predicted_edges": [{"edge_to_bb_id": 17, "freq": 78}, {"edge_to_bb_id": 16, "freq": 54}]}, {"actual_edges": [{"edge_to_bb_id": 17, "freq": 0}], "bb_id": 16, "freq": 0, "predicted_edges": [{"edge_to_bb_id": 17, "freq": 39}]}, {"actual_edges": [{"edge_to_bb_id": 6, "freq": 0}], "bb_id": 17, "freq": 0, "predicted_edges": [{"edge_to_bb_id": 6, "freq": 62}]}]} +2024-12-04 19:49:48 - {'cfg_bbs': [{'bb_id': 0, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 2, 'freq': 0}, {'edge_to_bb_id': 1, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 2, 'freq': 1}, {'edge_to_bb_id': 1, 'freq': 0}]}, {'bb_id': 1, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 0}]}, {'bb_id': 2, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 1}]}, {'bb_id': 3, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 4, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 4, 'freq': 1}]}, {'bb_id': 4, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 5, 'freq': 0}, {'edge_to_bb_id': 4, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 5, 'freq': 1}, {'edge_to_bb_id': 4, 'freq': 0}]}, {'bb_id': 5, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 1}]}, {'bb_id': 6, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 7, 'freq': 1}]}, {'bb_id': 7, 'freq': 11253, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}, {'edge_to_bb_id': 8, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 5626}, {'edge_to_bb_id': 8, 'freq': 5626}]}, {'bb_id': 8, 'freq': 5626, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 5626}]}, {'bb_id': 9, 'freq': 5626, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 5626}]}, {'bb_id': 10, 'freq': 11252, 'predicted_edges': [{'edge_to_bb_id': 12, 'freq': 0}, {'edge_to_bb_id': 11, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 12, 'freq': 11252}, {'edge_to_bb_id': 11, 'freq': 0}]}, {'bb_id': 11, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 12, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 12, 'freq': 0}]}, {'bb_id': 12, 'freq': 11252, 'predicted_edges': [{'edge_to_bb_id': 14, 'freq': 0}, {'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 14, 'freq': 0}, {'edge_to_bb_id': 13, 'freq': 11252}]}, {'bb_id': 13, 'freq': 11252, 'predicted_edges': [{'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 7, 'freq': 11252}]}, {'bb_id': 14, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 15, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 15, 'freq': 0}]}, {'bb_id': 15, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 17, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 17, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}]}, {'bb_id': 16, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 17, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 17, 'freq': 0}]}, {'bb_id': 17, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 0}]}, {'bb_id': 18, 'freq': 0, 'predicted_edges': [], 'actual_edges': []}]} +2024-12-04 19:50:03 - {"cfg_bbs": [{"actual_edges": [{"edge_to_bb_id": 2, "freq": 1}, {"edge_to_bb_id": 1, "freq": 0}], "actual_freq": 1, "bb_id": 0, "predicted_edges": [{"edge_to_bb_id": 2, "freq": 87}, {"edge_to_bb_id": 1, "freq": 23}], "predicted_freq": 110}, {"actual_edges": [{"edge_to_bb_id": 3, "freq": 0}], "actual_freq": 0, "bb_id": 1, "predicted_edges": [{"edge_to_bb_id": 3, "freq": 54}], "predicted_freq": 54}, {"actual_edges": [{"edge_to_bb_id": 3, "freq": 1}], "actual_freq": 1, "bb_id": 2, "predicted_edges": [{"edge_to_bb_id": 3, "freq": 12}], "predicted_freq": 12}, {"actual_edges": [{"edge_to_bb_id": 4, "freq": 1}], "actual_freq": 1, "bb_id": 3, "predicted_edges": [{"edge_to_bb_id": 4, "freq": 95}], "predicted_freq": 95}, {"actual_edges": [{"edge_to_bb_id": 5, "freq": 1}, {"edge_to_bb_id": 4, "freq": 0}], "actual_freq": 1, "bb_id": 4, "predicted_edges": [{"edge_to_bb_id": 5, "freq": 63}, {"edge_to_bb_id": 4, "freq": 17}], "predicted_freq": 80}, {"actual_edges": [{"edge_to_bb_id": 6, "freq": 1}], "actual_freq": 1, "bb_id": 5, "predicted_edges": [{"edge_to_bb_id": 6, "freq": 55}], "predicted_freq": 55}, {"actual_edges": [{"edge_to_bb_id": 15, "freq": 0}, {"edge_to_bb_id": 7, "freq": 1}], "actual_freq": 1, "bb_id": 6, "predicted_edges": [{"edge_to_bb_id": 15, "freq": 56}, {"edge_to_bb_id": 7, "freq": 22}], "predicted_freq": 78}, {"actual_edges": [{"edge_to_bb_id": 9, "freq": 5626}, {"edge_to_bb_id": 8, "freq": 5626}], "actual_freq": 11253, "bb_id": 7, "predicted_edges": [{"edge_to_bb_id": 9, "freq": 12}, {"edge_to_bb_id": 8, "freq": 45}], "predicted_freq": 57}, {"actual_edges": [{"edge_to_bb_id": 10, "freq": 5626}], "actual_freq": 5626, "bb_id": 8, "predicted_edges": [{"edge_to_bb_id": 10, "freq": 87}], "predicted_freq": 87}, {"actual_edges": [{"edge_to_bb_id": 10, "freq": 5626}], "actual_freq": 5626, "bb_id": 9, "predicted_edges": [{"edge_to_bb_id": 10, "freq": 23}], "predicted_freq": 23}, {"actual_edges": [{"edge_to_bb_id": 12, "freq": 11252}, {"edge_to_bb_id": 11, "freq": 0}], "actual_freq": 11252, "bb_id": 10, "predicted_edges": [{"edge_to_bb_id": 12, "freq": 94}, {"edge_to_bb_id": 11, "freq": 65}], "predicted_freq": 159}, {"actual_edges": [{"edge_to_bb_id": 12, "freq": 0}], "actual_freq": 0, "bb_id": 11, "predicted_edges": [{"edge_to_bb_id": 12, "freq": 34}], "predicted_freq": 34}, {"actual_edges": [{"edge_to_bb_id": 14, "freq": 0}, {"edge_to_bb_id": 13, "freq": 11252}], "actual_freq": 11252, "bb_id": 12, "predicted_edges": [{"edge_to_bb_id": 14, "freq": 12}, {"edge_to_bb_id": 13, "freq": 86}], "predicted_freq": 98}, {"actual_edges": [{"edge_to_bb_id": 7, "freq": 11252}], "actual_freq": 11252, "bb_id": 13, "predicted_edges": [{"edge_to_bb_id": 7, "freq": 76}], "predicted_freq": 76}, {"actual_edges": [{"edge_to_bb_id": 15, "freq": 0}], "actual_freq": 0, "bb_id": 14, "predicted_edges": [{"edge_to_bb_id": 15, "freq": 11}], "predicted_freq": 11}, {"actual_edges": [{"edge_to_bb_id": 17, "freq": 0}, {"edge_to_bb_id": 16, "freq": 0}], "actual_freq": 0, "bb_id": 15, "predicted_edges": [{"edge_to_bb_id": 17, "freq": 34}, {"edge_to_bb_id": 16, "freq": 54}], "predicted_freq": 88}, {"actual_edges": [{"edge_to_bb_id": 17, "freq": 0}], "actual_freq": 0, "bb_id": 16, "predicted_edges": [{"edge_to_bb_id": 17, "freq": 23}], "predicted_freq": 23}, {"actual_edges": [{"edge_to_bb_id": 6, "freq": 0}], "actual_freq": 0, "bb_id": 17, "predicted_edges": [{"edge_to_bb_id": 6, "freq": 65}], "predicted_freq": 65}, {"actual_edges": [], "actual_freq": 0, "bb_id": 18, "predicted_edges": [], "predicted_freq": 0}]} +2024-12-04 19:50:04 - {'cfg_bbs': [{'bb_id': 0, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 2, 'freq': 0}, {'edge_to_bb_id': 1, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 2, 'freq': 1}, {'edge_to_bb_id': 1, 'freq': 0}]}, {'bb_id': 1, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 0}]}, {'bb_id': 2, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 1}]}, {'bb_id': 3, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 4, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 4, 'freq': 1}]}, {'bb_id': 4, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 5, 'freq': 0}, {'edge_to_bb_id': 4, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 5, 'freq': 1}, {'edge_to_bb_id': 4, 'freq': 0}]}, {'bb_id': 5, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 1}]}, {'bb_id': 6, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 7, 'freq': 1}]}, {'bb_id': 7, 'freq': 30000, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}, {'edge_to_bb_id': 8, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 15000}, {'edge_to_bb_id': 8, 'freq': 15000}]}, {'bb_id': 8, 'freq': 15000, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 15000}]}, {'bb_id': 9, 'freq': 15000, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 15000}]}, {'bb_id': 10, 'freq': 30000, 'predicted_edges': [{'edge_to_bb_id': 12, 'freq': 0}, {'edge_to_bb_id': 11, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 12, 'freq': 30000}, {'edge_to_bb_id': 11, 'freq': 0}]}, {'bb_id': 11, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 12, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 12, 'freq': 0}]}, {'bb_id': 12, 'freq': 30000, 'predicted_edges': [{'edge_to_bb_id': 14, 'freq': 0}, {'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 14, 'freq': 1}, {'edge_to_bb_id': 13, 'freq': 29999}]}, {'bb_id': 13, 'freq': 29999, 'predicted_edges': [{'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 7, 'freq': 29999}]}, {'bb_id': 14, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 15, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 15, 'freq': 0}]}, {'bb_id': 15, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 17, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 17, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}]}, {'bb_id': 16, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 17, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 17, 'freq': 0}]}, {'bb_id': 17, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 0}]}, {'bb_id': 18, 'freq': 0, 'predicted_edges': [], 'actual_edges': []}]} +2024-12-04 19:50:19 - {"cfg_bbs": [{"actual_edges": [{"edge_to_bb_id": 2, "freq": 1}, {"edge_to_bb_id": 1, "freq": 0}], "actual_freq": 1, "bb_id": 0, "predicted_edges": [{"edge_to_bb_id": 2, "freq": 87}, {"edge_to_bb_id": 1, "freq": 23}], "predicted_freq": 110}, {"actual_edges": [{"edge_to_bb_id": 3, "freq": 0}], "actual_freq": 0, "bb_id": 1, "predicted_edges": [{"edge_to_bb_id": 3, "freq": 54}], "predicted_freq": 54}, {"actual_edges": [{"edge_to_bb_id": 3, "freq": 1}], "actual_freq": 1, "bb_id": 2, "predicted_edges": [{"edge_to_bb_id": 3, "freq": 12}], "predicted_freq": 12}, {"actual_edges": [{"edge_to_bb_id": 4, "freq": 1}], "actual_freq": 1, "bb_id": 3, "predicted_edges": [{"edge_to_bb_id": 4, "freq": 91}], "predicted_freq": 91}, {"actual_edges": [{"edge_to_bb_id": 5, "freq": 1}, {"edge_to_bb_id": 4, "freq": 0}], "actual_freq": 1, "bb_id": 4, "predicted_edges": [{"edge_to_bb_id": 5, "freq": 34}, {"edge_to_bb_id": 4, "freq": 17}], "predicted_freq": 51}, {"actual_edges": [{"edge_to_bb_id": 6, "freq": 1}], "actual_freq": 1, "bb_id": 5, "predicted_edges": [{"edge_to_bb_id": 6, "freq": 65}], "predicted_freq": 65}, {"actual_edges": [{"edge_to_bb_id": 15, "freq": 0}, {"edge_to_bb_id": 7, "freq": 1}], "actual_freq": 1, "bb_id": 6, "predicted_edges": [{"edge_to_bb_id": 15, "freq": 21}, {"edge_to_bb_id": 7, "freq": 76}], "predicted_freq": 97}, {"actual_edges": [{"edge_to_bb_id": 9, "freq": 15000}, {"edge_to_bb_id": 8, "freq": 15000}], "actual_freq": 30000, "bb_id": 7, "predicted_edges": [{"edge_to_bb_id": 9, "freq": 11235}, {"edge_to_bb_id": 8, "freq": 18765}], "predicted_freq": 30000}, {"actual_edges": [{"edge_to_bb_id": 10, "freq": 15000}], "actual_freq": 15000, "bb_id": 8, "predicted_edges": [{"edge_to_bb_id": 10, "freq": 12000}], "predicted_freq": 12000}, {"actual_edges": [{"edge_to_bb_id": 10, "freq": 15000}], "actual_freq": 15000, "bb_id": 9, "predicted_edges": [{"edge_to_bb_id": 10, "freq": 13000}], "predicted_freq": 13000}, {"actual_edges": [{"edge_to_bb_id": 12, "freq": 30000}, {"edge_to_bb_id": 11, "freq": 0}], "actual_freq": 30000, "bb_id": 10, "predicted_edges": [{"edge_to_bb_id": 12, "freq": 28000}, {"edge_to_bb_id": 11, "freq": 2000}], "predicted_freq": 30000}, {"actual_edges": [{"edge_to_bb_id": 12, "freq": 0}], "actual_freq": 0, "bb_id": 11, "predicted_edges": [{"edge_to_bb_id": 12, "freq": 1500}], "predicted_freq": 1500}, {"actual_edges": [{"edge_to_bb_id": 14, "freq": 1}, {"edge_to_bb_id": 13, "freq": 29999}], "actual_freq": 30000, "bb_id": 12, "predicted_edges": [{"edge_to_bb_id": 14, "freq": 1234}, {"edge_to_bb_id": 13, "freq": 28766}], "predicted_freq": 30000}, {"actual_edges": [{"edge_to_bb_id": 7, "freq": 29999}], "actual_freq": 29999, "bb_id": 13, "predicted_edges": [{"edge_to_bb_id": 7, "freq": 27000}], "predicted_freq": 27000}, {"actual_edges": [{"edge_to_bb_id": 15, "freq": 0}], "actual_freq": 1, "bb_id": 14, "predicted_edges": [{"edge_to_bb_id": 15, "freq": 500}], "predicted_freq": 500}, {"actual_edges": [{"edge_to_bb_id": 17, "freq": 0}, {"edge_to_bb_id": 16, "freq": 0}], "actual_freq": 0, "bb_id": 15, "predicted_edges": [{"edge_to_bb_id": 17, "freq": 100}, {"edge_to_bb_id": 16, "freq": 200}], "predicted_freq": 300}, {"actual_edges": [{"edge_to_bb_id": 17, "freq": 0}], "actual_freq": 0, "bb_id": 16, "predicted_edges": [{"edge_to_bb_id": 17, "freq": 300}], "predicted_freq": 300}, {"actual_edges": [{"edge_to_bb_id": 6, "freq": 0}], "actual_freq": 0, "bb_id": 17, "predicted_edges": [{"edge_to_bb_id": 6, "freq": 400}], "predicted_freq": 400}, {"actual_edges": [], "actual_freq": 0, "bb_id": 18, "predicted_edges": [], "predicted_freq": 0}]} diff --git a/jac/jaclang/runtimelib/gins/cfg.py b/jac/jaclang/runtimelib/gins/cfg.py index 29ffa4cdbe..452517872c 100644 --- a/jac/jaclang/runtimelib/gins/cfg.py +++ b/jac/jaclang/runtimelib/gins/cfg.py @@ -201,18 +201,20 @@ def get_cfg_repr(self): return self.__repr__() def to_json(self): - obj = {'timestamp':0,'cfg_bbs':[]} + obj = {'cfg_bbs':[]} for node in self.nodes: bb_obj = { 'bb_id': node, 'freq':self.block_map.idx_to_block[node].exec_count, - 'edges':[] + 'predicted_edges':[], + 'actual_edges':[] } if node in self.edges and self.edges[node]: for succ in self.edges[node]: + edge_placeholder = {'edge_to_bb_id':succ,'freq': 0} + bb_obj['predicted_edges'].append(edge_placeholder) edge_obj = {'edge_to_bb_id':succ,'freq': self.edge_counts[(node, succ)]} - bb_obj['edges'].append(edge_obj) - bb_obj['edges'].append(edge_obj) + bb_obj['actual_edges'].append(edge_obj) obj['cfg_bbs'].append(bb_obj) return obj diff --git a/jac/jaclang/runtimelib/gins/ghost.py b/jac/jaclang/runtimelib/gins/ghost.py index 4e05fc3a45..ef51f6fcfb 100644 --- a/jac/jaclang/runtimelib/gins/ghost.py +++ b/jac/jaclang/runtimelib/gins/ghost.py @@ -4,6 +4,7 @@ import os import threading import time +import logging from jaclang.runtimelib.gins.model import Gemini from jaclang.runtimelib.gins.tracer import CFGTracker, CfgDeque @@ -30,6 +31,19 @@ def __init__(self): self.__cfg_deque_dict = dict() self.__cfg_deque_size = 5 + self.logger = logging.getLogger() + if self.logger.hasHandlers(): + self.logger.handlers.clear() + logging.basicConfig( + level=logging.INFO, # Set the log level + format='%(asctime)s - %(message)s', # Set the log message format + datefmt='%Y-%m-%d %H:%M:%S', # Set the timestamp format + handlers=[ + logging.FileHandler("test.txt", mode='a'), # Log to a file in append mode + ] + ) + + def set_cfgs(self, cfgs): self.cfg_cv.acquire() self.cfgs = cfgs @@ -183,10 +197,10 @@ def prompt_llm(self, verbose: bool = False): self.finished_exception_lock.release() - prompt += "\nCan you identity bottlneck optimizations or where the code can error out?" - prompt += "\n(Reason about the program using cfg, semantic and type information. Instead of saying what BB could be improved, reason about the program itself and what improvements could be made.)" - prompt += "\n If variable values are available, reason about at what point did a variable cause an issue" - + # prompt += "\nCan you identity bottlneck optimizations or where the code can error out?" + # prompt += "\n(Reason about the program using cfg, semantic and type information. Instead of saying what BB could be improved, reason about the program itself and what improvements could be made.)" + # prompt += "\n If variable values are available, reason about at what point did a variable cause an issue" + prompt += "\n Please use the following information fill in predicted_edges[freq] for each BB edge with something completely random" if verbose: print(prompt) @@ -252,12 +266,9 @@ def worker(self): if self.cfgs == None: print("waiting") self.cfg_cv.wait() - for module_name, cfg in self.cfgs.items(): - print(f"Name: {module_name}") + # for module_name, cfg in self.cfgs.items(): + # print(f"Name: {module_name}") self.cfg_cv.release() - print("CFG INFO") - print(self.cfgs) - print("EO CFG INFO") # Once cv has been notifie, self.cfgs is no longer accessed across threads current_executing_bbs = {} @@ -313,6 +324,7 @@ def update_cfg(): self.variable_values = self.tracker.get_variable_values() self.update_cfg_deque(cfg.get_cfg_repr(), module) + self.logger.info(cfg.to_json()) self.finished_exception_lock.acquire() while not self.finished: @@ -321,17 +333,15 @@ def update_cfg(): time.sleep(1) print("\nUpdating cfgs") update_cfg() - # self.prompt_llm_with_history() + self.logger.info(self.prompt_llm()) + # print(f"history size: {len(self.__cfg_deque_dict['hot_path'])}") self.finished_exception_lock.acquire() - time.sleep(1) + # time.sleep(1) self.finished_exception_lock.release() print("\nUpdating cfgs at the end") update_cfg() - print("CCURRRENT CFG STUFFFFFF") - for module, cfg in self.cfgs.items(): - print(module) - print(cfg) - # self.prompt_llm_with_history(verbose=True) + # print(self.__cfg_deque_dict['hot_path'].get_cfg_repr()) + self.logger.info(self.prompt_llm()) diff --git a/jac/jaclang/runtimelib/gins/model.py b/jac/jaclang/runtimelib/gins/model.py index a4918c233d..e72ce2d876 100644 --- a/jac/jaclang/runtimelib/gins/model.py +++ b/jac/jaclang/runtimelib/gins/model.py @@ -1,5 +1,19 @@ -import typing_extensions as typing - +from typing import List, TypedDict + +#for identifying hot edge prediction +class Edge(TypedDict): + edge_to_bb_id: int + freq: int + +class BasicBlock(TypedDict): + bb_id: int + actual_freq: int + predicted_freq: int + predicted_edges: List[Edge] + actual_edges: List[Edge] + +class Cfg(TypedDict): + cfg_bbs: List[BasicBlock] """Generative AI model integration for GINS """ class BaseModel: @@ -37,5 +51,10 @@ def config(self): return None def generate(self, prompt: str): - response = self.model.generate_content(prompt) + import google.generativeai as genai + response = self.model.generate_content( + prompt, + generation_config=genai.GenerationConfig( + response_mime_type='application/json', + response_schema=Cfg),) return response.text diff --git a/jac/jaclang/runtimelib/gins/tracer.py b/jac/jaclang/runtimelib/gins/tracer.py index 6adae714ac..df81631995 100644 --- a/jac/jaclang/runtimelib/gins/tracer.py +++ b/jac/jaclang/runtimelib/gins/tracer.py @@ -25,6 +25,12 @@ def add_cfg(self, cfg_repr: str): if len(self.__deque) > self.__max_size: self.__deque.popleft() + def get_latest_cfg(self): + return self.__deque[-1] + + def __len__(self): + return len(self.__deque) + def get_cfg_repr(self): res = [f"CFG Changes in last {len(self.__deque)} Updates:\n"] for idx, cfg in enumerate(self.__deque): @@ -99,54 +105,54 @@ def trace_callback( variable_dict[var_name] = frame.f_locals[var_name] self.curr_variables[module] = (frame.f_lasti, variable_dict) self.curr_variables_lock.release() - elif event == "line": - ### - # this is really circumlocutious, but is also how - # [watchpoints](https://github.com/gaogaotiantian/watchpoints/tree/master) - # works - ### - try: - #print(inspect.getsourcefile(frame.f_code)) - #print(frame.f_lineno) - # TODO: super inefficient but just for now - # inspect.getsource doesn't seem to work like it does for - # regular python (see test_tracer.py) - # NOTE: we're parsing jac lines as python, fingers crossed - with open(inspect.getsourcefile(frame.f_code)) as file: - line_asts = ast.parse(file.readlines()[frame.f_lineno - 1].lstrip().rstrip(';')) - #print(" ", frame.f_lineno, ast.unparse(line_ast)) - except (IndexError, SyntaxError): - return self.trace_callback - #print(ast.dump(a)) - #print(len(a.body)) - assert len(line_asts.body) == 1 # we only parsed one line - line_ast = line_asts.body[0] - if isinstance(line_ast, ast.Assign) or isinstance(line_ast, ast.AugAssign): - # yes, I know this isn't strictly necessary in python - lhs_ast = None - rhs_ast = None - if isinstance(line_ast, ast.Assign): - assert len(line_ast.targets) == 1, "Only handling single targets right now" - lhs_ast = line_ast.targets[0] - elif isinstance(line_ast, ast.AugAssign): - lhs_ast = line_ast.target - lhs_var = ast.unparse(lhs_ast) - rhs_ast = line_ast.value - # NOTE: for some reason, eval(ast.Expression(rhs_ast)) doesn't work - rhs_value = eval(ast.unparse(rhs_ast), frame.f_globals, frame.f_locals) - if isinstance(line_ast, ast.Assign): - exec(f"{lhs_var} = {rhs_value}\n", frame.f_globals, frame.f_locals) - print(f"{lhs_var} = {rhs_value}") - elif isinstance(line_ast, ast.AugAssign): - exec(f"{lhs_var} += {rhs_value}\n", frame.f_globals, frame.f_locals) - print(f"{lhs_var} (+)= {rhs_value}") - #print(frame.f_locals) - if lhs_var == 'PROGRAM_INPUT': - if isinstance(line_ast, ast.AugAssign): - assert False, "Unimplemented" - print("tracer: PROGRAM_INPUT = ", rhs_value) - # this only silences some of the - # "RuntimeWarning: assigning None to unbound local" warnings - with warnings.catch_warnings(action="ignore"): - frame.f_lineno += 1 + # elif event == "line": + # ### + # # this is really circumlocutious, but is also how + # # [watchpoints](https://github.com/gaogaotiantian/watchpoints/tree/master) + # # works + # ### + # try: + # #print(inspect.getsourcefile(frame.f_code)) + # #print(frame.f_lineno) + # # TODO: super inefficient but just for now + # # inspect.getsource doesn't seem to work like it does for + # # regular python (see test_tracer.py) + # # NOTE: we're parsing jac lines as python, fingers crossed + # with open(inspect.getsourcefile(frame.f_code)) as file: + # line_asts = ast.parse(file.readlines()[frame.f_lineno - 1].lstrip().rstrip(';')) + # #print(" ", frame.f_lineno, ast.unparse(line_ast)) + # except (IndexError, SyntaxError): + # return self.trace_callback + # #print(ast.dump(a)) + # #print(len(a.body)) + # assert len(line_asts.body) == 1 # we only parsed one line + # line_ast = line_asts.body[0] + # if isinstance(line_ast, ast.Assign) or isinstance(line_ast, ast.AugAssign): + # # yes, I know this isn't strictly necessary in python + # lhs_ast = None + # rhs_ast = None + # if isinstance(line_ast, ast.Assign): + # assert len(line_ast.targets) == 1, "Only handling single targets right now" + # lhs_ast = line_ast.targets[0] + # elif isinstance(line_ast, ast.AugAssign): + # lhs_ast = line_ast.target + # lhs_var = ast.unparse(lhs_ast) + # rhs_ast = line_ast.value + # # NOTE: for some reason, eval(ast.Expression(rhs_ast)) doesn't work + # rhs_value = eval(ast.unparse(rhs_ast), frame.f_globals, frame.f_locals) + # if isinstance(line_ast, ast.Assign): + # exec(f"{lhs_var} = {rhs_value}\n", frame.f_globals, frame.f_locals) + # print(f"{lhs_var} = {rhs_value}") + # elif isinstance(line_ast, ast.AugAssign): + # exec(f"{lhs_var} += {rhs_value}\n", frame.f_globals, frame.f_locals) + # print(f"{lhs_var} (+)= {rhs_value}") + # #print(frame.f_locals) + # if lhs_var == 'PROGRAM_INPUT': + # if isinstance(line_ast, ast.AugAssign): + # assert False, "Unimplemented" + # print("tracer: PROGRAM_INPUT = ", rhs_value) + # # this only silences some of the + # # "RuntimeWarning: assigning None to unbound local" warnings + # with warnings.catch_warnings(action="ignore"): + # frame.f_lineno += 1 return self.trace_callback From d4d2d28b92b50c5f8a252abbbb397280b4e210f2 Mon Sep 17 00:00:00 2001 From: Jakob Louis Therkelsen Date: Thu, 5 Dec 2024 11:44:57 -0500 Subject: [PATCH 80/84] seperate structured output --- jac/jaclang/runtimelib/gins/model.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/jac/jaclang/runtimelib/gins/model.py b/jac/jaclang/runtimelib/gins/model.py index e72ce2d876..4ae60baf89 100644 --- a/jac/jaclang/runtimelib/gins/model.py +++ b/jac/jaclang/runtimelib/gins/model.py @@ -51,6 +51,10 @@ def config(self): return None def generate(self, prompt: str): + response = self.model.generate_content(prompt) + return response.text + + def generate_structured(self, prompt: str): import google.generativeai as genai response = self.model.generate_content( prompt, From e8714e167160269724a6f5f36ae953f5ef5a0f5b Mon Sep 17 00:00:00 2001 From: Jakob Louis Therkelsen Date: Thu, 5 Dec 2024 14:08:52 -0500 Subject: [PATCH 81/84] hot_path updates and input generation --- jac/examples/gins_scripts/hot_path.jac | 40 +- .../gins_scripts/inputs/generate_inputs.py | 39 + jac/examples/gins_scripts/inputs/test.txt | 1004 ++++++++++++++++- .../gins_scripts/inputs/test_predict.txt | 1000 ++++++++++++++++ jac/jaclang/runtimelib/gins/ghost.py | 42 +- 5 files changed, 2104 insertions(+), 21 deletions(-) create mode 100644 jac/examples/gins_scripts/inputs/generate_inputs.py create mode 100644 jac/examples/gins_scripts/inputs/test_predict.txt diff --git a/jac/examples/gins_scripts/hot_path.jac b/jac/examples/gins_scripts/hot_path.jac index 239a1f194e..88c7ee58f3 100644 --- a/jac/examples/gins_scripts/hot_path.jac +++ b/jac/examples/gins_scripts/hot_path.jac @@ -1,29 +1,43 @@ import:py os; +import:py random; with entry { - a:int = 0; - b:int = 0; - c:int = 0; current_directory = os.path.dirname(os.path.abspath(__file__)); input_dir = os.path.join(current_directory,'inputs/test.txt'); + var = []; with open(input_dir, 'r') as file { for line in file { # Process each line here - var.append(int(line.strip())); # .strip() removes trailing newlines + var.append(float(line.strip())); # .strip() removes trailing newlines } } - while a < 30000 { - if a % 2 == 0{ - c = a+b+7; - + a:int = 0; + b:int = 0; + c:int = 0; + input_val:float = 0.0; + test_val: float = 0.0; + count:int = 0; + accum_sum:float = 0.0; + changing_average:float = 0; + change_reduction_arr:list=[]; + for val in var { + input_val = val; + count = count + 1; + accum_sum = accum_sum + val; + changing_average = accum_sum/count; + if (changing_average)/100 < 1.0 { + test_val:int = test_val + 100.0; } else { - b = 2 + c; - } - a = a+ 1; - if a == 0{ - print("nothing"); + for i in range(count) { + test_val = test_val + 10.0; + } } } + while test_val > 0 { + reduce:float = random.uniform(5.0,10.0); + test_val -= 100.0; + change_reduction_arr.append(test_val); + } } \ No newline at end of file diff --git a/jac/examples/gins_scripts/inputs/generate_inputs.py b/jac/examples/gins_scripts/inputs/generate_inputs.py new file mode 100644 index 0000000000..10f32193e1 --- /dev/null +++ b/jac/examples/gins_scripts/inputs/generate_inputs.py @@ -0,0 +1,39 @@ +import numpy as np +import os +import random + +current_directory = os.path.dirname(os.path.abspath(__file__)) +output_file = os.path.join(current_directory,'test_predict.txt') + + +# mean = 92 +# std_dev = 9 +# num_samples = 100 +# skewness = 5 +# random_numbers = list(np.random.normal(mean,std_dev, num_samples)) +# w_str = "\n".join(str(round(num,3)) for num in random_numbers) + +num_samples = 1000 +start_value = 99 +end_avg = 105 + +# Initialize storage for sensor data +sensor_data = [] + +# Calculate the amount to increment each value to reach the desired average +increment = (end_avg - start_value) / num_samples + +current_value = start_value +for _ in range(num_samples): + # Add some noise to make the data more realistic + noise = random.uniform(-0.7, 0.5) + sensor_value = current_value + noise + sensor_data.append(sensor_value) + + # Update current value towards the end_avg + current_value += increment + +# Write data to output file +with open(output_file, 'w') as file: + for value in sensor_data: + file.write(f"{value:.2f}\n") \ No newline at end of file diff --git a/jac/examples/gins_scripts/inputs/test.txt b/jac/examples/gins_scripts/inputs/test.txt index b17865743d..3163f20534 100644 --- a/jac/examples/gins_scripts/inputs/test.txt +++ b/jac/examples/gins_scripts/inputs/test.txt @@ -1,4 +1,1000 @@ -1 -2 -3 -4 \ No newline at end of file +99.11 +98.88 +98.83 +99.11 +98.99 +99.42 +99.43 +98.56 +99.28 +98.75 +99.12 +99.23 +99.39 +99.03 +98.65 +98.74 +98.49 +98.77 +99.05 +98.82 +99.12 +99.53 +99.49 +99.01 +99.25 +99.40 +98.63 +98.63 +98.95 +99.58 +98.53 +99.66 +99.55 +98.86 +99.65 +98.62 +99.18 +99.30 +99.68 +99.72 +99.74 +99.42 +98.76 +99.24 +99.32 +99.46 +99.76 +99.28 +99.71 +98.73 +98.99 +98.69 +98.69 +99.75 +99.23 +99.79 +99.60 +99.66 +99.77 +98.71 +98.87 +99.00 +99.51 +98.82 +99.27 +99.68 +98.92 +99.08 +99.09 +99.52 +99.27 +98.82 +99.42 +99.54 +99.79 +99.71 +99.59 +99.04 +99.73 +99.94 +99.43 +98.96 +98.90 +99.80 +99.79 +99.48 +99.85 +99.85 +99.07 +99.31 +99.90 +99.13 +99.21 +99.24 +99.27 +99.51 +99.68 +100.01 +99.13 +99.28 +99.11 +99.35 +99.19 +99.57 +99.05 +99.49 +99.28 +98.96 +99.20 +99.66 +99.73 +100.14 +99.48 +99.80 +99.38 +99.37 +100.11 +99.11 +99.35 +99.27 +99.77 +99.21 +100.03 +99.63 +99.62 +100.23 +99.88 +99.54 +99.41 +99.60 +100.04 +99.53 +99.21 +99.84 +99.53 +99.27 +99.86 +99.94 +99.62 +100.32 +100.32 +99.22 +99.33 +99.64 +99.61 +99.57 +99.78 +99.87 +99.52 +100.22 +99.77 +99.23 +99.74 +99.71 +99.67 +99.97 +100.03 +99.90 +99.50 +100.35 +99.63 +99.29 +100.11 +100.20 +100.42 +100.20 +100.02 +99.71 +100.41 +99.67 +99.83 +99.65 +99.66 +99.66 +99.47 +99.43 +100.11 +99.50 +99.84 +99.69 +100.56 +100.41 +100.19 +100.36 +99.97 +99.91 +100.13 +99.83 +100.20 +100.07 +99.55 +99.89 +100.58 +99.98 +100.34 +100.46 +99.84 +100.13 +100.43 +100.64 +100.09 +99.91 +100.03 +99.97 +100.64 +99.78 +99.57 +100.41 +99.83 +100.36 +99.93 +99.59 +99.58 +99.62 +100.60 +99.72 +100.39 +99.61 +99.71 +99.73 +99.74 +100.31 +100.07 +99.79 +99.96 +100.58 +100.38 +100.35 +99.83 +100.76 +100.13 +100.78 +100.27 +100.59 +100.43 +100.37 +100.21 +100.33 +100.93 +99.75 +99.89 +100.73 +100.56 +100.89 +100.23 +100.24 +100.06 +100.06 +100.32 +100.86 +100.61 +100.52 +100.30 +100.78 +100.08 +100.19 +100.05 +100.53 +100.70 +101.01 +99.91 +100.70 +100.94 +100.51 +100.51 +101.04 +100.52 +100.23 +100.87 +100.97 +100.20 +100.36 +100.03 +100.25 +100.52 +101.09 +100.97 +100.18 +101.04 +100.76 +100.37 +101.12 +100.11 +101.13 +100.28 +100.28 +100.24 +100.17 +100.56 +101.14 +100.79 +101.01 +100.59 +100.06 +101.15 +101.08 +100.86 +100.77 +100.67 +100.56 +100.15 +101.20 +100.84 +100.57 +100.17 +101.05 +100.53 +100.61 +100.61 +101.23 +100.58 +100.28 +100.52 +101.15 +101.21 +101.21 +100.67 +100.64 +101.26 +100.22 +100.52 +101.37 +100.78 +100.88 +101.01 +100.67 +101.29 +101.26 +100.85 +100.29 +100.35 +100.91 +101.08 +100.36 +100.68 +100.41 +100.89 +100.52 +100.73 +101.40 +100.70 +101.22 +100.49 +100.49 +100.43 +101.52 +101.06 +101.02 +101.41 +100.48 +100.77 +101.21 +100.81 +100.60 +100.76 +101.01 +100.58 +101.53 +100.97 +101.22 +100.51 +100.80 +100.58 +100.67 +101.26 +100.72 +101.11 +101.65 +100.52 +100.92 +101.02 +100.61 +100.90 +101.54 +101.49 +100.96 +101.16 +100.75 +100.88 +101.09 +101.66 +100.69 +101.56 +100.82 +101.09 +101.39 +101.68 +100.73 +100.95 +100.79 +101.38 +100.85 +101.75 +100.78 +101.22 +101.17 +101.49 +101.43 +100.86 +101.14 +101.90 +101.21 +100.76 +101.79 +101.56 +101.87 +101.46 +101.68 +101.80 +100.90 +100.96 +101.40 +101.24 +101.79 +101.34 +101.94 +101.72 +101.52 +101.93 +101.62 +101.64 +101.52 +101.98 +101.98 +101.54 +101.56 +101.59 +101.11 +102.03 +101.97 +101.23 +101.76 +101.42 +101.60 +101.05 +101.21 +101.10 +101.88 +101.70 +101.80 +100.97 +101.88 +102.15 +101.89 +101.63 +102.15 +102.11 +102.02 +102.16 +102.15 +101.86 +102.18 +101.12 +101.80 +101.65 +101.08 +101.13 +101.93 +101.27 +101.75 +102.23 +101.44 +101.45 +102.26 +101.61 +101.53 +101.45 +101.12 +102.01 +102.20 +102.17 +101.96 +101.62 +101.89 +101.44 +101.38 +101.75 +102.05 +102.13 +101.81 +101.52 +101.32 +101.71 +101.52 +101.82 +101.45 +102.31 +101.74 +102.05 +101.24 +102.06 +102.12 +101.32 +101.74 +102.22 +102.03 +101.49 +101.52 +101.54 +102.24 +102.08 +101.43 +102.45 +101.32 +101.71 +101.35 +101.42 +102.44 +101.96 +101.86 +101.61 +101.93 +102.47 +102.31 +102.54 +102.20 +101.93 +102.31 +102.00 +102.57 +102.25 +101.52 +101.53 +102.19 +102.19 +101.81 +102.41 +102.43 +101.67 +101.56 +101.89 +102.60 +102.23 +102.49 +101.77 +101.84 +101.76 +102.55 +101.65 +102.32 +101.79 +102.18 +102.57 +102.09 +102.51 +102.66 +102.48 +101.72 +102.23 +101.78 +102.51 +102.15 +102.08 +102.59 +102.72 +102.55 +102.46 +102.33 +102.81 +102.39 +102.83 +101.77 +102.83 +102.35 +101.73 +102.31 +102.54 +102.43 +102.39 +102.09 +102.60 +101.83 +102.58 +102.53 +102.29 +101.96 +101.98 +101.78 +102.95 +102.94 +102.75 +102.77 +102.48 +102.53 +102.38 +102.95 +102.16 +101.98 +102.39 +101.94 +102.18 +101.85 +102.21 +102.47 +101.90 +102.07 +102.07 +102.70 +102.43 +101.96 +102.59 +102.06 +102.25 +102.97 +102.74 +103.07 +102.95 +102.90 +102.53 +102.54 +102.36 +102.22 +103.05 +102.46 +102.24 +102.58 +102.90 +102.25 +102.75 +103.11 +102.54 +102.44 +102.85 +102.78 +102.87 +102.90 +102.56 +103.11 +102.96 +102.10 +102.93 +102.23 +102.59 +102.70 +103.24 +102.72 +102.73 +103.08 +102.87 +103.10 +102.35 +103.00 +102.39 +102.99 +103.05 +102.38 +102.49 +102.41 +102.30 +103.33 +103.06 +102.47 +102.78 +103.35 +102.46 +102.30 +102.85 +102.40 +102.72 +102.65 +102.44 +103.46 +102.75 +103.17 +103.08 +102.48 +103.49 +102.50 +102.84 +102.53 +103.02 +103.36 +102.49 +102.68 +102.47 +103.33 +102.62 +102.82 +103.57 +102.90 +103.07 +102.56 +102.60 +103.55 +102.69 +103.43 +103.35 +103.19 +102.65 +103.08 +103.05 +103.18 +103.20 +103.42 +103.03 +103.50 +103.29 +102.91 +102.53 +103.50 +102.61 +103.24 +103.53 +103.29 +102.97 +102.81 +102.62 +102.70 +102.64 +103.21 +103.66 +103.35 +102.67 +102.83 +103.70 +103.73 +103.02 +103.15 +102.89 +103.02 +103.29 +103.74 +103.83 +103.80 +103.50 +103.83 +102.88 +103.41 +103.09 +102.78 +102.79 +102.99 +102.95 +102.88 +103.48 +103.58 +102.82 +103.01 +103.04 +103.63 +103.22 +103.84 +103.46 +103.65 +103.69 +103.03 +103.89 +103.11 +103.56 +103.27 +103.48 +103.87 +103.95 +103.17 +103.53 +103.93 +102.91 +103.26 +102.87 +103.70 +103.27 +103.40 +103.77 +103.58 +103.41 +103.25 +103.49 +103.56 +103.18 +103.39 +103.77 +103.32 +103.94 +103.83 +104.01 +103.61 +103.46 +104.12 +103.82 +103.77 +103.99 +103.25 +103.28 +103.91 +103.84 +103.87 +103.43 +103.62 +103.72 +103.50 +103.10 +103.49 +103.44 +103.09 +103.88 +103.98 +103.96 +103.21 +104.01 +104.16 +103.76 +104.18 +104.17 +103.45 +104.21 +103.99 +104.17 +103.39 +104.06 +103.50 +104.14 +103.86 +104.01 +103.48 +103.20 +104.14 +104.25 +104.04 +103.71 +104.06 +103.72 +103.35 +103.29 +103.56 +103.81 +103.27 +103.89 +104.16 +103.60 +103.52 +103.68 +104.31 +103.47 +104.25 +103.51 +103.41 +103.87 +103.57 +104.01 +103.82 +104.30 +104.17 +104.52 +103.45 +103.80 +104.14 +104.23 +103.54 +103.77 +104.00 +103.58 +104.49 +104.50 +104.35 +103.59 +104.41 +104.02 +104.10 +104.39 +103.62 +104.30 +104.65 +104.02 +104.27 +103.90 +104.07 +104.12 +103.57 +103.88 +104.39 +104.59 +104.24 +104.25 +103.93 +103.93 +104.13 +104.04 +104.19 +104.70 +104.67 +103.62 +104.06 +104.56 +103.68 +104.35 +104.12 +104.32 +103.81 +104.42 +104.51 +103.81 +104.12 +103.78 +103.88 +104.30 +104.66 +104.00 +103.98 +104.72 +103.87 +104.67 +104.17 +104.30 +104.51 +104.70 +103.85 +104.61 +104.77 +104.59 +104.24 +104.07 +104.18 +104.19 +104.88 +104.81 +104.08 +104.70 +103.82 +104.01 +104.06 +104.87 +104.27 +104.06 +104.23 +104.17 +104.63 +104.10 +104.71 +104.66 +105.02 +104.80 +104.49 +104.87 +104.07 +104.50 +104.14 +104.97 +104.64 +103.93 +104.29 +104.11 +104.10 +104.50 +104.11 +104.52 +104.06 +104.48 +104.99 +104.60 +104.78 +104.49 +105.00 +104.63 +104.48 +104.40 +104.79 +104.12 +104.45 +104.53 +104.18 +104.15 +104.78 +104.22 +104.80 +105.24 +104.89 +104.31 +104.53 +104.32 +104.89 +104.99 +104.21 +105.21 +104.94 +105.25 +104.89 +104.68 +104.47 +105.03 +104.22 +105.25 +104.74 +104.97 +105.20 +105.02 +105.19 +105.21 +104.79 +105.29 +104.70 +105.37 +104.96 +104.60 +104.35 +104.57 +105.27 +104.98 +104.68 +105.45 +104.76 diff --git a/jac/examples/gins_scripts/inputs/test_predict.txt b/jac/examples/gins_scripts/inputs/test_predict.txt new file mode 100644 index 0000000000..bb16927d4b --- /dev/null +++ b/jac/examples/gins_scripts/inputs/test_predict.txt @@ -0,0 +1,1000 @@ +99.01 +99.23 +98.85 +99.05 +98.55 +98.71 +99.10 +98.90 +98.44 +98.64 +98.97 +98.97 +99.15 +99.48 +99.52 +98.72 +99.06 +98.71 +98.84 +98.49 +99.18 +98.73 +98.81 +99.17 +99.02 +98.78 +99.37 +98.51 +99.16 +98.49 +98.62 +98.90 +99.26 +99.65 +98.86 +98.95 +98.52 +98.70 +98.83 +99.05 +99.67 +99.40 +99.05 +98.93 +99.16 +98.77 +98.58 +98.67 +99.39 +99.77 +98.80 +99.74 +99.23 +99.30 +98.98 +99.80 +98.88 +98.88 +99.57 +99.83 +99.19 +99.86 +99.38 +98.76 +98.87 +99.02 +99.44 +98.79 +99.45 +99.81 +98.97 +99.15 +99.14 +99.40 +99.88 +98.90 +98.95 +99.33 +99.82 +98.88 +99.50 +99.40 +99.13 +99.84 +99.84 +99.75 +99.12 +99.53 +99.12 +98.97 +99.45 +99.93 +98.85 +99.18 +99.38 +99.98 +99.60 +99.52 +99.21 +99.29 +99.29 +100.02 +99.41 +99.09 +99.73 +99.71 +99.29 +99.17 +99.93 +99.03 +99.49 +99.31 +99.39 +99.98 +99.55 +99.67 +99.70 +99.17 +99.84 +99.90 +100.04 +99.81 +99.16 +100.09 +100.11 +99.33 +99.56 +99.27 +100.02 +99.14 +99.92 +99.33 +99.51 +99.11 +99.34 +99.55 +99.86 +99.41 +99.93 +99.89 +100.02 +100.19 +99.18 +99.68 +100.18 +99.57 +99.28 +99.30 +100.22 +100.10 +100.13 +100.10 +99.57 +99.79 +99.67 +100.09 +100.10 +100.14 +100.05 +100.03 +100.39 +100.20 +100.46 +100.43 +100.18 +100.16 +99.96 +99.42 +99.68 +99.62 +99.41 +100.08 +100.18 +100.24 +99.61 +100.28 +100.35 +99.40 +100.55 +100.10 +99.73 +99.56 +100.41 +100.28 +100.27 +100.60 +99.73 +100.11 +99.57 +99.73 +100.58 +99.91 +99.86 +100.27 +100.42 +99.59 +99.64 +100.17 +100.30 +99.90 +100.25 +100.47 +100.41 +100.56 +99.82 +99.88 +99.79 +100.15 +100.10 +99.70 +99.76 +100.72 +100.54 +99.77 +100.40 +99.71 +100.25 +99.74 +100.77 +100.48 +100.80 +100.20 +100.17 +99.77 +100.36 +100.48 +100.54 +100.37 +100.63 +100.85 +100.84 +100.50 +100.23 +100.60 +100.01 +100.83 +100.31 +100.91 +99.83 +100.41 +100.43 +100.46 +100.94 +100.29 +100.75 +100.85 +100.90 +100.81 +100.38 +100.36 +100.81 +101.00 +100.69 +100.00 +100.11 +99.93 +100.90 +100.80 +101.00 +99.92 +100.28 +100.85 +100.19 +100.21 +100.03 +100.12 +100.50 +100.52 +100.90 +100.50 +100.06 +100.87 +101.02 +100.22 +100.63 +100.47 +100.60 +100.72 +100.33 +100.71 +100.51 +100.42 +101.01 +100.31 +101.02 +100.62 +100.20 +100.91 +101.04 +100.53 +101.10 +101.23 +100.60 +100.37 +100.65 +101.00 +100.22 +101.10 +101.19 +100.82 +100.89 +100.12 +100.75 +101.06 +101.23 +101.21 +100.15 +100.78 +101.29 +100.17 +100.71 +100.62 +101.03 +100.40 +101.12 +100.48 +101.31 +101.24 +100.61 +100.65 +101.40 +100.35 +101.33 +100.74 +101.32 +100.61 +101.35 +100.46 +101.10 +100.64 +101.30 +100.79 +101.32 +100.69 +100.49 +101.04 +101.48 +100.84 +100.94 +100.73 +100.97 +100.67 +101.08 +100.93 +100.74 +101.54 +100.49 +101.38 +101.00 +101.10 +101.04 +100.47 +101.13 +101.45 +100.78 +101.61 +101.59 +100.79 +101.27 +101.34 +101.12 +100.67 +100.68 +101.45 +101.41 +101.39 +100.88 +101.19 +101.07 +101.49 +101.38 +101.17 +101.13 +100.69 +100.89 +101.23 +101.28 +101.22 +101.12 +100.78 +101.57 +101.50 +101.50 +101.06 +101.63 +100.63 +100.78 +101.61 +101.71 +101.12 +101.21 +101.22 +100.73 +100.85 +101.40 +101.75 +101.69 +101.30 +101.15 +100.86 +101.60 +101.56 +101.89 +101.30 +101.21 +101.08 +101.70 +100.85 +101.56 +100.85 +101.71 +101.35 +101.07 +101.33 +101.81 +101.52 +100.83 +101.01 +102.00 +101.79 +101.60 +101.95 +101.70 +101.97 +101.92 +102.02 +101.00 +101.16 +101.82 +101.28 +100.96 +101.09 +101.64 +101.72 +101.06 +101.31 +101.50 +101.69 +101.31 +101.29 +101.78 +101.89 +101.10 +101.78 +101.81 +101.27 +101.67 +101.61 +102.11 +102.15 +101.04 +101.85 +101.94 +101.92 +101.72 +101.79 +101.53 +101.13 +101.08 +101.35 +101.17 +101.29 +102.24 +101.77 +101.92 +101.79 +102.15 +101.92 +101.26 +101.17 +102.07 +101.77 +102.25 +101.99 +101.73 +101.25 +102.21 +102.34 +101.49 +101.91 +101.83 +101.56 +101.46 +102.30 +101.23 +102.02 +101.49 +102.35 +102.38 +101.57 +101.98 +101.66 +101.62 +101.84 +101.42 +101.87 +101.43 +101.53 +101.29 +101.53 +101.67 +101.74 +101.48 +101.44 +101.57 +101.75 +101.50 +101.37 +102.20 +102.14 +101.77 +102.51 +101.82 +102.05 +102.27 +101.63 +102.22 +101.94 +102.09 +102.42 +102.10 +102.36 +101.60 +101.76 +102.47 +102.01 +102.05 +101.93 +102.43 +101.86 +101.58 +101.71 +101.52 +102.29 +101.67 +102.00 +101.81 +101.78 +101.70 +102.51 +102.45 +101.70 +102.50 +101.94 +102.28 +101.96 +102.07 +102.09 +102.77 +101.66 +102.40 +102.71 +102.26 +102.26 +102.00 +102.47 +102.57 +101.91 +102.04 +101.67 +102.53 +102.06 +102.36 +102.43 +101.75 +102.59 +101.81 +102.51 +102.60 +102.54 +102.72 +102.40 +102.10 +102.68 +102.02 +102.10 +102.36 +102.23 +102.34 +101.83 +102.00 +102.26 +102.89 +102.26 +102.44 +102.50 +102.21 +102.42 +102.74 +102.38 +101.93 +102.55 +102.58 +102.61 +102.20 +102.94 +102.53 +101.90 +102.65 +102.36 +102.99 +102.20 +102.66 +103.11 +102.81 +102.32 +102.02 +102.87 +102.57 +102.65 +102.89 +102.41 +102.08 +102.03 +102.99 +102.69 +102.25 +102.51 +102.96 +102.03 +102.09 +102.30 +102.10 +102.23 +102.53 +102.14 +102.64 +102.28 +102.85 +102.52 +102.49 +102.74 +102.40 +102.91 +103.21 +102.82 +103.27 +102.90 +103.22 +102.53 +103.05 +102.55 +102.17 +102.97 +102.84 +102.63 +102.48 +103.21 +103.14 +103.12 +103.10 +102.82 +103.38 +102.89 +102.38 +103.01 +102.83 +102.27 +103.11 +103.18 +102.60 +103.40 +103.43 +102.46 +103.40 +102.43 +102.41 +102.40 +103.13 +103.50 +102.45 +102.92 +102.35 +102.89 +103.01 +102.97 +103.53 +103.48 +102.47 +102.72 +102.60 +103.26 +102.85 +102.51 +102.61 +103.05 +103.34 +102.90 +102.94 +103.58 +103.56 +102.79 +102.91 +103.07 +102.69 +103.54 +103.67 +103.05 +103.25 +103.31 +103.14 +103.64 +103.38 +103.13 +102.99 +103.52 +103.71 +103.01 +102.81 +102.83 +103.29 +103.45 +103.08 +103.76 +103.09 +103.58 +103.00 +102.73 +103.20 +103.04 +103.50 +102.94 +103.13 +102.92 +102.95 +103.28 +103.31 +102.80 +103.32 +103.76 +103.79 +103.64 +103.66 +103.03 +103.42 +103.65 +103.55 +103.62 +102.76 +103.13 +103.85 +103.84 +103.60 +103.76 +103.21 +103.72 +102.82 +103.67 +103.91 +103.42 +103.87 +103.99 +103.64 +103.63 +103.71 +103.77 +103.26 +103.55 +103.08 +103.37 +102.97 +103.06 +103.00 +103.33 +103.79 +103.11 +103.61 +103.55 +103.36 +102.92 +103.39 +103.16 +103.29 +103.66 +103.89 +103.16 +103.69 +103.00 +103.12 +103.05 +103.23 +103.51 +104.06 +103.13 +103.71 +104.04 +104.05 +103.20 +103.28 +103.72 +104.01 +103.59 +104.00 +103.32 +103.48 +104.11 +103.65 +103.33 +103.97 +104.09 +103.86 +103.14 +103.32 +104.21 +103.30 +104.32 +104.14 +103.49 +103.41 +103.48 +103.16 +104.34 +103.59 +104.12 +103.98 +103.68 +103.34 +103.24 +104.24 +103.48 +104.28 +103.43 +103.63 +104.06 +103.38 +103.69 +103.56 +104.26 +103.45 +103.98 +104.36 +103.97 +104.49 +104.37 +103.35 +103.87 +103.83 +103.33 +104.37 +103.48 +104.15 +103.57 +104.01 +104.07 +104.34 +104.31 +104.06 +104.11 +103.68 +103.88 +104.56 +103.95 +104.43 +103.90 +103.60 +103.48 +104.29 +103.93 +104.29 +103.52 +103.75 +104.37 +103.63 +103.98 +103.67 +103.96 +103.74 +103.75 +103.87 +104.12 +104.26 +103.95 +103.93 +104.26 +104.31 +103.75 +103.81 +104.59 +103.58 +104.59 +104.50 +104.64 +104.72 +104.51 +104.25 +104.07 +104.05 +103.79 +103.67 +104.01 +104.82 +104.09 +103.97 +103.70 +103.95 +104.32 +104.56 +104.31 +104.17 +104.88 +104.37 +104.37 +103.79 +104.36 +104.58 +104.79 +104.68 +104.19 +103.94 +104.75 +104.82 +104.57 +104.34 +104.11 +104.45 +104.71 +104.65 +103.92 +104.20 +104.61 +104.60 +104.62 +104.69 +104.87 +104.89 +104.65 +104.03 +104.72 +104.29 +104.84 +104.28 +104.28 +103.99 +105.06 +104.14 +104.22 +104.59 +104.11 +104.88 +104.97 +104.47 +104.90 +104.21 +104.73 +104.47 +104.08 +104.62 +104.23 +104.90 +104.10 +104.82 +104.46 +104.51 +104.84 +104.13 +104.82 +104.98 +104.50 +105.02 +105.19 +105.24 +105.05 +105.26 +104.92 +104.26 +104.09 +104.22 +104.18 +104.71 +104.23 +104.60 +104.78 +104.95 +104.99 +105.03 +104.77 +105.11 +104.18 +104.51 +105.25 +104.67 +104.95 +105.09 +104.28 +105.40 +104.89 +104.65 +105.31 +104.83 +105.17 +104.64 +104.99 +104.64 +104.85 +104.93 +104.37 +105.28 +104.55 +104.94 +104.62 diff --git a/jac/jaclang/runtimelib/gins/ghost.py b/jac/jaclang/runtimelib/gins/ghost.py index ef51f6fcfb..8173129529 100644 --- a/jac/jaclang/runtimelib/gins/ghost.py +++ b/jac/jaclang/runtimelib/gins/ghost.py @@ -29,7 +29,7 @@ def __init__(self): self.deque_lock = threading.Lock() self.__cfg_deque_dict = dict() - self.__cfg_deque_size = 5 + self.__cfg_deque_size = 10 self.logger = logging.getLogger() if self.logger.hasHandlers(): @@ -259,7 +259,40 @@ def prompt_llm_with_history(self, verbose: bool = False): return response + def prompt_for_runtime(self, verbose: bool = False): + prompt = """I have a program. + Up to last {history_size} CFGs recorded: + {cfgs}, + Instructions per basic block: + {instructions} + Semantic and Type information from source code: + {sem_ir}""" + + cfg_string = "" + ins_string = "" + for module, cfg in self.cfgs.items(): + cfg_history = "None at this time" + if module in self.__cfg_deque_dict: + cfg_history = self.__cfg_deque_dict[module].get_cfg_repr() + cfg_string += f"Module: {module}\n{cfg_history}" + ins_string += f"Module: {module}\n{cfg.display_instructions()}" + prompt = prompt.format( + history_size=self.__cfg_deque_size, + cfgs=cfg_string, + instructions=ins_string, + sem_ir=self.sem_ir.pp() + ) + + if self.variable_values != None: + prompt += "\nCurrent variable values at the specified bytecode offset:" + + for module, var_map in self.variable_values.items(): + prompt += f"\nModule {module}: Offset: {var_map[0]}, Variables: {str(var_map[1])}" + + prompt+="\n given this information, what is the program behavior? Please express this in short bullets" + response = self.model.generate(prompt) + return response def worker(self): # get static cfgs self.cfg_cv.acquire() @@ -330,10 +363,10 @@ def update_cfg(): while not self.finished: self.finished_exception_lock.release() - time.sleep(1) + time.sleep(3) print("\nUpdating cfgs") update_cfg() - self.logger.info(self.prompt_llm()) + # self.logger.info(self.prompt_llm()) # print(f"history size: {len(self.__cfg_deque_dict['hot_path'])}") self.finished_exception_lock.acquire() # time.sleep(1) @@ -342,6 +375,7 @@ def update_cfg(): print("\nUpdating cfgs at the end") update_cfg() + print(self.prompt_for_runtime()) # print(self.__cfg_deque_dict['hot_path'].get_cfg_repr()) - self.logger.info(self.prompt_llm()) + # self.logger.info(self.prompt_llm()) From 590f4ac373ca13dfa0bafb0ffdfcf2dfa816e6c9 Mon Sep 17 00:00:00 2001 From: Jakob Louis Therkelsen Date: Thu, 5 Dec 2024 15:34:54 -0500 Subject: [PATCH 82/84] small updates --- jac/examples/gins_scripts/hot_path.jac | 2 +- .../gins_scripts/inputs/test_predict.txt | 1698 ++++++++--------- jac/examples/gins_scripts/test.txt | 11 + 3 files changed, 861 insertions(+), 850 deletions(-) diff --git a/jac/examples/gins_scripts/hot_path.jac b/jac/examples/gins_scripts/hot_path.jac index 88c7ee58f3..835a3ffe35 100644 --- a/jac/examples/gins_scripts/hot_path.jac +++ b/jac/examples/gins_scripts/hot_path.jac @@ -38,6 +38,6 @@ with entry { while test_val > 0 { reduce:float = random.uniform(5.0,10.0); test_val -= 100.0; - change_reduction_arr.append(test_val); + # change_reduction_arr.append(test_val); } } \ No newline at end of file diff --git a/jac/examples/gins_scripts/inputs/test_predict.txt b/jac/examples/gins_scripts/inputs/test_predict.txt index bb16927d4b..005d194095 100644 --- a/jac/examples/gins_scripts/inputs/test_predict.txt +++ b/jac/examples/gins_scripts/inputs/test_predict.txt @@ -1,1000 +1,1000 @@ -99.01 -99.23 -98.85 -99.05 +98.53 +98.54 +98.65 +98.40 +98.95 +98.58 +98.67 +98.59 98.55 -98.71 +99.28 99.10 -98.90 -98.44 -98.64 -98.97 -98.97 -99.15 -99.48 -99.52 -98.72 -99.06 -98.71 -98.84 -98.49 -99.18 -98.73 -98.81 +99.31 +98.67 +98.39 99.17 -99.02 -98.78 -99.37 -98.51 -99.16 -98.49 -98.62 -98.90 -99.26 -99.65 -98.86 -98.95 -98.52 -98.70 +99.24 98.83 -99.05 -99.67 -99.40 -99.05 -98.93 -99.16 98.77 -98.58 -98.67 -99.39 -99.77 -98.80 -99.74 -99.23 -99.30 -98.98 -99.80 -98.88 -98.88 -99.57 -99.83 +98.74 +99.32 +98.72 99.19 -99.86 +99.27 +99.63 +99.37 +98.92 +99.06 +99.18 +99.20 99.38 -98.76 +99.22 +99.22 +98.54 +99.06 +99.30 +98.92 98.87 -99.02 -99.44 -98.79 -99.45 -99.81 -98.97 -99.15 -99.14 -99.40 -99.88 -98.90 -98.95 -99.33 -99.82 +98.67 +99.49 +99.36 +99.43 +98.68 +99.37 +98.72 +99.11 98.88 -99.50 -99.40 -99.13 -99.84 -99.84 -99.75 -99.12 -99.53 -99.12 -98.97 +99.39 +99.30 +98.66 +99.78 +99.70 +98.98 +99.58 +98.66 +99.36 99.45 -99.93 -98.85 -99.18 -99.38 -99.98 -99.60 -99.52 +99.35 99.21 -99.29 -99.29 -100.02 -99.41 -99.09 -99.73 -99.71 -99.29 -99.17 -99.93 -99.03 +98.76 +99.28 +99.38 +98.96 +98.77 +99.13 +99.87 99.49 -99.31 99.39 -99.98 -99.55 -99.67 -99.70 -99.17 -99.84 -99.90 -100.04 -99.81 -99.16 -100.09 -100.11 -99.33 +99.89 +99.32 +99.10 +98.78 +99.28 +99.03 +99.40 +99.74 +99.44 +99.72 +99.78 99.56 -99.27 -100.02 -99.14 -99.92 +99.12 +99.82 +98.96 +99.73 +99.04 +99.08 +99.43 +99.95 +99.06 +99.31 +99.53 +99.83 +99.85 +100.00 +99.03 +98.96 99.33 -99.51 -99.11 -99.34 +99.23 +99.76 99.55 -99.86 +99.08 +99.97 +98.93 +99.68 99.41 +99.97 +99.99 +99.54 +99.62 +99.78 +99.61 +99.73 +99.35 +99.57 +99.77 +99.16 +99.45 +99.79 99.93 -99.89 -100.02 -100.19 +99.84 +100.07 99.18 -99.68 -100.18 -99.57 -99.28 +99.83 +99.66 99.30 +99.76 +100.14 100.22 +100.26 +100.15 +99.96 +99.86 +99.27 +99.89 +100.11 +99.55 +100.29 +99.21 +99.52 +100.12 +99.48 +99.24 +99.75 +99.93 +99.40 +99.65 +99.23 +99.23 +99.56 +99.23 100.10 -100.13 +99.99 +100.07 +100.34 +100.34 +99.44 +99.25 +99.80 +100.03 +99.46 100.10 -99.57 -99.79 -99.67 +100.29 +99.69 +100.01 +99.40 +99.59 100.09 -100.10 -100.14 -100.05 -100.03 -100.39 -100.20 +99.94 +99.46 +100.41 +99.96 +99.73 +100.02 +99.84 +100.35 +99.35 +99.74 +99.74 +99.55 +99.54 +99.86 +100.15 100.46 100.43 -100.18 +100.22 +99.54 +100.38 +99.88 +99.91 +99.76 +100.11 +99.63 +100.44 +99.84 +99.83 +100.04 +100.29 100.16 -99.96 -99.42 -99.68 -99.62 -99.41 -100.08 -100.18 -100.24 -99.61 -100.28 -100.35 -99.40 -100.55 +100.17 +99.93 100.10 -99.73 -99.56 -100.41 +99.71 +99.74 +100.14 +100.52 +100.34 +100.15 +100.45 +100.51 +99.95 +100.04 +100.33 +100.03 +99.75 +99.91 +100.38 +100.15 +99.99 +100.76 +100.02 +100.45 100.28 -100.27 -100.60 -99.73 -100.11 -99.57 +99.82 +100.23 +100.35 +99.74 +99.69 +100.34 +99.95 +100.81 99.73 -100.58 99.91 -99.86 -100.27 +100.29 +100.44 +100.85 +100.20 +99.97 +100.46 +99.98 +100.08 +100.23 +100.11 +100.54 +99.78 +100.15 +100.02 +99.89 +100.22 +100.32 +99.82 +100.13 +100.35 +100.50 +99.98 +100.51 +100.09 100.42 -99.59 -99.64 -100.17 -100.30 -99.90 +100.09 +100.36 +100.43 +99.94 100.25 -100.47 -100.41 -100.56 -99.82 -99.88 -99.79 +100.30 +101.06 +100.23 +100.95 +100.73 +100.82 +100.02 +100.10 +100.49 +100.62 +100.90 +101.12 +100.09 +100.21 +100.81 +101.02 +100.76 +100.28 +101.15 +100.90 +100.01 +100.77 +100.75 +101.00 100.15 +100.86 +100.79 +101.14 +100.74 +100.37 100.10 -99.70 -99.76 -100.72 -100.54 -99.77 +100.69 +100.16 +100.75 +101.25 +100.59 100.40 -99.71 -100.25 -99.74 -100.77 +100.62 +101.12 +101.28 +100.30 +100.39 +101.30 +101.29 100.48 -100.80 -100.20 +100.15 +100.46 +101.21 +101.16 100.17 -99.77 -100.36 +100.59 +100.67 100.48 -100.54 -100.37 -100.63 -100.85 -100.84 +101.36 +101.23 100.50 -100.23 -100.60 -100.01 -100.83 -100.31 -100.91 -99.83 -100.41 +100.98 +100.50 +100.78 +101.00 +101.03 +100.73 100.43 -100.46 -100.94 +100.33 100.29 -100.75 -100.85 -100.90 -100.81 -100.38 -100.36 -100.81 -101.00 -100.69 -100.00 -100.11 -99.93 -100.90 +100.91 100.80 -101.00 -99.92 -100.28 -100.85 -100.19 -100.21 -100.03 -100.12 -100.50 -100.52 -100.90 -100.50 -100.06 -100.87 -101.02 -100.22 -100.63 -100.47 -100.60 -100.72 -100.33 -100.71 -100.51 -100.42 -101.01 -100.31 -101.02 -100.62 -100.20 +100.86 +101.34 100.91 -101.04 -100.53 -101.10 -101.23 -100.60 -100.37 -100.65 -101.00 -100.22 -101.10 -101.19 +101.07 +100.49 100.82 -100.89 -100.12 -100.75 -101.06 -101.23 -101.21 -100.15 -100.78 -101.29 -100.17 -100.71 -100.62 -101.03 -100.40 -101.12 -100.48 -101.31 -101.24 -100.61 -100.65 +100.69 +100.33 +100.46 101.40 +101.30 100.35 -101.33 -100.74 -101.32 -100.61 -101.35 +100.83 100.46 -101.10 -100.64 -101.30 -100.79 -101.32 -100.69 -100.49 -101.04 -101.48 -100.84 -100.94 -100.73 -100.97 -100.67 -101.08 -100.93 -100.74 -101.54 -100.49 +101.55 101.38 -101.00 -101.10 -101.04 -100.47 +101.01 +100.62 101.13 -101.45 -100.78 -101.61 -101.59 -100.79 -101.27 101.34 -101.12 -100.67 -100.68 -101.45 -101.41 -101.39 -100.88 -101.19 -101.07 -101.49 -101.38 -101.17 -101.13 +101.37 +100.50 +100.49 +100.98 +100.50 100.69 +101.15 +101.21 +100.48 +100.53 +101.07 +101.31 +101.63 +100.57 +101.58 +101.40 +101.65 +101.16 +100.56 +101.08 +101.06 +101.40 100.89 -101.23 -101.28 -101.22 -101.12 -100.78 +100.86 +100.74 +100.75 101.57 -101.50 -101.50 -101.06 +100.99 +101.38 +100.93 +100.77 +101.66 +100.62 +101.40 101.63 -100.63 -100.78 -101.61 -101.71 -101.12 -101.21 -101.22 -100.73 -100.85 +101.26 +101.06 101.40 +100.80 +100.92 +100.86 +100.67 +101.41 +101.10 +101.82 +101.46 +101.64 +100.95 +101.79 +101.73 +101.62 +101.43 +101.87 101.75 -101.69 -101.30 +101.84 +101.57 +101.63 +101.04 +101.80 +101.78 +101.84 +101.51 +101.39 +101.76 +101.55 +101.91 +101.15 +101.29 101.15 -100.86 101.60 -101.56 -101.89 -101.30 -101.21 -101.08 -101.70 -100.85 -101.56 -100.85 -101.71 -101.35 -101.07 -101.33 101.81 -101.52 -100.83 -101.01 -102.00 -101.79 -101.60 -101.95 -101.70 -101.97 -101.92 +101.11 +101.78 +101.83 102.02 -101.00 -101.16 -101.82 -101.28 -100.96 -101.09 -101.64 -101.72 -101.06 -101.31 -101.50 -101.69 +102.03 +101.57 +101.19 +101.96 +101.55 101.31 -101.29 -101.78 -101.89 -101.10 +100.94 +100.96 +100.98 101.78 -101.81 -101.27 -101.67 -101.61 -102.11 -102.15 -101.04 -101.85 -101.94 -101.92 -101.72 -101.79 -101.53 -101.13 -101.08 -101.35 -101.17 -101.29 -102.24 -101.77 -101.92 -101.79 -102.15 -101.92 -101.26 -101.17 -102.07 +101.06 +101.00 101.77 -102.25 -101.99 +101.66 +101.82 +101.68 +101.64 +101.00 101.73 -101.25 -102.21 -102.34 -101.49 +101.19 +101.27 101.91 -101.83 -101.56 +101.05 +101.86 +101.71 +101.91 +102.03 +101.55 +101.18 +101.10 +101.20 +101.84 +101.53 +101.34 +101.69 +101.28 +101.90 +101.63 +101.93 +102.16 101.46 +101.21 +102.06 +101.53 +102.23 +101.14 +101.91 +102.17 +101.88 +101.76 +101.59 +102.03 +102.09 102.30 -101.23 -102.02 -101.49 +101.93 +102.14 102.35 -102.38 -101.57 -101.98 -101.66 -101.62 -101.84 -101.42 -101.87 -101.43 -101.53 -101.29 +101.89 +101.82 +102.15 +102.03 +102.21 +102.12 +101.61 +101.61 +102.37 101.53 -101.67 -101.74 -101.48 +101.27 +102.31 +102.04 +101.33 +101.69 +101.51 +101.37 101.44 -101.57 +101.52 +102.19 +101.68 +101.67 +101.93 +102.48 101.75 -101.50 +101.99 +101.80 +102.42 +101.73 101.37 -102.20 -102.14 -101.77 -102.51 -101.82 -102.05 -102.27 101.63 -102.22 -101.94 -102.09 -102.42 -102.10 -102.36 -101.60 -101.76 -102.47 -102.01 -102.05 -101.93 102.43 -101.86 -101.58 -101.71 -101.52 +101.98 +102.06 102.29 -101.67 -102.00 -101.81 -101.78 -101.70 -102.51 -102.45 -101.70 +101.68 +102.30 102.50 -101.94 -102.28 -101.96 -102.07 -102.09 -102.77 -101.66 -102.40 -102.71 -102.26 -102.26 -102.00 -102.47 -102.57 -101.91 -102.04 -101.67 -102.53 -102.06 -102.36 -102.43 -101.75 -102.59 -101.81 -102.51 -102.60 +101.50 +101.61 +102.20 102.54 -102.72 -102.40 -102.10 -102.68 -102.02 -102.10 -102.36 -102.23 -102.34 -101.83 -102.00 -102.26 -102.89 +101.71 102.26 -102.44 -102.50 -102.21 -102.42 -102.74 -102.38 +101.94 +101.60 101.93 -102.55 +102.00 +102.21 +101.65 +101.63 +101.63 +102.06 +101.71 +101.96 +101.82 +102.57 +102.65 102.58 -102.61 +101.82 +102.18 +102.73 102.20 -102.94 -102.53 +102.37 +101.66 +102.52 +101.84 +102.02 +101.93 +101.95 +102.56 +101.97 +101.86 +102.24 +101.96 +102.56 +102.60 +101.96 +101.77 +102.29 +102.06 +102.69 +101.98 +101.82 101.90 +102.53 +102.22 +102.61 +102.73 +101.76 +102.90 +101.98 102.65 -102.36 -102.99 -102.20 -102.66 -103.11 -102.81 -102.32 102.02 -102.87 -102.57 +101.97 +102.17 +102.01 +101.88 +101.91 +102.87 +102.87 +101.97 +102.24 +101.81 +102.48 +102.65 +102.82 +102.15 +101.89 +102.30 +102.19 +102.11 +102.09 +102.05 +102.02 +101.90 +102.80 +102.26 +102.45 +102.39 +102.59 +101.95 +101.93 +102.96 +102.40 +102.30 +102.63 +102.22 +102.27 +103.12 +102.89 +102.53 +102.60 +102.48 +102.31 +102.38 +102.98 +102.24 102.65 102.89 -102.41 -102.08 -102.03 -102.99 -102.69 -102.25 -102.51 102.96 -102.03 -102.09 -102.30 -102.10 -102.23 +102.57 102.53 -102.14 -102.64 +103.16 +102.54 +102.17 +102.48 102.28 102.85 -102.52 -102.49 -102.74 -102.40 -102.91 -103.21 -102.82 -103.27 -102.90 -103.22 -102.53 -103.05 +102.87 102.55 -102.17 -102.97 +103.28 +103.16 +102.15 102.84 -102.63 +102.15 +102.28 +102.21 +102.71 +102.82 +102.72 +102.36 +103.15 +103.16 +102.64 +103.13 102.48 -103.21 -103.14 -103.12 -103.10 +102.61 +103.06 +103.15 +103.07 +102.61 +103.15 102.82 -103.38 -102.89 +102.96 +103.42 102.38 -103.01 -102.83 -102.27 -103.11 -103.18 -102.60 -103.40 -103.43 -102.46 -103.40 -102.43 -102.41 -102.40 -103.13 -103.50 -102.45 -102.92 -102.35 -102.89 -103.01 -102.97 -103.53 -103.48 -102.47 -102.72 -102.60 +103.33 +103.20 103.26 +102.75 +102.74 +102.97 +103.25 +103.22 +102.66 +102.99 +103.32 +102.89 102.85 -102.51 -102.61 -103.05 -103.34 +103.38 +102.55 +103.21 +102.73 +102.93 +102.53 +102.71 +103.31 102.90 -102.94 -103.58 -103.56 -102.79 -102.91 -103.07 +103.03 102.69 -103.54 -103.67 -103.05 -103.25 -103.31 -103.14 +103.02 +102.60 +103.50 +102.68 +102.73 +103.59 +102.62 +102.60 +103.12 +102.58 +102.84 +102.51 103.64 -103.38 -103.13 -102.99 -103.52 +103.03 +103.46 +102.67 +103.48 +103.59 +102.92 +102.95 +103.21 +103.41 +102.88 +103.63 +103.66 +102.62 +103.06 +103.65 103.71 +102.64 +103.19 +102.88 103.01 +102.94 +103.27 +103.19 +102.68 +103.49 +102.75 +103.61 +103.42 +103.18 +103.03 +102.73 +102.67 +102.73 +103.55 +102.68 +103.56 +102.85 +103.43 +103.10 +103.38 +102.79 102.81 -102.83 -103.29 -103.45 -103.08 103.76 -103.09 -103.58 -103.00 -102.73 -103.20 -103.04 -103.50 -102.94 -103.13 -102.92 -102.95 -103.28 -103.31 -102.80 +103.84 103.32 +103.00 +103.74 +103.17 +103.47 +103.55 103.76 -103.79 -103.64 -103.66 +103.24 +103.85 +102.95 +103.74 +103.08 103.03 +103.16 +103.96 +103.87 +102.96 +103.48 +103.24 103.42 -103.65 -103.55 -103.62 -102.76 -103.13 -103.85 -103.84 -103.60 -103.76 -103.21 -103.72 -102.82 +103.05 +102.96 +103.58 +103.27 +103.47 +103.30 +102.92 +102.94 103.67 +103.32 +103.46 +102.95 +103.70 +103.44 103.91 -103.42 -103.87 -103.99 -103.64 -103.63 +103.18 +103.81 +103.56 +104.10 +103.22 +103.47 103.71 +104.15 +104.03 +103.18 +103.80 +103.97 +103.12 +103.79 +103.87 +103.87 +103.79 103.77 -103.26 -103.55 -103.08 -103.37 -102.97 -103.06 -103.00 +104.18 +103.78 +103.10 +103.70 +103.72 +104.03 +103.72 +103.10 +103.71 +103.81 +103.28 103.33 -103.79 -103.11 -103.61 -103.55 -103.36 -102.92 -103.39 -103.16 -103.29 -103.66 -103.89 -103.16 -103.69 -103.00 -103.12 -103.05 -103.23 -103.51 104.06 -103.13 -103.71 +103.47 +104.02 +103.83 +103.28 104.04 +103.83 +103.70 +103.24 +103.93 +103.22 104.05 -103.20 -103.28 -103.72 -104.01 -103.59 +103.50 104.00 -103.32 -103.48 -104.11 -103.65 -103.33 -103.97 -104.09 -103.86 -103.14 -103.32 -104.21 -103.30 -104.32 -104.14 -103.49 -103.41 -103.48 -103.16 -104.34 -103.59 -104.12 103.98 -103.68 -103.34 -103.24 -104.24 +103.81 103.48 -104.28 -103.43 -103.63 -104.06 -103.38 -103.69 -103.56 -104.26 -103.45 -103.98 -104.36 -103.97 -104.49 -104.37 +104.21 +104.01 +104.17 +103.80 +104.27 +103.77 103.35 -103.87 -103.83 -103.33 -104.37 +103.64 +103.81 +104.20 +103.92 +103.79 +103.58 +103.77 +103.92 +104.51 +103.47 +104.17 +104.47 +104.11 +104.47 103.48 -104.15 +104.52 +104.00 +103.40 103.57 -104.01 -104.07 -104.34 -104.31 -104.06 -104.11 +104.30 103.68 -103.88 -104.56 -103.95 -104.43 -103.90 -103.60 -103.48 -104.29 -103.93 -104.29 -103.52 -103.75 -104.37 -103.63 -103.98 -103.67 +104.51 +104.55 +104.24 103.96 -103.74 +103.56 +103.99 +103.45 103.75 +104.62 +104.24 +103.72 +103.92 103.87 -104.12 -104.26 -103.95 -103.93 -104.26 -104.31 -103.75 -103.81 -104.59 -103.58 +103.78 +103.71 104.59 -104.50 -104.64 -104.72 -104.51 -104.25 -104.07 +103.68 +103.84 +104.17 +103.95 104.05 -103.79 -103.67 -104.01 -104.82 +104.25 104.09 -103.97 -103.70 -103.95 -104.32 -104.56 -104.31 -104.17 -104.88 -104.37 -104.37 -103.79 -104.36 -104.58 -104.79 -104.68 +104.50 104.19 -103.94 +104.14 +104.16 +104.54 +104.33 104.75 -104.82 -104.57 -104.34 -104.11 +103.97 +103.67 +103.61 +104.66 +104.52 104.45 +104.21 104.71 +104.40 +103.84 +103.91 +104.29 +104.31 +104.52 +103.96 +104.17 +103.76 +103.98 +104.29 +104.40 104.65 +103.99 +104.37 +103.82 +104.02 +103.80 +104.88 +103.80 +103.95 +104.12 +104.60 +104.13 +104.06 103.92 +104.34 +104.59 +104.74 +104.30 +104.79 +104.38 +104.89 +104.30 +104.49 104.20 +103.85 +104.69 +104.25 +103.98 +104.58 +104.06 104.61 -104.60 +104.08 +104.42 +104.67 +105.06 104.62 +104.05 +105.09 +103.94 +104.04 +104.18 +104.11 +104.64 +105.04 +104.70 +104.95 +104.06 +104.74 +104.61 104.69 -104.87 -104.89 -104.65 -104.03 -104.72 -104.29 -104.84 -104.28 -104.28 -103.99 -105.06 -104.14 +104.57 +104.01 104.22 -104.59 +105.12 +104.46 +104.24 104.11 -104.88 +104.57 +105.02 +104.38 +104.70 +104.76 +104.40 +104.37 104.97 -104.47 -104.90 -104.21 -104.73 -104.47 -104.08 -104.62 -104.23 -104.90 -104.10 -104.82 -104.46 -104.51 -104.84 -104.13 -104.82 -104.98 -104.50 +104.20 +104.24 +104.41 105.02 -105.19 -105.24 -105.05 -105.26 -104.92 -104.26 -104.09 -104.22 -104.18 -104.71 -104.23 +104.79 +104.68 104.60 -104.78 -104.95 -104.99 +104.18 +104.91 +104.38 +105.01 +105.08 105.03 +104.91 +104.76 +104.35 +104.39 104.77 -105.11 -104.18 -104.51 -105.25 -104.67 -104.95 105.09 -104.28 -105.40 -104.89 -104.65 -105.31 +104.95 +104.76 +105.34 +105.30 +104.79 +105.26 104.83 -105.17 -104.64 -104.99 -104.64 -104.85 -104.93 104.37 -105.28 -104.55 -104.94 +104.69 +104.87 +104.36 +104.57 +104.82 +105.00 104.62 +105.47 +105.26 +104.73 diff --git a/jac/examples/gins_scripts/test.txt b/jac/examples/gins_scripts/test.txt index 98e903505b..deae538298 100644 --- a/jac/examples/gins_scripts/test.txt +++ b/jac/examples/gins_scripts/test.txt @@ -141,3 +141,14 @@ The exact frequencies for bb7, bb8, bb9, bb10, bb12 and bb13 depend on how many 2024-12-04 19:50:03 - {"cfg_bbs": [{"actual_edges": [{"edge_to_bb_id": 2, "freq": 1}, {"edge_to_bb_id": 1, "freq": 0}], "actual_freq": 1, "bb_id": 0, "predicted_edges": [{"edge_to_bb_id": 2, "freq": 87}, {"edge_to_bb_id": 1, "freq": 23}], "predicted_freq": 110}, {"actual_edges": [{"edge_to_bb_id": 3, "freq": 0}], "actual_freq": 0, "bb_id": 1, "predicted_edges": [{"edge_to_bb_id": 3, "freq": 54}], "predicted_freq": 54}, {"actual_edges": [{"edge_to_bb_id": 3, "freq": 1}], "actual_freq": 1, "bb_id": 2, "predicted_edges": [{"edge_to_bb_id": 3, "freq": 12}], "predicted_freq": 12}, {"actual_edges": [{"edge_to_bb_id": 4, "freq": 1}], "actual_freq": 1, "bb_id": 3, "predicted_edges": [{"edge_to_bb_id": 4, "freq": 95}], "predicted_freq": 95}, {"actual_edges": [{"edge_to_bb_id": 5, "freq": 1}, {"edge_to_bb_id": 4, "freq": 0}], "actual_freq": 1, "bb_id": 4, "predicted_edges": [{"edge_to_bb_id": 5, "freq": 63}, {"edge_to_bb_id": 4, "freq": 17}], "predicted_freq": 80}, {"actual_edges": [{"edge_to_bb_id": 6, "freq": 1}], "actual_freq": 1, "bb_id": 5, "predicted_edges": [{"edge_to_bb_id": 6, "freq": 55}], "predicted_freq": 55}, {"actual_edges": [{"edge_to_bb_id": 15, "freq": 0}, {"edge_to_bb_id": 7, "freq": 1}], "actual_freq": 1, "bb_id": 6, "predicted_edges": [{"edge_to_bb_id": 15, "freq": 56}, {"edge_to_bb_id": 7, "freq": 22}], "predicted_freq": 78}, {"actual_edges": [{"edge_to_bb_id": 9, "freq": 5626}, {"edge_to_bb_id": 8, "freq": 5626}], "actual_freq": 11253, "bb_id": 7, "predicted_edges": [{"edge_to_bb_id": 9, "freq": 12}, {"edge_to_bb_id": 8, "freq": 45}], "predicted_freq": 57}, {"actual_edges": [{"edge_to_bb_id": 10, "freq": 5626}], "actual_freq": 5626, "bb_id": 8, "predicted_edges": [{"edge_to_bb_id": 10, "freq": 87}], "predicted_freq": 87}, {"actual_edges": [{"edge_to_bb_id": 10, "freq": 5626}], "actual_freq": 5626, "bb_id": 9, "predicted_edges": [{"edge_to_bb_id": 10, "freq": 23}], "predicted_freq": 23}, {"actual_edges": [{"edge_to_bb_id": 12, "freq": 11252}, {"edge_to_bb_id": 11, "freq": 0}], "actual_freq": 11252, "bb_id": 10, "predicted_edges": [{"edge_to_bb_id": 12, "freq": 94}, {"edge_to_bb_id": 11, "freq": 65}], "predicted_freq": 159}, {"actual_edges": [{"edge_to_bb_id": 12, "freq": 0}], "actual_freq": 0, "bb_id": 11, "predicted_edges": [{"edge_to_bb_id": 12, "freq": 34}], "predicted_freq": 34}, {"actual_edges": [{"edge_to_bb_id": 14, "freq": 0}, {"edge_to_bb_id": 13, "freq": 11252}], "actual_freq": 11252, "bb_id": 12, "predicted_edges": [{"edge_to_bb_id": 14, "freq": 12}, {"edge_to_bb_id": 13, "freq": 86}], "predicted_freq": 98}, {"actual_edges": [{"edge_to_bb_id": 7, "freq": 11252}], "actual_freq": 11252, "bb_id": 13, "predicted_edges": [{"edge_to_bb_id": 7, "freq": 76}], "predicted_freq": 76}, {"actual_edges": [{"edge_to_bb_id": 15, "freq": 0}], "actual_freq": 0, "bb_id": 14, "predicted_edges": [{"edge_to_bb_id": 15, "freq": 11}], "predicted_freq": 11}, {"actual_edges": [{"edge_to_bb_id": 17, "freq": 0}, {"edge_to_bb_id": 16, "freq": 0}], "actual_freq": 0, "bb_id": 15, "predicted_edges": [{"edge_to_bb_id": 17, "freq": 34}, {"edge_to_bb_id": 16, "freq": 54}], "predicted_freq": 88}, {"actual_edges": [{"edge_to_bb_id": 17, "freq": 0}], "actual_freq": 0, "bb_id": 16, "predicted_edges": [{"edge_to_bb_id": 17, "freq": 23}], "predicted_freq": 23}, {"actual_edges": [{"edge_to_bb_id": 6, "freq": 0}], "actual_freq": 0, "bb_id": 17, "predicted_edges": [{"edge_to_bb_id": 6, "freq": 65}], "predicted_freq": 65}, {"actual_edges": [], "actual_freq": 0, "bb_id": 18, "predicted_edges": [], "predicted_freq": 0}]} 2024-12-04 19:50:04 - {'cfg_bbs': [{'bb_id': 0, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 2, 'freq': 0}, {'edge_to_bb_id': 1, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 2, 'freq': 1}, {'edge_to_bb_id': 1, 'freq': 0}]}, {'bb_id': 1, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 0}]}, {'bb_id': 2, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 1}]}, {'bb_id': 3, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 4, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 4, 'freq': 1}]}, {'bb_id': 4, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 5, 'freq': 0}, {'edge_to_bb_id': 4, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 5, 'freq': 1}, {'edge_to_bb_id': 4, 'freq': 0}]}, {'bb_id': 5, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 1}]}, {'bb_id': 6, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 7, 'freq': 1}]}, {'bb_id': 7, 'freq': 30000, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}, {'edge_to_bb_id': 8, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 15000}, {'edge_to_bb_id': 8, 'freq': 15000}]}, {'bb_id': 8, 'freq': 15000, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 15000}]}, {'bb_id': 9, 'freq': 15000, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 15000}]}, {'bb_id': 10, 'freq': 30000, 'predicted_edges': [{'edge_to_bb_id': 12, 'freq': 0}, {'edge_to_bb_id': 11, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 12, 'freq': 30000}, {'edge_to_bb_id': 11, 'freq': 0}]}, {'bb_id': 11, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 12, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 12, 'freq': 0}]}, {'bb_id': 12, 'freq': 30000, 'predicted_edges': [{'edge_to_bb_id': 14, 'freq': 0}, {'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 14, 'freq': 1}, {'edge_to_bb_id': 13, 'freq': 29999}]}, {'bb_id': 13, 'freq': 29999, 'predicted_edges': [{'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 7, 'freq': 29999}]}, {'bb_id': 14, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 15, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 15, 'freq': 0}]}, {'bb_id': 15, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 17, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 17, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}]}, {'bb_id': 16, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 17, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 17, 'freq': 0}]}, {'bb_id': 17, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 0}]}, {'bb_id': 18, 'freq': 0, 'predicted_edges': [], 'actual_edges': []}]} 2024-12-04 19:50:19 - {"cfg_bbs": [{"actual_edges": [{"edge_to_bb_id": 2, "freq": 1}, {"edge_to_bb_id": 1, "freq": 0}], "actual_freq": 1, "bb_id": 0, "predicted_edges": [{"edge_to_bb_id": 2, "freq": 87}, {"edge_to_bb_id": 1, "freq": 23}], "predicted_freq": 110}, {"actual_edges": [{"edge_to_bb_id": 3, "freq": 0}], "actual_freq": 0, "bb_id": 1, "predicted_edges": [{"edge_to_bb_id": 3, "freq": 54}], "predicted_freq": 54}, {"actual_edges": [{"edge_to_bb_id": 3, "freq": 1}], "actual_freq": 1, "bb_id": 2, "predicted_edges": [{"edge_to_bb_id": 3, "freq": 12}], "predicted_freq": 12}, {"actual_edges": [{"edge_to_bb_id": 4, "freq": 1}], "actual_freq": 1, "bb_id": 3, "predicted_edges": [{"edge_to_bb_id": 4, "freq": 91}], "predicted_freq": 91}, {"actual_edges": [{"edge_to_bb_id": 5, "freq": 1}, {"edge_to_bb_id": 4, "freq": 0}], "actual_freq": 1, "bb_id": 4, "predicted_edges": [{"edge_to_bb_id": 5, "freq": 34}, {"edge_to_bb_id": 4, "freq": 17}], "predicted_freq": 51}, {"actual_edges": [{"edge_to_bb_id": 6, "freq": 1}], "actual_freq": 1, "bb_id": 5, "predicted_edges": [{"edge_to_bb_id": 6, "freq": 65}], "predicted_freq": 65}, {"actual_edges": [{"edge_to_bb_id": 15, "freq": 0}, {"edge_to_bb_id": 7, "freq": 1}], "actual_freq": 1, "bb_id": 6, "predicted_edges": [{"edge_to_bb_id": 15, "freq": 21}, {"edge_to_bb_id": 7, "freq": 76}], "predicted_freq": 97}, {"actual_edges": [{"edge_to_bb_id": 9, "freq": 15000}, {"edge_to_bb_id": 8, "freq": 15000}], "actual_freq": 30000, "bb_id": 7, "predicted_edges": [{"edge_to_bb_id": 9, "freq": 11235}, {"edge_to_bb_id": 8, "freq": 18765}], "predicted_freq": 30000}, {"actual_edges": [{"edge_to_bb_id": 10, "freq": 15000}], "actual_freq": 15000, "bb_id": 8, "predicted_edges": [{"edge_to_bb_id": 10, "freq": 12000}], "predicted_freq": 12000}, {"actual_edges": [{"edge_to_bb_id": 10, "freq": 15000}], "actual_freq": 15000, "bb_id": 9, "predicted_edges": [{"edge_to_bb_id": 10, "freq": 13000}], "predicted_freq": 13000}, {"actual_edges": [{"edge_to_bb_id": 12, "freq": 30000}, {"edge_to_bb_id": 11, "freq": 0}], "actual_freq": 30000, "bb_id": 10, "predicted_edges": [{"edge_to_bb_id": 12, "freq": 28000}, {"edge_to_bb_id": 11, "freq": 2000}], "predicted_freq": 30000}, {"actual_edges": [{"edge_to_bb_id": 12, "freq": 0}], "actual_freq": 0, "bb_id": 11, "predicted_edges": [{"edge_to_bb_id": 12, "freq": 1500}], "predicted_freq": 1500}, {"actual_edges": [{"edge_to_bb_id": 14, "freq": 1}, {"edge_to_bb_id": 13, "freq": 29999}], "actual_freq": 30000, "bb_id": 12, "predicted_edges": [{"edge_to_bb_id": 14, "freq": 1234}, {"edge_to_bb_id": 13, "freq": 28766}], "predicted_freq": 30000}, {"actual_edges": [{"edge_to_bb_id": 7, "freq": 29999}], "actual_freq": 29999, "bb_id": 13, "predicted_edges": [{"edge_to_bb_id": 7, "freq": 27000}], "predicted_freq": 27000}, {"actual_edges": [{"edge_to_bb_id": 15, "freq": 0}], "actual_freq": 1, "bb_id": 14, "predicted_edges": [{"edge_to_bb_id": 15, "freq": 500}], "predicted_freq": 500}, {"actual_edges": [{"edge_to_bb_id": 17, "freq": 0}, {"edge_to_bb_id": 16, "freq": 0}], "actual_freq": 0, "bb_id": 15, "predicted_edges": [{"edge_to_bb_id": 17, "freq": 100}, {"edge_to_bb_id": 16, "freq": 200}], "predicted_freq": 300}, {"actual_edges": [{"edge_to_bb_id": 17, "freq": 0}], "actual_freq": 0, "bb_id": 16, "predicted_edges": [{"edge_to_bb_id": 17, "freq": 300}], "predicted_freq": 300}, {"actual_edges": [{"edge_to_bb_id": 6, "freq": 0}], "actual_freq": 0, "bb_id": 17, "predicted_edges": [{"edge_to_bb_id": 6, "freq": 400}], "predicted_freq": 400}, {"actual_edges": [], "actual_freq": 0, "bb_id": 18, "predicted_edges": [], "predicted_freq": 0}]} +2024-12-05 15:27:39 - {'cfg_bbs': [{'bb_id': 0, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 2, 'freq': 0}, {'edge_to_bb_id': 1, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 2, 'freq': 1}, {'edge_to_bb_id': 1, 'freq': 0}]}, {'bb_id': 1, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 0}]}, {'bb_id': 2, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 1}]}, {'bb_id': 3, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 5, 'freq': 0}, {'edge_to_bb_id': 4, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 5, 'freq': 1}, {'edge_to_bb_id': 4, 'freq': 0}]}, {'bb_id': 4, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 0}]}, {'bb_id': 5, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 1}]}, {'bb_id': 6, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 7, 'freq': 1}]}, {'bb_id': 7, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 8, 'freq': 0}, {'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 8, 'freq': 1}, {'edge_to_bb_id': 7, 'freq': 0}]}, {'bb_id': 8, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 1}]}, {'bb_id': 9, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 1}]}, {'bb_id': 10, 'freq': 549, 'predicted_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 12, 'freq': 0}, {'edge_to_bb_id': 11, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 12, 'freq': 179}, {'edge_to_bb_id': 11, 'freq': 370}]}, {'bb_id': 11, 'freq': 370, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 370}]}, {'bb_id': 12, 'freq': 179, 'predicted_edges': [{'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 13, 'freq': 179}]}, {'bb_id': 13, 'freq': 179, 'predicted_edges': [{'edge_to_bb_id': 14, 'freq': 0}, {'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 14, 'freq': 178}, {'edge_to_bb_id': 13, 'freq': 0}]}, {'bb_id': 14, 'freq': 178, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 178}]}, {'bb_id': 15, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 19, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 19, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}]}, {'bb_id': 16, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 18, 'freq': 0}, {'edge_to_bb_id': 17, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 18, 'freq': 0}, {'edge_to_bb_id': 17, 'freq': 0}]}, {'bb_id': 17, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 16, 'freq': 0}]}, {'bb_id': 18, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 19, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 19, 'freq': 0}]}, {'bb_id': 19, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 21, 'freq': 0}, {'edge_to_bb_id': 20, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 21, 'freq': 0}, {'edge_to_bb_id': 20, 'freq': 0}]}, {'bb_id': 20, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 21, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 21, 'freq': 0}]}, {'bb_id': 21, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 0}]}, {'bb_id': 22, 'freq': 0, 'predicted_edges': [], 'actual_edges': []}]} +2024-12-05 15:27:46 - {'cfg_bbs': [{'bb_id': 0, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 2, 'freq': 0}, {'edge_to_bb_id': 1, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 2, 'freq': 1}, {'edge_to_bb_id': 1, 'freq': 0}]}, {'bb_id': 1, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 0}]}, {'bb_id': 2, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 1}]}, {'bb_id': 3, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 5, 'freq': 0}, {'edge_to_bb_id': 4, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 5, 'freq': 1}, {'edge_to_bb_id': 4, 'freq': 0}]}, {'bb_id': 4, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 0}]}, {'bb_id': 5, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 1}]}, {'bb_id': 6, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 7, 'freq': 1}]}, {'bb_id': 7, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 8, 'freq': 0}, {'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 8, 'freq': 1}, {'edge_to_bb_id': 7, 'freq': 0}]}, {'bb_id': 8, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 1}]}, {'bb_id': 9, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 1}]}, {'bb_id': 10, 'freq': 738, 'predicted_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 12, 'freq': 0}, {'edge_to_bb_id': 11, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 12, 'freq': 368}, {'edge_to_bb_id': 11, 'freq': 370}]}, {'bb_id': 11, 'freq': 370, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 370}]}, {'bb_id': 12, 'freq': 368, 'predicted_edges': [{'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 13, 'freq': 368}]}, {'bb_id': 13, 'freq': 368, 'predicted_edges': [{'edge_to_bb_id': 14, 'freq': 0}, {'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 14, 'freq': 367}, {'edge_to_bb_id': 13, 'freq': 0}]}, {'bb_id': 14, 'freq': 367, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 367}]}, {'bb_id': 15, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 19, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 19, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}]}, {'bb_id': 16, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 18, 'freq': 0}, {'edge_to_bb_id': 17, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 18, 'freq': 0}, {'edge_to_bb_id': 17, 'freq': 0}]}, {'bb_id': 17, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 16, 'freq': 0}]}, {'bb_id': 18, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 19, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 19, 'freq': 0}]}, {'bb_id': 19, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 21, 'freq': 0}, {'edge_to_bb_id': 20, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 21, 'freq': 0}, {'edge_to_bb_id': 20, 'freq': 0}]}, {'bb_id': 20, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 21, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 21, 'freq': 0}]}, {'bb_id': 21, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 0}]}, {'bb_id': 22, 'freq': 0, 'predicted_edges': [], 'actual_edges': []}]} +2024-12-05 15:27:52 - {'cfg_bbs': [{'bb_id': 0, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 2, 'freq': 0}, {'edge_to_bb_id': 1, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 2, 'freq': 1}, {'edge_to_bb_id': 1, 'freq': 0}]}, {'bb_id': 1, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 0}]}, {'bb_id': 2, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 1}]}, {'bb_id': 3, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 5, 'freq': 0}, {'edge_to_bb_id': 4, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 5, 'freq': 1}, {'edge_to_bb_id': 4, 'freq': 0}]}, {'bb_id': 4, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 0}]}, {'bb_id': 5, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 1}]}, {'bb_id': 6, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 7, 'freq': 1}]}, {'bb_id': 7, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 8, 'freq': 0}, {'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 8, 'freq': 1}, {'edge_to_bb_id': 7, 'freq': 0}]}, {'bb_id': 8, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 1}]}, {'bb_id': 9, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 1}]}, {'bb_id': 10, 'freq': 904, 'predicted_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 12, 'freq': 0}, {'edge_to_bb_id': 11, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 12, 'freq': 534}, {'edge_to_bb_id': 11, 'freq': 370}]}, {'bb_id': 11, 'freq': 370, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 370}]}, {'bb_id': 12, 'freq': 534, 'predicted_edges': [{'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 13, 'freq': 534}]}, {'bb_id': 13, 'freq': 534, 'predicted_edges': [{'edge_to_bb_id': 14, 'freq': 0}, {'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 14, 'freq': 533}, {'edge_to_bb_id': 13, 'freq': 0}]}, {'bb_id': 14, 'freq': 533, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 533}]}, {'bb_id': 15, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 19, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 19, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}]}, {'bb_id': 16, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 18, 'freq': 0}, {'edge_to_bb_id': 17, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 18, 'freq': 0}, {'edge_to_bb_id': 17, 'freq': 0}]}, {'bb_id': 17, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 16, 'freq': 0}]}, {'bb_id': 18, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 19, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 19, 'freq': 0}]}, {'bb_id': 19, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 21, 'freq': 0}, {'edge_to_bb_id': 20, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 21, 'freq': 0}, {'edge_to_bb_id': 20, 'freq': 0}]}, {'bb_id': 20, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 21, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 21, 'freq': 0}]}, {'bb_id': 21, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 0}]}, {'bb_id': 22, 'freq': 0, 'predicted_edges': [], 'actual_edges': []}]} +2024-12-05 15:28:16 - {'cfg_bbs': [{'bb_id': 0, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 2, 'freq': 0}, {'edge_to_bb_id': 1, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 2, 'freq': 1}, {'edge_to_bb_id': 1, 'freq': 0}]}, {'bb_id': 1, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 0}]}, {'bb_id': 2, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 1}]}, {'bb_id': 3, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 5, 'freq': 0}, {'edge_to_bb_id': 4, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 5, 'freq': 1}, {'edge_to_bb_id': 4, 'freq': 0}]}, {'bb_id': 4, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 0}]}, {'bb_id': 5, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 1}]}, {'bb_id': 6, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 7, 'freq': 1}]}, {'bb_id': 7, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 8, 'freq': 0}, {'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 8, 'freq': 1}, {'edge_to_bb_id': 7, 'freq': 0}]}, {'bb_id': 8, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 1}]}, {'bb_id': 9, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 1}]}, {'bb_id': 10, 'freq': 525, 'predicted_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 12, 'freq': 0}, {'edge_to_bb_id': 11, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 12, 'freq': 155}, {'edge_to_bb_id': 11, 'freq': 370}]}, {'bb_id': 11, 'freq': 370, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 370}]}, {'bb_id': 12, 'freq': 155, 'predicted_edges': [{'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 13, 'freq': 155}]}, {'bb_id': 13, 'freq': 155, 'predicted_edges': [{'edge_to_bb_id': 14, 'freq': 0}, {'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 14, 'freq': 154}, {'edge_to_bb_id': 13, 'freq': 0}]}, {'bb_id': 14, 'freq': 154, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 154}]}, {'bb_id': 15, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 19, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 19, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}]}, {'bb_id': 16, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 18, 'freq': 0}, {'edge_to_bb_id': 17, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 18, 'freq': 0}, {'edge_to_bb_id': 17, 'freq': 0}]}, {'bb_id': 17, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 16, 'freq': 0}]}, {'bb_id': 18, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 19, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 19, 'freq': 0}]}, {'bb_id': 19, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 21, 'freq': 0}, {'edge_to_bb_id': 20, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 21, 'freq': 0}, {'edge_to_bb_id': 20, 'freq': 0}]}, {'bb_id': 20, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 21, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 21, 'freq': 0}]}, {'bb_id': 21, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 0}]}, {'bb_id': 22, 'freq': 0, 'predicted_edges': [], 'actual_edges': []}]} +2024-12-05 15:28:23 - {'cfg_bbs': [{'bb_id': 0, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 2, 'freq': 0}, {'edge_to_bb_id': 1, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 2, 'freq': 1}, {'edge_to_bb_id': 1, 'freq': 0}]}, {'bb_id': 1, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 0}]}, {'bb_id': 2, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 1}]}, {'bb_id': 3, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 5, 'freq': 0}, {'edge_to_bb_id': 4, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 5, 'freq': 1}, {'edge_to_bb_id': 4, 'freq': 0}]}, {'bb_id': 4, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 0}]}, {'bb_id': 5, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 1}]}, {'bb_id': 6, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 7, 'freq': 1}]}, {'bb_id': 7, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 8, 'freq': 0}, {'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 8, 'freq': 1}, {'edge_to_bb_id': 7, 'freq': 0}]}, {'bb_id': 8, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 1}]}, {'bb_id': 9, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 1}]}, {'bb_id': 10, 'freq': 722, 'predicted_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 12, 'freq': 0}, {'edge_to_bb_id': 11, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 12, 'freq': 352}, {'edge_to_bb_id': 11, 'freq': 370}]}, {'bb_id': 11, 'freq': 370, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 370}]}, {'bb_id': 12, 'freq': 352, 'predicted_edges': [{'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 13, 'freq': 352}]}, {'bb_id': 13, 'freq': 352, 'predicted_edges': [{'edge_to_bb_id': 14, 'freq': 0}, {'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 14, 'freq': 351}, {'edge_to_bb_id': 13, 'freq': 0}]}, {'bb_id': 14, 'freq': 351, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 351}]}, {'bb_id': 15, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 19, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 19, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}]}, {'bb_id': 16, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 18, 'freq': 0}, {'edge_to_bb_id': 17, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 18, 'freq': 0}, {'edge_to_bb_id': 17, 'freq': 0}]}, {'bb_id': 17, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 16, 'freq': 0}]}, {'bb_id': 18, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 19, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 19, 'freq': 0}]}, {'bb_id': 19, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 21, 'freq': 0}, {'edge_to_bb_id': 20, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 21, 'freq': 0}, {'edge_to_bb_id': 20, 'freq': 0}]}, {'bb_id': 20, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 21, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 21, 'freq': 0}]}, {'bb_id': 21, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 0}]}, {'bb_id': 22, 'freq': 0, 'predicted_edges': [], 'actual_edges': []}]} +2024-12-05 15:28:30 - {'cfg_bbs': [{'bb_id': 0, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 2, 'freq': 0}, {'edge_to_bb_id': 1, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 2, 'freq': 1}, {'edge_to_bb_id': 1, 'freq': 0}]}, {'bb_id': 1, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 0}]}, {'bb_id': 2, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 1}]}, {'bb_id': 3, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 5, 'freq': 0}, {'edge_to_bb_id': 4, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 5, 'freq': 1}, {'edge_to_bb_id': 4, 'freq': 0}]}, {'bb_id': 4, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 0}]}, {'bb_id': 5, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 1}]}, {'bb_id': 6, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 7, 'freq': 1}]}, {'bb_id': 7, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 8, 'freq': 0}, {'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 8, 'freq': 1}, {'edge_to_bb_id': 7, 'freq': 0}]}, {'bb_id': 8, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 1}]}, {'bb_id': 9, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 1}]}, {'bb_id': 10, 'freq': 892, 'predicted_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 12, 'freq': 0}, {'edge_to_bb_id': 11, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 12, 'freq': 522}, {'edge_to_bb_id': 11, 'freq': 370}]}, {'bb_id': 11, 'freq': 370, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 370}]}, {'bb_id': 12, 'freq': 522, 'predicted_edges': [{'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 13, 'freq': 522}]}, {'bb_id': 13, 'freq': 522, 'predicted_edges': [{'edge_to_bb_id': 14, 'freq': 0}, {'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 14, 'freq': 521}, {'edge_to_bb_id': 13, 'freq': 0}]}, {'bb_id': 14, 'freq': 521, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 521}]}, {'bb_id': 15, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 19, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 19, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}]}, {'bb_id': 16, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 18, 'freq': 0}, {'edge_to_bb_id': 17, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 18, 'freq': 0}, {'edge_to_bb_id': 17, 'freq': 0}]}, {'bb_id': 17, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 16, 'freq': 0}]}, {'bb_id': 18, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 19, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 19, 'freq': 0}]}, {'bb_id': 19, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 21, 'freq': 0}, {'edge_to_bb_id': 20, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 21, 'freq': 0}, {'edge_to_bb_id': 20, 'freq': 0}]}, {'bb_id': 20, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 21, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 21, 'freq': 0}]}, {'bb_id': 21, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 0}]}, {'bb_id': 22, 'freq': 0, 'predicted_edges': [], 'actual_edges': []}]} +2024-12-05 15:28:37 - {'cfg_bbs': [{'bb_id': 0, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 2, 'freq': 0}, {'edge_to_bb_id': 1, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 2, 'freq': 1}, {'edge_to_bb_id': 1, 'freq': 0}]}, {'bb_id': 1, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 0}]}, {'bb_id': 2, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 1}]}, {'bb_id': 3, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 5, 'freq': 0}, {'edge_to_bb_id': 4, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 5, 'freq': 1}, {'edge_to_bb_id': 4, 'freq': 0}]}, {'bb_id': 4, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 0}]}, {'bb_id': 5, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 1}]}, {'bb_id': 6, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 7, 'freq': 1}]}, {'bb_id': 7, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 8, 'freq': 0}, {'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 8, 'freq': 1}, {'edge_to_bb_id': 7, 'freq': 0}]}, {'bb_id': 8, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 1}]}, {'bb_id': 9, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 1}]}, {'bb_id': 10, 'freq': 1001, 'predicted_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 12, 'freq': 0}, {'edge_to_bb_id': 11, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 15, 'freq': 1}, {'edge_to_bb_id': 12, 'freq': 630}, {'edge_to_bb_id': 11, 'freq': 370}]}, {'bb_id': 11, 'freq': 370, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 370}]}, {'bb_id': 12, 'freq': 630, 'predicted_edges': [{'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 13, 'freq': 630}]}, {'bb_id': 13, 'freq': 630, 'predicted_edges': [{'edge_to_bb_id': 14, 'freq': 0}, {'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 14, 'freq': 630}, {'edge_to_bb_id': 13, 'freq': 0}]}, {'bb_id': 14, 'freq': 630, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 630}]}, {'bb_id': 15, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 19, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 19, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 1}]}, {'bb_id': 16, 'freq': 6305, 'predicted_edges': [{'edge_to_bb_id': 18, 'freq': 0}, {'edge_to_bb_id': 17, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 18, 'freq': 0}, {'edge_to_bb_id': 17, 'freq': 6304}]}, {'bb_id': 17, 'freq': 6304, 'predicted_edges': [{'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 16, 'freq': 6304}]}, {'bb_id': 18, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 19, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 19, 'freq': 0}]}, {'bb_id': 19, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 21, 'freq': 0}, {'edge_to_bb_id': 20, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 21, 'freq': 0}, {'edge_to_bb_id': 20, 'freq': 0}]}, {'bb_id': 20, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 21, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 21, 'freq': 0}]}, {'bb_id': 21, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 0}]}, {'bb_id': 22, 'freq': 0, 'predicted_edges': [], 'actual_edges': []}]} +2024-12-05 15:28:40 - {'cfg_bbs': [{'bb_id': 0, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 2, 'freq': 0}, {'edge_to_bb_id': 1, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 2, 'freq': 1}, {'edge_to_bb_id': 1, 'freq': 0}]}, {'bb_id': 1, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 0}]}, {'bb_id': 2, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 1}]}, {'bb_id': 3, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 5, 'freq': 0}, {'edge_to_bb_id': 4, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 5, 'freq': 1}, {'edge_to_bb_id': 4, 'freq': 0}]}, {'bb_id': 4, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 0}]}, {'bb_id': 5, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 1}]}, {'bb_id': 6, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 7, 'freq': 1}]}, {'bb_id': 7, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 8, 'freq': 0}, {'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 8, 'freq': 1}, {'edge_to_bb_id': 7, 'freq': 0}]}, {'bb_id': 8, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 1}]}, {'bb_id': 9, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 1}]}, {'bb_id': 10, 'freq': 1001, 'predicted_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 12, 'freq': 0}, {'edge_to_bb_id': 11, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 15, 'freq': 1}, {'edge_to_bb_id': 12, 'freq': 630}, {'edge_to_bb_id': 11, 'freq': 370}]}, {'bb_id': 11, 'freq': 370, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 370}]}, {'bb_id': 12, 'freq': 630, 'predicted_edges': [{'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 13, 'freq': 630}]}, {'bb_id': 13, 'freq': 630, 'predicted_edges': [{'edge_to_bb_id': 14, 'freq': 0}, {'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 14, 'freq': 630}, {'edge_to_bb_id': 13, 'freq': 0}]}, {'bb_id': 14, 'freq': 630, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 630}]}, {'bb_id': 15, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 19, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 19, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 1}]}, {'bb_id': 16, 'freq': 43557, 'predicted_edges': [{'edge_to_bb_id': 18, 'freq': 0}, {'edge_to_bb_id': 17, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 18, 'freq': 1}, {'edge_to_bb_id': 17, 'freq': 43556}]}, {'bb_id': 17, 'freq': 43556, 'predicted_edges': [{'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 16, 'freq': 43556}]}, {'bb_id': 18, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 19, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 19, 'freq': 0}]}, {'bb_id': 19, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 21, 'freq': 0}, {'edge_to_bb_id': 20, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 21, 'freq': 0}, {'edge_to_bb_id': 20, 'freq': 0}]}, {'bb_id': 20, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 21, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 21, 'freq': 0}]}, {'bb_id': 21, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 0}]}, {'bb_id': 22, 'freq': 0, 'predicted_edges': [], 'actual_edges': []}]} +2024-12-05 15:30:56 - {'cfg_bbs': [{'bb_id': 0, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 2, 'freq': 0}, {'edge_to_bb_id': 1, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 2, 'freq': 1}, {'edge_to_bb_id': 1, 'freq': 0}]}, {'bb_id': 1, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 0}]}, {'bb_id': 2, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 1}]}, {'bb_id': 3, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 5, 'freq': 0}, {'edge_to_bb_id': 4, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 5, 'freq': 1}, {'edge_to_bb_id': 4, 'freq': 0}]}, {'bb_id': 4, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 0}]}, {'bb_id': 5, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 1}]}, {'bb_id': 6, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 7, 'freq': 1}]}, {'bb_id': 7, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 8, 'freq': 0}, {'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 8, 'freq': 1}, {'edge_to_bb_id': 7, 'freq': 0}]}, {'bb_id': 8, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 1}]}, {'bb_id': 9, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 1}]}, {'bb_id': 10, 'freq': 664, 'predicted_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 12, 'freq': 0}, {'edge_to_bb_id': 11, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 12, 'freq': 294}, {'edge_to_bb_id': 11, 'freq': 370}]}, {'bb_id': 11, 'freq': 370, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 370}]}, {'bb_id': 12, 'freq': 294, 'predicted_edges': [{'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 13, 'freq': 294}]}, {'bb_id': 13, 'freq': 294, 'predicted_edges': [{'edge_to_bb_id': 14, 'freq': 0}, {'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 14, 'freq': 293}, {'edge_to_bb_id': 13, 'freq': 0}]}, {'bb_id': 14, 'freq': 293, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 293}]}, {'bb_id': 15, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 19, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 19, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}]}, {'bb_id': 16, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 18, 'freq': 0}, {'edge_to_bb_id': 17, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 18, 'freq': 0}, {'edge_to_bb_id': 17, 'freq': 0}]}, {'bb_id': 17, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 16, 'freq': 0}]}, {'bb_id': 18, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 19, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 19, 'freq': 0}]}, {'bb_id': 19, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 21, 'freq': 0}, {'edge_to_bb_id': 20, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 21, 'freq': 0}, {'edge_to_bb_id': 20, 'freq': 0}]}, {'bb_id': 20, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 21, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 21, 'freq': 0}]}, {'bb_id': 21, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 0}]}, {'bb_id': 22, 'freq': 0, 'predicted_edges': [], 'actual_edges': []}]} +2024-12-05 15:31:12 - {'cfg_bbs': [{'bb_id': 0, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 2, 'freq': 0}, {'edge_to_bb_id': 1, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 2, 'freq': 1}, {'edge_to_bb_id': 1, 'freq': 0}]}, {'bb_id': 1, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 0}]}, {'bb_id': 2, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 1}]}, {'bb_id': 3, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 5, 'freq': 0}, {'edge_to_bb_id': 4, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 5, 'freq': 1}, {'edge_to_bb_id': 4, 'freq': 0}]}, {'bb_id': 4, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 0}]}, {'bb_id': 5, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 1}]}, {'bb_id': 6, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 7, 'freq': 1}]}, {'bb_id': 7, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 8, 'freq': 0}, {'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 8, 'freq': 1}, {'edge_to_bb_id': 7, 'freq': 0}]}, {'bb_id': 8, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 1}]}, {'bb_id': 9, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 1}]}, {'bb_id': 10, 'freq': 1001, 'predicted_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 12, 'freq': 0}, {'edge_to_bb_id': 11, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 15, 'freq': 1}, {'edge_to_bb_id': 12, 'freq': 630}, {'edge_to_bb_id': 11, 'freq': 370}]}, {'bb_id': 11, 'freq': 370, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 370}]}, {'bb_id': 12, 'freq': 630, 'predicted_edges': [{'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 13, 'freq': 630}]}, {'bb_id': 13, 'freq': 630, 'predicted_edges': [{'edge_to_bb_id': 14, 'freq': 0}, {'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 14, 'freq': 630}, {'edge_to_bb_id': 13, 'freq': 0}]}, {'bb_id': 14, 'freq': 630, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 630}]}, {'bb_id': 15, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 19, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 19, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 1}]}, {'bb_id': 16, 'freq': 43557, 'predicted_edges': [{'edge_to_bb_id': 18, 'freq': 0}, {'edge_to_bb_id': 17, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 18, 'freq': 1}, {'edge_to_bb_id': 17, 'freq': 43556}]}, {'bb_id': 17, 'freq': 43556, 'predicted_edges': [{'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 16, 'freq': 43556}]}, {'bb_id': 18, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 19, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 19, 'freq': 0}]}, {'bb_id': 19, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 21, 'freq': 0}, {'edge_to_bb_id': 20, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 21, 'freq': 0}, {'edge_to_bb_id': 20, 'freq': 0}]}, {'bb_id': 20, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 21, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 21, 'freq': 0}]}, {'bb_id': 21, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 0}]}, {'bb_id': 22, 'freq': 0, 'predicted_edges': [], 'actual_edges': []}]} +2024-12-05 15:32:15 - {'cfg_bbs': [{'bb_id': 0, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 2, 'freq': 0}, {'edge_to_bb_id': 1, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 2, 'freq': 1}, {'edge_to_bb_id': 1, 'freq': 0}]}, {'bb_id': 1, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 0}]}, {'bb_id': 2, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 1}]}, {'bb_id': 3, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 5, 'freq': 0}, {'edge_to_bb_id': 4, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 5, 'freq': 1}, {'edge_to_bb_id': 4, 'freq': 0}]}, {'bb_id': 4, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 0}]}, {'bb_id': 5, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 1}]}, {'bb_id': 6, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 7, 'freq': 1}]}, {'bb_id': 7, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 8, 'freq': 0}, {'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 8, 'freq': 1}, {'edge_to_bb_id': 7, 'freq': 0}]}, {'bb_id': 8, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 1}]}, {'bb_id': 9, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 1}]}, {'bb_id': 10, 'freq': 673, 'predicted_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 12, 'freq': 0}, {'edge_to_bb_id': 11, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 12, 'freq': 303}, {'edge_to_bb_id': 11, 'freq': 370}]}, {'bb_id': 11, 'freq': 370, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 370}]}, {'bb_id': 12, 'freq': 303, 'predicted_edges': [{'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 13, 'freq': 303}]}, {'bb_id': 13, 'freq': 303, 'predicted_edges': [{'edge_to_bb_id': 14, 'freq': 0}, {'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 14, 'freq': 302}, {'edge_to_bb_id': 13, 'freq': 0}]}, {'bb_id': 14, 'freq': 302, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 302}]}, {'bb_id': 15, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 19, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 19, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}]}, {'bb_id': 16, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 18, 'freq': 0}, {'edge_to_bb_id': 17, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 18, 'freq': 0}, {'edge_to_bb_id': 17, 'freq': 0}]}, {'bb_id': 17, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 16, 'freq': 0}]}, {'bb_id': 18, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 19, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 19, 'freq': 0}]}, {'bb_id': 19, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 21, 'freq': 0}, {'edge_to_bb_id': 20, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 21, 'freq': 0}, {'edge_to_bb_id': 20, 'freq': 0}]}, {'bb_id': 20, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 21, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 21, 'freq': 0}]}, {'bb_id': 21, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 0}]}, {'bb_id': 22, 'freq': 0, 'predicted_edges': [], 'actual_edges': []}]} From 8b4b15e31510454ead47d7db4e5d2e7a93f69d16 Mon Sep 17 00:00:00 2001 From: Jakob Louis Therkelsen Date: Thu, 5 Dec 2024 16:00:58 -0500 Subject: [PATCH 83/84] getting basic inputs (hacky method) --- .../gins_scripts/inputs/generate_inputs.py | 4 +- .../gins_scripts/inputs/test_predict.txt | 1030 ++--------------- jac/examples/gins_scripts/test.txt | 31 + jac/jaclang/runtimelib/gins/ghost.py | 1 + jac/jaclang/runtimelib/gins/tracer.py | 15 + 5 files changed, 114 insertions(+), 967 deletions(-) diff --git a/jac/examples/gins_scripts/inputs/generate_inputs.py b/jac/examples/gins_scripts/inputs/generate_inputs.py index 10f32193e1..6eb4e57d1d 100644 --- a/jac/examples/gins_scripts/inputs/generate_inputs.py +++ b/jac/examples/gins_scripts/inputs/generate_inputs.py @@ -13,7 +13,7 @@ # random_numbers = list(np.random.normal(mean,std_dev, num_samples)) # w_str = "\n".join(str(round(num,3)) for num in random_numbers) -num_samples = 1000 +num_samples = 100 start_value = 99 end_avg = 105 @@ -36,4 +36,4 @@ # Write data to output file with open(output_file, 'w') as file: for value in sensor_data: - file.write(f"{value:.2f}\n") \ No newline at end of file + file.write(f"{value:.4f}\n") \ No newline at end of file diff --git a/jac/examples/gins_scripts/inputs/test_predict.txt b/jac/examples/gins_scripts/inputs/test_predict.txt index 005d194095..63dd0b0992 100644 --- a/jac/examples/gins_scripts/inputs/test_predict.txt +++ b/jac/examples/gins_scripts/inputs/test_predict.txt @@ -1,1000 +1,100 @@ -98.53 -98.54 -98.65 -98.40 98.95 -98.58 -98.67 -98.59 -98.55 -99.28 -99.10 -99.31 -98.67 -98.39 -99.17 -99.24 -98.83 -98.77 -98.74 -99.32 -98.72 -99.19 -99.27 -99.63 -99.37 -98.92 -99.06 -99.18 -99.20 -99.38 -99.22 -99.22 -98.54 -99.06 -99.30 -98.92 -98.87 -98.67 -99.49 -99.36 -99.43 -98.68 +98.36 +98.60 +99.57 +98.91 +99.12 99.37 -98.72 -99.11 -98.88 -99.39 -99.30 -98.66 -99.78 -99.70 -98.98 -99.58 -98.66 -99.36 -99.45 -99.35 -99.21 -98.76 -99.28 -99.38 -98.96 -98.77 -99.13 -99.87 -99.49 -99.39 -99.89 -99.32 -99.10 -98.78 +99.04 99.28 -99.03 -99.40 -99.74 -99.44 +99.96 +99.23 99.72 -99.78 -99.56 -99.12 -99.82 -98.96 -99.73 -99.04 -99.08 -99.43 -99.95 -99.06 -99.31 -99.53 -99.83 -99.85 -100.00 -99.03 -98.96 -99.33 99.23 -99.76 -99.55 -99.08 -99.97 -98.93 -99.68 -99.41 -99.97 -99.99 -99.54 -99.62 -99.78 -99.61 -99.73 -99.35 -99.57 -99.77 -99.16 99.45 -99.79 -99.93 -99.84 -100.07 -99.18 -99.83 -99.66 -99.30 -99.76 -100.14 -100.22 -100.26 -100.15 -99.96 -99.86 -99.27 -99.89 -100.11 -99.55 -100.29 -99.21 -99.52 -100.12 -99.48 -99.24 99.75 -99.93 -99.40 -99.65 -99.23 -99.23 -99.56 -99.23 -100.10 -99.99 -100.07 -100.34 -100.34 -99.44 -99.25 -99.80 -100.03 -99.46 -100.10 -100.29 -99.69 -100.01 -99.40 -99.59 -100.09 -99.94 -99.46 -100.41 -99.96 -99.73 -100.02 -99.84 -100.35 -99.35 -99.74 -99.74 -99.55 -99.54 -99.86 -100.15 -100.46 -100.43 -100.22 99.54 -100.38 -99.88 -99.91 -99.76 -100.11 -99.63 -100.44 -99.84 -99.83 -100.04 -100.29 -100.16 -100.17 -99.93 -100.10 -99.71 -99.74 -100.14 -100.52 -100.34 -100.15 -100.45 -100.51 -99.95 -100.04 -100.33 -100.03 -99.75 -99.91 -100.38 -100.15 -99.99 -100.76 -100.02 -100.45 -100.28 -99.82 -100.23 -100.35 -99.74 -99.69 -100.34 -99.95 -100.81 -99.73 -99.91 -100.29 -100.44 -100.85 -100.20 +100.37 +100.12 99.97 -100.46 -99.98 -100.08 -100.23 -100.11 -100.54 -99.78 -100.15 -100.02 -99.89 -100.22 -100.32 -99.82 -100.13 -100.35 -100.50 -99.98 -100.51 -100.09 -100.42 -100.09 -100.36 -100.43 -99.94 -100.25 -100.30 -101.06 -100.23 -100.95 -100.73 -100.82 -100.02 -100.10 -100.49 -100.62 -100.90 -101.12 -100.09 -100.21 -100.81 -101.02 -100.76 -100.28 -101.15 -100.90 +100.48 +100.44 +99.77 +99.67 +99.79 100.01 -100.77 -100.75 -101.00 -100.15 -100.86 -100.79 -101.14 -100.74 -100.37 -100.10 +100.31 100.69 -100.16 -100.75 -101.25 -100.59 -100.40 -100.62 -101.12 -101.28 -100.30 -100.39 -101.30 -101.29 -100.48 -100.15 -100.46 -101.21 -101.16 -100.17 -100.59 -100.67 -100.48 -101.36 -101.23 -100.50 -100.98 -100.50 -100.78 -101.00 -101.03 -100.73 -100.43 -100.33 -100.29 -100.91 -100.80 -100.86 -101.34 -100.91 -101.07 +101.04 +100.79 +101.09 +101.11 100.49 -100.82 -100.69 -100.33 -100.46 -101.40 -101.30 -100.35 +100.24 +100.79 +100.40 100.83 -100.46 -101.55 -101.38 -101.01 -100.62 -101.13 -101.34 -101.37 -100.50 -100.49 -100.98 -100.50 -100.69 -101.15 -101.21 -100.48 -100.53 101.07 -101.31 -101.63 -100.57 -101.58 -101.40 -101.65 -101.16 -100.56 -101.08 -101.06 -101.40 -100.89 -100.86 -100.74 -100.75 -101.57 -100.99 +101.18 +101.02 101.38 -100.93 -100.77 -101.66 -100.62 -101.40 -101.63 -101.26 -101.06 -101.40 -100.80 -100.92 -100.86 -100.67 -101.41 -101.10 -101.82 -101.46 -101.64 -100.95 -101.79 -101.73 101.62 -101.43 -101.87 -101.75 -101.84 -101.57 -101.63 -101.04 -101.80 -101.78 -101.84 -101.51 -101.39 -101.76 -101.55 -101.91 -101.15 -101.29 -101.15 -101.60 -101.81 -101.11 -101.78 -101.83 -102.02 -102.03 -101.57 -101.19 -101.96 -101.55 -101.31 -100.94 -100.96 -100.98 -101.78 -101.06 -101.00 -101.77 -101.66 -101.82 -101.68 -101.64 -101.00 -101.73 -101.19 -101.27 -101.91 -101.05 -101.86 -101.71 -101.91 -102.03 -101.55 -101.18 -101.10 -101.20 +101.61 +101.40 101.84 -101.53 -101.34 -101.69 -101.28 -101.90 -101.63 -101.93 -102.16 -101.46 -101.21 -102.06 -101.53 -102.23 -101.14 -101.91 -102.17 -101.88 -101.76 +101.70 +101.87 +102.11 101.59 -102.03 -102.09 -102.30 +101.31 101.93 -102.14 -102.35 -101.89 -101.82 -102.15 -102.03 -102.21 -102.12 -101.61 -101.61 -102.37 -101.53 -101.27 -102.31 -102.04 -101.33 -101.69 -101.51 -101.37 -101.44 -101.52 -102.19 -101.68 +102.20 +102.36 101.67 -101.93 -102.48 -101.75 -101.99 -101.80 -102.42 -101.73 -101.37 -101.63 -102.43 -101.98 -102.06 102.29 -101.68 -102.30 -102.50 -101.50 -101.61 -102.20 -102.54 -101.71 -102.26 -101.94 -101.60 -101.93 -102.00 -102.21 -101.65 -101.63 -101.63 -102.06 -101.71 -101.96 -101.82 -102.57 -102.65 -102.58 -101.82 -102.18 -102.73 -102.20 -102.37 -101.66 -102.52 -101.84 -102.02 -101.93 -101.95 -102.56 -101.97 -101.86 -102.24 -101.96 -102.56 -102.60 -101.96 +102.74 101.77 -102.29 -102.06 -102.69 -101.98 -101.82 -101.90 -102.53 -102.22 -102.61 -102.73 -101.76 -102.90 -101.98 -102.65 -102.02 -101.97 -102.17 -102.01 -101.88 -101.91 -102.87 -102.87 -101.97 -102.24 -101.81 -102.48 -102.65 -102.82 -102.15 -101.89 -102.30 +101.73 +102.41 +101.83 102.19 -102.11 -102.09 -102.05 -102.02 -101.90 -102.80 -102.26 -102.45 -102.39 -102.59 -101.95 -101.93 -102.96 -102.40 -102.30 -102.63 -102.22 -102.27 -103.12 -102.89 -102.53 -102.60 -102.48 -102.31 -102.38 -102.98 -102.24 -102.65 -102.89 -102.96 -102.57 -102.53 -103.16 -102.54 -102.17 -102.48 -102.28 -102.85 -102.87 -102.55 -103.28 -103.16 -102.15 -102.84 -102.15 -102.28 -102.21 -102.71 -102.82 -102.72 102.36 -103.15 -103.16 -102.64 -103.13 -102.48 -102.61 -103.06 -103.15 -103.07 -102.61 -103.15 -102.82 -102.96 -103.42 -102.38 -103.33 -103.20 -103.26 -102.75 -102.74 -102.97 -103.25 -103.22 -102.66 -102.99 -103.32 -102.89 -102.85 -103.38 -102.55 -103.21 -102.73 -102.93 -102.53 -102.71 -103.31 -102.90 -103.03 -102.69 -103.02 -102.60 -103.50 -102.68 -102.73 -103.59 -102.62 -102.60 -103.12 -102.58 -102.84 -102.51 -103.64 -103.03 -103.46 -102.67 -103.48 -103.59 -102.92 -102.95 -103.21 -103.41 -102.88 -103.63 -103.66 -102.62 -103.06 -103.65 -103.71 -102.64 -103.19 -102.88 -103.01 -102.94 -103.27 -103.19 -102.68 -103.49 -102.75 -103.61 -103.42 -103.18 103.03 -102.73 -102.67 -102.73 -103.55 -102.68 -103.56 -102.85 -103.43 +102.83 +102.90 103.10 -103.38 -102.79 -102.81 -103.76 -103.84 -103.32 +103.05 103.00 -103.74 -103.17 -103.47 -103.55 -103.76 -103.24 -103.85 -102.95 -103.74 103.08 -103.03 -103.16 -103.96 -103.87 -102.96 -103.48 -103.24 -103.42 -103.05 -102.96 -103.58 -103.27 -103.47 -103.30 -102.92 -102.94 -103.67 -103.32 -103.46 -102.95 -103.70 -103.44 -103.91 -103.18 -103.81 -103.56 -104.10 -103.22 -103.47 -103.71 -104.15 -104.03 -103.18 -103.80 -103.97 -103.12 -103.79 -103.87 -103.87 -103.79 -103.77 -104.18 -103.78 -103.10 -103.70 -103.72 -104.03 -103.72 -103.10 -103.71 -103.81 -103.28 -103.33 -104.06 -103.47 -104.02 -103.83 -103.28 -104.04 -103.83 -103.70 -103.24 -103.93 -103.22 -104.05 -103.50 -104.00 -103.98 -103.81 -103.48 -104.21 -104.01 -104.17 -103.80 -104.27 -103.77 +102.93 103.35 -103.64 -103.81 -104.20 -103.92 -103.79 -103.58 -103.77 -103.92 -104.51 -103.47 -104.17 -104.47 -104.11 -104.47 -103.48 -104.52 -104.00 -103.40 -103.57 -104.30 -103.68 -104.51 -104.55 -104.24 -103.96 -103.56 -103.99 -103.45 +102.55 103.75 -104.62 -104.24 -103.72 -103.92 -103.87 -103.78 -103.71 -104.59 -103.68 +102.81 +103.23 +103.75 +102.93 +103.51 103.84 -104.17 -103.95 -104.05 -104.25 +103.51 104.09 -104.50 -104.19 -104.14 -104.16 -104.54 -104.33 -104.75 -103.97 -103.67 -103.61 -104.66 -104.52 -104.45 -104.21 -104.71 -104.40 -103.84 -103.91 -104.29 -104.31 -104.52 -103.96 -104.17 -103.76 -103.98 -104.29 -104.40 -104.65 -103.99 -104.37 -103.82 -104.02 -103.80 -104.88 -103.80 -103.95 -104.12 -104.60 -104.13 -104.06 -103.92 -104.34 -104.59 -104.74 -104.30 -104.79 -104.38 -104.89 -104.30 -104.49 -104.20 +103.62 +103.42 +103.54 103.85 -104.69 -104.25 -103.98 -104.58 -104.06 +103.64 +104.48 +103.50 +104.09 104.61 -104.08 -104.42 -104.67 -105.06 -104.62 -104.05 -105.09 -103.94 -104.04 -104.18 -104.11 -104.64 -105.04 -104.70 -104.95 -104.06 -104.74 +103.66 104.61 -104.69 -104.57 -104.01 -104.22 -105.12 -104.46 -104.24 -104.11 -104.57 -105.02 -104.38 -104.70 -104.76 -104.40 -104.37 -104.97 -104.20 -104.24 -104.41 -105.02 -104.79 -104.68 -104.60 -104.18 -104.91 -104.38 -105.01 -105.08 -105.03 -104.91 -104.76 -104.35 -104.39 -104.77 -105.09 -104.95 -104.76 -105.34 -105.30 -104.79 -105.26 -104.83 -104.37 -104.69 -104.87 -104.36 -104.57 -104.82 -105.00 -104.62 -105.47 -105.26 -104.73 +104.47 +104.72 +104.14 +104.65 +104.92 +104.92 +104.15 +104.59 +104.44 diff --git a/jac/examples/gins_scripts/test.txt b/jac/examples/gins_scripts/test.txt index deae538298..70bb97496e 100644 --- a/jac/examples/gins_scripts/test.txt +++ b/jac/examples/gins_scripts/test.txt @@ -152,3 +152,34 @@ The exact frequencies for bb7, bb8, bb9, bb10, bb12 and bb13 depend on how many 2024-12-05 15:30:56 - {'cfg_bbs': [{'bb_id': 0, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 2, 'freq': 0}, {'edge_to_bb_id': 1, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 2, 'freq': 1}, {'edge_to_bb_id': 1, 'freq': 0}]}, {'bb_id': 1, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 0}]}, {'bb_id': 2, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 1}]}, {'bb_id': 3, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 5, 'freq': 0}, {'edge_to_bb_id': 4, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 5, 'freq': 1}, {'edge_to_bb_id': 4, 'freq': 0}]}, {'bb_id': 4, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 0}]}, {'bb_id': 5, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 1}]}, {'bb_id': 6, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 7, 'freq': 1}]}, {'bb_id': 7, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 8, 'freq': 0}, {'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 8, 'freq': 1}, {'edge_to_bb_id': 7, 'freq': 0}]}, {'bb_id': 8, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 1}]}, {'bb_id': 9, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 1}]}, {'bb_id': 10, 'freq': 664, 'predicted_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 12, 'freq': 0}, {'edge_to_bb_id': 11, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 12, 'freq': 294}, {'edge_to_bb_id': 11, 'freq': 370}]}, {'bb_id': 11, 'freq': 370, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 370}]}, {'bb_id': 12, 'freq': 294, 'predicted_edges': [{'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 13, 'freq': 294}]}, {'bb_id': 13, 'freq': 294, 'predicted_edges': [{'edge_to_bb_id': 14, 'freq': 0}, {'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 14, 'freq': 293}, {'edge_to_bb_id': 13, 'freq': 0}]}, {'bb_id': 14, 'freq': 293, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 293}]}, {'bb_id': 15, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 19, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 19, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}]}, {'bb_id': 16, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 18, 'freq': 0}, {'edge_to_bb_id': 17, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 18, 'freq': 0}, {'edge_to_bb_id': 17, 'freq': 0}]}, {'bb_id': 17, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 16, 'freq': 0}]}, {'bb_id': 18, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 19, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 19, 'freq': 0}]}, {'bb_id': 19, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 21, 'freq': 0}, {'edge_to_bb_id': 20, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 21, 'freq': 0}, {'edge_to_bb_id': 20, 'freq': 0}]}, {'bb_id': 20, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 21, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 21, 'freq': 0}]}, {'bb_id': 21, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 0}]}, {'bb_id': 22, 'freq': 0, 'predicted_edges': [], 'actual_edges': []}]} 2024-12-05 15:31:12 - {'cfg_bbs': [{'bb_id': 0, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 2, 'freq': 0}, {'edge_to_bb_id': 1, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 2, 'freq': 1}, {'edge_to_bb_id': 1, 'freq': 0}]}, {'bb_id': 1, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 0}]}, {'bb_id': 2, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 1}]}, {'bb_id': 3, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 5, 'freq': 0}, {'edge_to_bb_id': 4, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 5, 'freq': 1}, {'edge_to_bb_id': 4, 'freq': 0}]}, {'bb_id': 4, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 0}]}, {'bb_id': 5, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 1}]}, {'bb_id': 6, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 7, 'freq': 1}]}, {'bb_id': 7, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 8, 'freq': 0}, {'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 8, 'freq': 1}, {'edge_to_bb_id': 7, 'freq': 0}]}, {'bb_id': 8, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 1}]}, {'bb_id': 9, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 1}]}, {'bb_id': 10, 'freq': 1001, 'predicted_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 12, 'freq': 0}, {'edge_to_bb_id': 11, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 15, 'freq': 1}, {'edge_to_bb_id': 12, 'freq': 630}, {'edge_to_bb_id': 11, 'freq': 370}]}, {'bb_id': 11, 'freq': 370, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 370}]}, {'bb_id': 12, 'freq': 630, 'predicted_edges': [{'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 13, 'freq': 630}]}, {'bb_id': 13, 'freq': 630, 'predicted_edges': [{'edge_to_bb_id': 14, 'freq': 0}, {'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 14, 'freq': 630}, {'edge_to_bb_id': 13, 'freq': 0}]}, {'bb_id': 14, 'freq': 630, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 630}]}, {'bb_id': 15, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 19, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 19, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 1}]}, {'bb_id': 16, 'freq': 43557, 'predicted_edges': [{'edge_to_bb_id': 18, 'freq': 0}, {'edge_to_bb_id': 17, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 18, 'freq': 1}, {'edge_to_bb_id': 17, 'freq': 43556}]}, {'bb_id': 17, 'freq': 43556, 'predicted_edges': [{'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 16, 'freq': 43556}]}, {'bb_id': 18, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 19, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 19, 'freq': 0}]}, {'bb_id': 19, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 21, 'freq': 0}, {'edge_to_bb_id': 20, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 21, 'freq': 0}, {'edge_to_bb_id': 20, 'freq': 0}]}, {'bb_id': 20, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 21, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 21, 'freq': 0}]}, {'bb_id': 21, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 0}]}, {'bb_id': 22, 'freq': 0, 'predicted_edges': [], 'actual_edges': []}]} 2024-12-05 15:32:15 - {'cfg_bbs': [{'bb_id': 0, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 2, 'freq': 0}, {'edge_to_bb_id': 1, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 2, 'freq': 1}, {'edge_to_bb_id': 1, 'freq': 0}]}, {'bb_id': 1, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 0}]}, {'bb_id': 2, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 1}]}, {'bb_id': 3, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 5, 'freq': 0}, {'edge_to_bb_id': 4, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 5, 'freq': 1}, {'edge_to_bb_id': 4, 'freq': 0}]}, {'bb_id': 4, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 0}]}, {'bb_id': 5, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 1}]}, {'bb_id': 6, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 7, 'freq': 1}]}, {'bb_id': 7, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 8, 'freq': 0}, {'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 8, 'freq': 1}, {'edge_to_bb_id': 7, 'freq': 0}]}, {'bb_id': 8, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 1}]}, {'bb_id': 9, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 1}]}, {'bb_id': 10, 'freq': 673, 'predicted_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 12, 'freq': 0}, {'edge_to_bb_id': 11, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 12, 'freq': 303}, {'edge_to_bb_id': 11, 'freq': 370}]}, {'bb_id': 11, 'freq': 370, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 370}]}, {'bb_id': 12, 'freq': 303, 'predicted_edges': [{'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 13, 'freq': 303}]}, {'bb_id': 13, 'freq': 303, 'predicted_edges': [{'edge_to_bb_id': 14, 'freq': 0}, {'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 14, 'freq': 302}, {'edge_to_bb_id': 13, 'freq': 0}]}, {'bb_id': 14, 'freq': 302, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 302}]}, {'bb_id': 15, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 19, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 19, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}]}, {'bb_id': 16, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 18, 'freq': 0}, {'edge_to_bb_id': 17, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 18, 'freq': 0}, {'edge_to_bb_id': 17, 'freq': 0}]}, {'bb_id': 17, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 16, 'freq': 0}]}, {'bb_id': 18, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 19, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 19, 'freq': 0}]}, {'bb_id': 19, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 21, 'freq': 0}, {'edge_to_bb_id': 20, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 21, 'freq': 0}, {'edge_to_bb_id': 20, 'freq': 0}]}, {'bb_id': 20, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 21, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 21, 'freq': 0}]}, {'bb_id': 21, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 0}]}, {'bb_id': 22, 'freq': 0, 'predicted_edges': [], 'actual_edges': []}]} +2024-12-05 15:49:40 - {'cfg_bbs': [{'bb_id': 0, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 2, 'freq': 0}, {'edge_to_bb_id': 1, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 2, 'freq': 1}, {'edge_to_bb_id': 1, 'freq': 0}]}, {'bb_id': 1, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 0}]}, {'bb_id': 2, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 1}]}, {'bb_id': 3, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 5, 'freq': 0}, {'edge_to_bb_id': 4, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 5, 'freq': 1}, {'edge_to_bb_id': 4, 'freq': 0}]}, {'bb_id': 4, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 0}]}, {'bb_id': 5, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 1}]}, {'bb_id': 6, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 7, 'freq': 1}]}, {'bb_id': 7, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 8, 'freq': 0}, {'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 8, 'freq': 1}, {'edge_to_bb_id': 7, 'freq': 0}]}, {'bb_id': 8, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 1}]}, {'bb_id': 9, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 1}]}, {'bb_id': 10, 'freq': 584, 'predicted_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 12, 'freq': 0}, {'edge_to_bb_id': 11, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 12, 'freq': 214}, {'edge_to_bb_id': 11, 'freq': 370}]}, {'bb_id': 11, 'freq': 370, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 370}]}, {'bb_id': 12, 'freq': 214, 'predicted_edges': [{'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 13, 'freq': 214}]}, {'bb_id': 13, 'freq': 214, 'predicted_edges': [{'edge_to_bb_id': 14, 'freq': 0}, {'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 14, 'freq': 213}, {'edge_to_bb_id': 13, 'freq': 0}]}, {'bb_id': 14, 'freq': 213, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 213}]}, {'bb_id': 15, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 19, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 19, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}]}, {'bb_id': 16, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 18, 'freq': 0}, {'edge_to_bb_id': 17, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 18, 'freq': 0}, {'edge_to_bb_id': 17, 'freq': 0}]}, {'bb_id': 17, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 16, 'freq': 0}]}, {'bb_id': 18, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 19, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 19, 'freq': 0}]}, {'bb_id': 19, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 21, 'freq': 0}, {'edge_to_bb_id': 20, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 21, 'freq': 0}, {'edge_to_bb_id': 20, 'freq': 0}]}, {'bb_id': 20, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 21, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 21, 'freq': 0}]}, {'bb_id': 21, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 0}]}, {'bb_id': 22, 'freq': 0, 'predicted_edges': [], 'actual_edges': []}]} +2024-12-05 15:49:44 - {'cfg_bbs': [{'bb_id': 0, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 2, 'freq': 0}, {'edge_to_bb_id': 1, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 2, 'freq': 1}, {'edge_to_bb_id': 1, 'freq': 0}]}, {'bb_id': 1, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 0}]}, {'bb_id': 2, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 1}]}, {'bb_id': 3, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 5, 'freq': 0}, {'edge_to_bb_id': 4, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 5, 'freq': 1}, {'edge_to_bb_id': 4, 'freq': 0}]}, {'bb_id': 4, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 0}]}, {'bb_id': 5, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 1}]}, {'bb_id': 6, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 7, 'freq': 1}]}, {'bb_id': 7, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 8, 'freq': 0}, {'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 8, 'freq': 1}, {'edge_to_bb_id': 7, 'freq': 0}]}, {'bb_id': 8, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 1}]}, {'bb_id': 9, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 1}]}, {'bb_id': 10, 'freq': 767, 'predicted_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 12, 'freq': 0}, {'edge_to_bb_id': 11, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 12, 'freq': 397}, {'edge_to_bb_id': 11, 'freq': 370}]}, {'bb_id': 11, 'freq': 370, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 370}]}, {'bb_id': 12, 'freq': 397, 'predicted_edges': [{'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 13, 'freq': 397}]}, {'bb_id': 13, 'freq': 397, 'predicted_edges': [{'edge_to_bb_id': 14, 'freq': 0}, {'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 14, 'freq': 396}, {'edge_to_bb_id': 13, 'freq': 0}]}, {'bb_id': 14, 'freq': 396, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 396}]}, {'bb_id': 15, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 19, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 19, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}]}, {'bb_id': 16, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 18, 'freq': 0}, {'edge_to_bb_id': 17, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 18, 'freq': 0}, {'edge_to_bb_id': 17, 'freq': 0}]}, {'bb_id': 17, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 16, 'freq': 0}]}, {'bb_id': 18, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 19, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 19, 'freq': 0}]}, {'bb_id': 19, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 21, 'freq': 0}, {'edge_to_bb_id': 20, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 21, 'freq': 0}, {'edge_to_bb_id': 20, 'freq': 0}]}, {'bb_id': 20, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 21, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 21, 'freq': 0}]}, {'bb_id': 21, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 0}]}, {'bb_id': 22, 'freq': 0, 'predicted_edges': [], 'actual_edges': []}]} +2024-12-05 15:50:26 - {'cfg_bbs': [{'bb_id': 0, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 2, 'freq': 0}, {'edge_to_bb_id': 1, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 2, 'freq': 1}, {'edge_to_bb_id': 1, 'freq': 0}]}, {'bb_id': 1, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 0}]}, {'bb_id': 2, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 1}]}, {'bb_id': 3, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 5, 'freq': 0}, {'edge_to_bb_id': 4, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 5, 'freq': 1}, {'edge_to_bb_id': 4, 'freq': 0}]}, {'bb_id': 4, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 0}]}, {'bb_id': 5, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 1}]}, {'bb_id': 6, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 7, 'freq': 1}]}, {'bb_id': 7, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 8, 'freq': 0}, {'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 8, 'freq': 1}, {'edge_to_bb_id': 7, 'freq': 0}]}, {'bb_id': 8, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 1}]}, {'bb_id': 9, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 1}]}, {'bb_id': 10, 'freq': 388, 'predicted_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 12, 'freq': 0}, {'edge_to_bb_id': 11, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 12, 'freq': 18}, {'edge_to_bb_id': 11, 'freq': 370}]}, {'bb_id': 11, 'freq': 370, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 370}]}, {'bb_id': 12, 'freq': 18, 'predicted_edges': [{'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 13, 'freq': 18}]}, {'bb_id': 13, 'freq': 18, 'predicted_edges': [{'edge_to_bb_id': 14, 'freq': 0}, {'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 14, 'freq': 17}, {'edge_to_bb_id': 13, 'freq': 0}]}, {'bb_id': 14, 'freq': 17, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 17}]}, {'bb_id': 15, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 19, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 19, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}]}, {'bb_id': 16, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 18, 'freq': 0}, {'edge_to_bb_id': 17, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 18, 'freq': 0}, {'edge_to_bb_id': 17, 'freq': 0}]}, {'bb_id': 17, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 16, 'freq': 0}]}, {'bb_id': 18, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 19, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 19, 'freq': 0}]}, {'bb_id': 19, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 21, 'freq': 0}, {'edge_to_bb_id': 20, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 21, 'freq': 0}, {'edge_to_bb_id': 20, 'freq': 0}]}, {'bb_id': 20, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 21, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 21, 'freq': 0}]}, {'bb_id': 21, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 0}]}, {'bb_id': 22, 'freq': 0, 'predicted_edges': [], 'actual_edges': []}]} +2024-12-05 15:54:22 - list index out of range +2024-12-05 15:54:22 - Error: list index out of range + 115 | self.curr_variables_lock.acquire() + 116 | for var_name in frame.f_locals["__annotations__"]: + 117 | if var_name == "input_val" and frame.f_locals[var_name] != self.inputs[-1]: + | ^^^^^^^^^^^^^^^ + 118 | self.inputs.append(frame.f_locals[var_name]) + 119 | + at trace_callback() /Users/jakobtherkelsen/Documents/jaseci-ginS/jac/jaclang/runtimelib/gins/tracer.py:117 + at /Users/jakobtherkelsen/Documents/jaseci-ginS/jac/examples/gins_scripts/hot_path.jac:19 +2024-12-05 15:55:37 - {'cfg_bbs': [{'bb_id': 0, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 2, 'freq': 0}, {'edge_to_bb_id': 1, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 2, 'freq': 1}, {'edge_to_bb_id': 1, 'freq': 0}]}, {'bb_id': 1, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 0}]}, {'bb_id': 2, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 1}]}, {'bb_id': 3, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 5, 'freq': 0}, {'edge_to_bb_id': 4, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 5, 'freq': 1}, {'edge_to_bb_id': 4, 'freq': 0}]}, {'bb_id': 4, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 0}]}, {'bb_id': 5, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 1}]}, {'bb_id': 6, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 7, 'freq': 1}]}, {'bb_id': 7, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 8, 'freq': 0}, {'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 8, 'freq': 1}, {'edge_to_bb_id': 7, 'freq': 0}]}, {'bb_id': 8, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 1}]}, {'bb_id': 9, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 1}]}, {'bb_id': 10, 'freq': 558, 'predicted_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 12, 'freq': 0}, {'edge_to_bb_id': 11, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 12, 'freq': 188}, {'edge_to_bb_id': 11, 'freq': 370}]}, {'bb_id': 11, 'freq': 370, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 370}]}, {'bb_id': 12, 'freq': 188, 'predicted_edges': [{'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 13, 'freq': 188}]}, {'bb_id': 13, 'freq': 188, 'predicted_edges': [{'edge_to_bb_id': 14, 'freq': 0}, {'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 14, 'freq': 187}, {'edge_to_bb_id': 13, 'freq': 0}]}, {'bb_id': 14, 'freq': 187, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 187}]}, {'bb_id': 15, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 19, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 19, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}]}, {'bb_id': 16, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 18, 'freq': 0}, {'edge_to_bb_id': 17, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 18, 'freq': 0}, {'edge_to_bb_id': 17, 'freq': 0}]}, {'bb_id': 17, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 16, 'freq': 0}]}, {'bb_id': 18, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 19, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 19, 'freq': 0}]}, {'bb_id': 19, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 21, 'freq': 0}, {'edge_to_bb_id': 20, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 21, 'freq': 0}, {'edge_to_bb_id': 20, 'freq': 0}]}, {'bb_id': 20, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 21, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 21, 'freq': 0}]}, {'bb_id': 21, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 0}]}, {'bb_id': 22, 'freq': 0, 'predicted_edges': [], 'actual_edges': []}]} +2024-12-05 15:55:43 - {'cfg_bbs': [{'bb_id': 0, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 2, 'freq': 0}, {'edge_to_bb_id': 1, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 2, 'freq': 1}, {'edge_to_bb_id': 1, 'freq': 0}]}, {'bb_id': 1, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 0}]}, {'bb_id': 2, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 1}]}, {'bb_id': 3, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 5, 'freq': 0}, {'edge_to_bb_id': 4, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 5, 'freq': 1}, {'edge_to_bb_id': 4, 'freq': 0}]}, {'bb_id': 4, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 0}]}, {'bb_id': 5, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 1}]}, {'bb_id': 6, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 7, 'freq': 1}]}, {'bb_id': 7, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 8, 'freq': 0}, {'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 8, 'freq': 1}, {'edge_to_bb_id': 7, 'freq': 0}]}, {'bb_id': 8, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 1}]}, {'bb_id': 9, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 1}]}, {'bb_id': 10, 'freq': 750, 'predicted_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 12, 'freq': 0}, {'edge_to_bb_id': 11, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 12, 'freq': 380}, {'edge_to_bb_id': 11, 'freq': 370}]}, {'bb_id': 11, 'freq': 370, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 370}]}, {'bb_id': 12, 'freq': 380, 'predicted_edges': [{'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 13, 'freq': 380}]}, {'bb_id': 13, 'freq': 380, 'predicted_edges': [{'edge_to_bb_id': 14, 'freq': 0}, {'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 14, 'freq': 379}, {'edge_to_bb_id': 13, 'freq': 0}]}, {'bb_id': 14, 'freq': 379, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 379}]}, {'bb_id': 15, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 19, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 19, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}]}, {'bb_id': 16, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 18, 'freq': 0}, {'edge_to_bb_id': 17, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 18, 'freq': 0}, {'edge_to_bb_id': 17, 'freq': 0}]}, {'bb_id': 17, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 16, 'freq': 0}]}, {'bb_id': 18, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 19, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 19, 'freq': 0}]}, {'bb_id': 19, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 21, 'freq': 0}, {'edge_to_bb_id': 20, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 21, 'freq': 0}, {'edge_to_bb_id': 20, 'freq': 0}]}, {'bb_id': 20, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 21, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 21, 'freq': 0}]}, {'bb_id': 21, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 0}]}, {'bb_id': 22, 'freq': 0, 'predicted_edges': [], 'actual_edges': []}]} +2024-12-05 15:56:25 - {'cfg_bbs': [{'bb_id': 0, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 2, 'freq': 0}, {'edge_to_bb_id': 1, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 2, 'freq': 1}, {'edge_to_bb_id': 1, 'freq': 0}]}, {'bb_id': 1, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 0}]}, {'bb_id': 2, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 1}]}, {'bb_id': 3, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 5, 'freq': 0}, {'edge_to_bb_id': 4, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 5, 'freq': 1}, {'edge_to_bb_id': 4, 'freq': 0}]}, {'bb_id': 4, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 0}]}, {'bb_id': 5, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 1}]}, {'bb_id': 6, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 7, 'freq': 1}]}, {'bb_id': 7, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 8, 'freq': 0}, {'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 8, 'freq': 1}, {'edge_to_bb_id': 7, 'freq': 0}]}, {'bb_id': 8, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 1}]}, {'bb_id': 9, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 1}]}, {'bb_id': 10, 'freq': 555, 'predicted_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 12, 'freq': 0}, {'edge_to_bb_id': 11, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 12, 'freq': 185}, {'edge_to_bb_id': 11, 'freq': 370}]}, {'bb_id': 11, 'freq': 370, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 370}]}, {'bb_id': 12, 'freq': 185, 'predicted_edges': [{'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 13, 'freq': 185}]}, {'bb_id': 13, 'freq': 185, 'predicted_edges': [{'edge_to_bb_id': 14, 'freq': 0}, {'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 14, 'freq': 184}, {'edge_to_bb_id': 13, 'freq': 0}]}, {'bb_id': 14, 'freq': 184, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 184}]}, {'bb_id': 15, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 19, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 19, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}]}, {'bb_id': 16, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 18, 'freq': 0}, {'edge_to_bb_id': 17, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 18, 'freq': 0}, {'edge_to_bb_id': 17, 'freq': 0}]}, {'bb_id': 17, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 16, 'freq': 0}]}, {'bb_id': 18, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 19, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 19, 'freq': 0}]}, {'bb_id': 19, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 21, 'freq': 0}, {'edge_to_bb_id': 20, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 21, 'freq': 0}, {'edge_to_bb_id': 20, 'freq': 0}]}, {'bb_id': 20, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 21, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 21, 'freq': 0}]}, {'bb_id': 21, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 0}]}, {'bb_id': 22, 'freq': 0, 'predicted_edges': [], 'actual_edges': []}]} +2024-12-05 15:56:31 - {'cfg_bbs': [{'bb_id': 0, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 2, 'freq': 0}, {'edge_to_bb_id': 1, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 2, 'freq': 1}, {'edge_to_bb_id': 1, 'freq': 0}]}, {'bb_id': 1, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 0}]}, {'bb_id': 2, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 1}]}, {'bb_id': 3, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 5, 'freq': 0}, {'edge_to_bb_id': 4, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 5, 'freq': 1}, {'edge_to_bb_id': 4, 'freq': 0}]}, {'bb_id': 4, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 0}]}, {'bb_id': 5, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 1}]}, {'bb_id': 6, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 7, 'freq': 1}]}, {'bb_id': 7, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 8, 'freq': 0}, {'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 8, 'freq': 1}, {'edge_to_bb_id': 7, 'freq': 0}]}, {'bb_id': 8, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 1}]}, {'bb_id': 9, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 1}]}, {'bb_id': 10, 'freq': 728, 'predicted_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 12, 'freq': 0}, {'edge_to_bb_id': 11, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 12, 'freq': 358}, {'edge_to_bb_id': 11, 'freq': 370}]}, {'bb_id': 11, 'freq': 370, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 370}]}, {'bb_id': 12, 'freq': 358, 'predicted_edges': [{'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 13, 'freq': 358}]}, {'bb_id': 13, 'freq': 358, 'predicted_edges': [{'edge_to_bb_id': 14, 'freq': 0}, {'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 14, 'freq': 357}, {'edge_to_bb_id': 13, 'freq': 0}]}, {'bb_id': 14, 'freq': 357, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 357}]}, {'bb_id': 15, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 19, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 19, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}]}, {'bb_id': 16, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 18, 'freq': 0}, {'edge_to_bb_id': 17, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 18, 'freq': 0}, {'edge_to_bb_id': 17, 'freq': 0}]}, {'bb_id': 17, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 16, 'freq': 0}]}, {'bb_id': 18, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 19, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 19, 'freq': 0}]}, {'bb_id': 19, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 21, 'freq': 0}, {'edge_to_bb_id': 20, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 21, 'freq': 0}, {'edge_to_bb_id': 20, 'freq': 0}]}, {'bb_id': 20, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 21, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 21, 'freq': 0}]}, {'bb_id': 21, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 0}]}, {'bb_id': 22, 'freq': 0, 'predicted_edges': [], 'actual_edges': []}]} +2024-12-05 15:56:37 - {'cfg_bbs': [{'bb_id': 0, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 2, 'freq': 0}, {'edge_to_bb_id': 1, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 2, 'freq': 1}, {'edge_to_bb_id': 1, 'freq': 0}]}, {'bb_id': 1, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 0}]}, {'bb_id': 2, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 1}]}, {'bb_id': 3, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 5, 'freq': 0}, {'edge_to_bb_id': 4, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 5, 'freq': 1}, {'edge_to_bb_id': 4, 'freq': 0}]}, {'bb_id': 4, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 0}]}, {'bb_id': 5, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 1}]}, {'bb_id': 6, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 7, 'freq': 1}]}, {'bb_id': 7, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 8, 'freq': 0}, {'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 8, 'freq': 1}, {'edge_to_bb_id': 7, 'freq': 0}]}, {'bb_id': 8, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 1}]}, {'bb_id': 9, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 1}]}, {'bb_id': 10, 'freq': 873, 'predicted_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 12, 'freq': 0}, {'edge_to_bb_id': 11, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 12, 'freq': 503}, {'edge_to_bb_id': 11, 'freq': 370}]}, {'bb_id': 11, 'freq': 370, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 370}]}, {'bb_id': 12, 'freq': 503, 'predicted_edges': [{'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 13, 'freq': 503}]}, {'bb_id': 13, 'freq': 503, 'predicted_edges': [{'edge_to_bb_id': 14, 'freq': 0}, {'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 14, 'freq': 502}, {'edge_to_bb_id': 13, 'freq': 0}]}, {'bb_id': 14, 'freq': 502, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 502}]}, {'bb_id': 15, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 19, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 19, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}]}, {'bb_id': 16, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 18, 'freq': 0}, {'edge_to_bb_id': 17, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 18, 'freq': 0}, {'edge_to_bb_id': 17, 'freq': 0}]}, {'bb_id': 17, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 16, 'freq': 0}]}, {'bb_id': 18, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 19, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 19, 'freq': 0}]}, {'bb_id': 19, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 21, 'freq': 0}, {'edge_to_bb_id': 20, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 21, 'freq': 0}, {'edge_to_bb_id': 20, 'freq': 0}]}, {'bb_id': 20, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 21, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 21, 'freq': 0}]}, {'bb_id': 21, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 0}]}, {'bb_id': 22, 'freq': 0, 'predicted_edges': [], 'actual_edges': []}]} +2024-12-05 15:56:43 - {'cfg_bbs': [{'bb_id': 0, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 2, 'freq': 0}, {'edge_to_bb_id': 1, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 2, 'freq': 1}, {'edge_to_bb_id': 1, 'freq': 0}]}, {'bb_id': 1, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 0}]}, {'bb_id': 2, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 1}]}, {'bb_id': 3, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 5, 'freq': 0}, {'edge_to_bb_id': 4, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 5, 'freq': 1}, {'edge_to_bb_id': 4, 'freq': 0}]}, {'bb_id': 4, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 0}]}, {'bb_id': 5, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 1}]}, {'bb_id': 6, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 7, 'freq': 1}]}, {'bb_id': 7, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 8, 'freq': 0}, {'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 8, 'freq': 1}, {'edge_to_bb_id': 7, 'freq': 0}]}, {'bb_id': 8, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 1}]}, {'bb_id': 9, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 1}]}, {'bb_id': 10, 'freq': 996, 'predicted_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 12, 'freq': 0}, {'edge_to_bb_id': 11, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 12, 'freq': 626}, {'edge_to_bb_id': 11, 'freq': 370}]}, {'bb_id': 11, 'freq': 370, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 370}]}, {'bb_id': 12, 'freq': 626, 'predicted_edges': [{'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 13, 'freq': 626}]}, {'bb_id': 13, 'freq': 626, 'predicted_edges': [{'edge_to_bb_id': 14, 'freq': 0}, {'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 14, 'freq': 625}, {'edge_to_bb_id': 13, 'freq': 0}]}, {'bb_id': 14, 'freq': 625, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 625}]}, {'bb_id': 15, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 19, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 19, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}]}, {'bb_id': 16, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 18, 'freq': 0}, {'edge_to_bb_id': 17, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 18, 'freq': 0}, {'edge_to_bb_id': 17, 'freq': 0}]}, {'bb_id': 17, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 16, 'freq': 0}]}, {'bb_id': 18, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 19, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 19, 'freq': 0}]}, {'bb_id': 19, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 21, 'freq': 0}, {'edge_to_bb_id': 20, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 21, 'freq': 0}, {'edge_to_bb_id': 20, 'freq': 0}]}, {'bb_id': 20, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 21, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 21, 'freq': 0}]}, {'bb_id': 21, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 0}]}, {'bb_id': 22, 'freq': 0, 'predicted_edges': [], 'actual_edges': []}]} +2024-12-05 15:57:13 - {'cfg_bbs': [{'bb_id': 0, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 2, 'freq': 0}, {'edge_to_bb_id': 1, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 2, 'freq': 1}, {'edge_to_bb_id': 1, 'freq': 0}]}, {'bb_id': 1, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 0}]}, {'bb_id': 2, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 1}]}, {'bb_id': 3, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 5, 'freq': 0}, {'edge_to_bb_id': 4, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 5, 'freq': 1}, {'edge_to_bb_id': 4, 'freq': 0}]}, {'bb_id': 4, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 0}]}, {'bb_id': 5, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 1}]}, {'bb_id': 6, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 7, 'freq': 1}]}, {'bb_id': 7, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 8, 'freq': 0}, {'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 8, 'freq': 1}, {'edge_to_bb_id': 7, 'freq': 0}]}, {'bb_id': 8, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 1}]}, {'bb_id': 9, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 1}]}, {'bb_id': 10, 'freq': 558, 'predicted_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 12, 'freq': 0}, {'edge_to_bb_id': 11, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 12, 'freq': 188}, {'edge_to_bb_id': 11, 'freq': 370}]}, {'bb_id': 11, 'freq': 370, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 370}]}, {'bb_id': 12, 'freq': 188, 'predicted_edges': [{'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 13, 'freq': 188}]}, {'bb_id': 13, 'freq': 188, 'predicted_edges': [{'edge_to_bb_id': 14, 'freq': 0}, {'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 14, 'freq': 187}, {'edge_to_bb_id': 13, 'freq': 0}]}, {'bb_id': 14, 'freq': 187, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 187}]}, {'bb_id': 15, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 19, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 19, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}]}, {'bb_id': 16, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 18, 'freq': 0}, {'edge_to_bb_id': 17, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 18, 'freq': 0}, {'edge_to_bb_id': 17, 'freq': 0}]}, {'bb_id': 17, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 16, 'freq': 0}]}, {'bb_id': 18, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 19, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 19, 'freq': 0}]}, {'bb_id': 19, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 21, 'freq': 0}, {'edge_to_bb_id': 20, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 21, 'freq': 0}, {'edge_to_bb_id': 20, 'freq': 0}]}, {'bb_id': 20, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 21, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 21, 'freq': 0}]}, {'bb_id': 21, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 0}]}, {'bb_id': 22, 'freq': 0, 'predicted_edges': [], 'actual_edges': []}]} +2024-12-05 15:57:19 - {'cfg_bbs': [{'bb_id': 0, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 2, 'freq': 0}, {'edge_to_bb_id': 1, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 2, 'freq': 1}, {'edge_to_bb_id': 1, 'freq': 0}]}, {'bb_id': 1, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 0}]}, {'bb_id': 2, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 1}]}, {'bb_id': 3, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 5, 'freq': 0}, {'edge_to_bb_id': 4, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 5, 'freq': 1}, {'edge_to_bb_id': 4, 'freq': 0}]}, {'bb_id': 4, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 0}]}, {'bb_id': 5, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 1}]}, {'bb_id': 6, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 7, 'freq': 1}]}, {'bb_id': 7, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 8, 'freq': 0}, {'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 8, 'freq': 1}, {'edge_to_bb_id': 7, 'freq': 0}]}, {'bb_id': 8, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 1}]}, {'bb_id': 9, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 1}]}, {'bb_id': 10, 'freq': 732, 'predicted_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 12, 'freq': 0}, {'edge_to_bb_id': 11, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 12, 'freq': 362}, {'edge_to_bb_id': 11, 'freq': 370}]}, {'bb_id': 11, 'freq': 370, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 370}]}, {'bb_id': 12, 'freq': 362, 'predicted_edges': [{'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 13, 'freq': 362}]}, {'bb_id': 13, 'freq': 362, 'predicted_edges': [{'edge_to_bb_id': 14, 'freq': 0}, {'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 14, 'freq': 361}, {'edge_to_bb_id': 13, 'freq': 0}]}, {'bb_id': 14, 'freq': 361, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 361}]}, {'bb_id': 15, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 19, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 19, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}]}, {'bb_id': 16, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 18, 'freq': 0}, {'edge_to_bb_id': 17, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 18, 'freq': 0}, {'edge_to_bb_id': 17, 'freq': 0}]}, {'bb_id': 17, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 16, 'freq': 0}]}, {'bb_id': 18, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 19, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 19, 'freq': 0}]}, {'bb_id': 19, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 21, 'freq': 0}, {'edge_to_bb_id': 20, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 21, 'freq': 0}, {'edge_to_bb_id': 20, 'freq': 0}]}, {'bb_id': 20, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 21, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 21, 'freq': 0}]}, {'bb_id': 21, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 0}]}, {'bb_id': 22, 'freq': 0, 'predicted_edges': [], 'actual_edges': []}]} +2024-12-05 15:57:25 - {'cfg_bbs': [{'bb_id': 0, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 2, 'freq': 0}, {'edge_to_bb_id': 1, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 2, 'freq': 1}, {'edge_to_bb_id': 1, 'freq': 0}]}, {'bb_id': 1, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 0}]}, {'bb_id': 2, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 1}]}, {'bb_id': 3, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 5, 'freq': 0}, {'edge_to_bb_id': 4, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 5, 'freq': 1}, {'edge_to_bb_id': 4, 'freq': 0}]}, {'bb_id': 4, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 0}]}, {'bb_id': 5, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 1}]}, {'bb_id': 6, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 7, 'freq': 1}]}, {'bb_id': 7, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 8, 'freq': 0}, {'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 8, 'freq': 1}, {'edge_to_bb_id': 7, 'freq': 0}]}, {'bb_id': 8, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 1}]}, {'bb_id': 9, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 1}]}, {'bb_id': 10, 'freq': 878, 'predicted_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 12, 'freq': 0}, {'edge_to_bb_id': 11, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 12, 'freq': 508}, {'edge_to_bb_id': 11, 'freq': 370}]}, {'bb_id': 11, 'freq': 370, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 370}]}, {'bb_id': 12, 'freq': 508, 'predicted_edges': [{'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 13, 'freq': 508}]}, {'bb_id': 13, 'freq': 508, 'predicted_edges': [{'edge_to_bb_id': 14, 'freq': 0}, {'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 14, 'freq': 507}, {'edge_to_bb_id': 13, 'freq': 0}]}, {'bb_id': 14, 'freq': 507, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 507}]}, {'bb_id': 15, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 19, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 19, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}]}, {'bb_id': 16, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 18, 'freq': 0}, {'edge_to_bb_id': 17, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 18, 'freq': 0}, {'edge_to_bb_id': 17, 'freq': 0}]}, {'bb_id': 17, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 16, 'freq': 0}]}, {'bb_id': 18, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 19, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 19, 'freq': 0}]}, {'bb_id': 19, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 21, 'freq': 0}, {'edge_to_bb_id': 20, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 21, 'freq': 0}, {'edge_to_bb_id': 20, 'freq': 0}]}, {'bb_id': 20, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 21, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 21, 'freq': 0}]}, {'bb_id': 21, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 0}]}, {'bb_id': 22, 'freq': 0, 'predicted_edges': [], 'actual_edges': []}]} +2024-12-05 15:57:31 - {'cfg_bbs': [{'bb_id': 0, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 2, 'freq': 0}, {'edge_to_bb_id': 1, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 2, 'freq': 1}, {'edge_to_bb_id': 1, 'freq': 0}]}, {'bb_id': 1, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 0}]}, {'bb_id': 2, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 1}]}, {'bb_id': 3, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 5, 'freq': 0}, {'edge_to_bb_id': 4, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 5, 'freq': 1}, {'edge_to_bb_id': 4, 'freq': 0}]}, {'bb_id': 4, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 0}]}, {'bb_id': 5, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 1}]}, {'bb_id': 6, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 7, 'freq': 1}]}, {'bb_id': 7, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 8, 'freq': 0}, {'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 8, 'freq': 1}, {'edge_to_bb_id': 7, 'freq': 0}]}, {'bb_id': 8, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 1}]}, {'bb_id': 9, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 1}]}, {'bb_id': 10, 'freq': 1001, 'predicted_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 12, 'freq': 0}, {'edge_to_bb_id': 11, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 15, 'freq': 1}, {'edge_to_bb_id': 12, 'freq': 630}, {'edge_to_bb_id': 11, 'freq': 370}]}, {'bb_id': 11, 'freq': 370, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 370}]}, {'bb_id': 12, 'freq': 630, 'predicted_edges': [{'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 13, 'freq': 630}]}, {'bb_id': 13, 'freq': 630, 'predicted_edges': [{'edge_to_bb_id': 14, 'freq': 0}, {'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 14, 'freq': 630}, {'edge_to_bb_id': 13, 'freq': 0}]}, {'bb_id': 14, 'freq': 630, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 630}]}, {'bb_id': 15, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 19, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 19, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 1}]}, {'bb_id': 16, 'freq': 725, 'predicted_edges': [{'edge_to_bb_id': 18, 'freq': 0}, {'edge_to_bb_id': 17, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 18, 'freq': 0}, {'edge_to_bb_id': 17, 'freq': 724}]}, {'bb_id': 17, 'freq': 724, 'predicted_edges': [{'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 16, 'freq': 724}]}, {'bb_id': 18, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 19, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 19, 'freq': 0}]}, {'bb_id': 19, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 21, 'freq': 0}, {'edge_to_bb_id': 20, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 21, 'freq': 0}, {'edge_to_bb_id': 20, 'freq': 0}]}, {'bb_id': 20, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 21, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 21, 'freq': 0}]}, {'bb_id': 21, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 0}]}, {'bb_id': 22, 'freq': 0, 'predicted_edges': [], 'actual_edges': []}]} +2024-12-05 15:57:36 - {'cfg_bbs': [{'bb_id': 0, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 2, 'freq': 0}, {'edge_to_bb_id': 1, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 2, 'freq': 1}, {'edge_to_bb_id': 1, 'freq': 0}]}, {'bb_id': 1, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 0}]}, {'bb_id': 2, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 1}]}, {'bb_id': 3, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 5, 'freq': 0}, {'edge_to_bb_id': 4, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 5, 'freq': 1}, {'edge_to_bb_id': 4, 'freq': 0}]}, {'bb_id': 4, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 0}]}, {'bb_id': 5, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 1}]}, {'bb_id': 6, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 7, 'freq': 1}]}, {'bb_id': 7, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 8, 'freq': 0}, {'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 8, 'freq': 1}, {'edge_to_bb_id': 7, 'freq': 0}]}, {'bb_id': 8, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 1}]}, {'bb_id': 9, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 1}]}, {'bb_id': 10, 'freq': 1001, 'predicted_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 12, 'freq': 0}, {'edge_to_bb_id': 11, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 15, 'freq': 1}, {'edge_to_bb_id': 12, 'freq': 630}, {'edge_to_bb_id': 11, 'freq': 370}]}, {'bb_id': 11, 'freq': 370, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 370}]}, {'bb_id': 12, 'freq': 630, 'predicted_edges': [{'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 13, 'freq': 630}]}, {'bb_id': 13, 'freq': 630, 'predicted_edges': [{'edge_to_bb_id': 14, 'freq': 0}, {'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 14, 'freq': 630}, {'edge_to_bb_id': 13, 'freq': 0}]}, {'bb_id': 14, 'freq': 630, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 630}]}, {'bb_id': 15, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 19, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 19, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 1}]}, {'bb_id': 16, 'freq': 40569, 'predicted_edges': [{'edge_to_bb_id': 18, 'freq': 0}, {'edge_to_bb_id': 17, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 18, 'freq': 0}, {'edge_to_bb_id': 17, 'freq': 40569}]}, {'bb_id': 17, 'freq': 40569, 'predicted_edges': [{'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 16, 'freq': 40568}]}, {'bb_id': 18, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 19, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 19, 'freq': 0}]}, {'bb_id': 19, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 21, 'freq': 0}, {'edge_to_bb_id': 20, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 21, 'freq': 0}, {'edge_to_bb_id': 20, 'freq': 0}]}, {'bb_id': 20, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 21, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 21, 'freq': 0}]}, {'bb_id': 21, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 0}]}, {'bb_id': 22, 'freq': 0, 'predicted_edges': [], 'actual_edges': []}]} +2024-12-05 15:57:36 - {'cfg_bbs': [{'bb_id': 0, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 2, 'freq': 0}, {'edge_to_bb_id': 1, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 2, 'freq': 1}, {'edge_to_bb_id': 1, 'freq': 0}]}, {'bb_id': 1, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 0}]}, {'bb_id': 2, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 1}]}, {'bb_id': 3, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 5, 'freq': 0}, {'edge_to_bb_id': 4, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 5, 'freq': 1}, {'edge_to_bb_id': 4, 'freq': 0}]}, {'bb_id': 4, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 0}]}, {'bb_id': 5, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 1}]}, {'bb_id': 6, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 7, 'freq': 1}]}, {'bb_id': 7, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 8, 'freq': 0}, {'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 8, 'freq': 1}, {'edge_to_bb_id': 7, 'freq': 0}]}, {'bb_id': 8, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 1}]}, {'bb_id': 9, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 1}]}, {'bb_id': 10, 'freq': 1001, 'predicted_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 12, 'freq': 0}, {'edge_to_bb_id': 11, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 15, 'freq': 1}, {'edge_to_bb_id': 12, 'freq': 630}, {'edge_to_bb_id': 11, 'freq': 370}]}, {'bb_id': 11, 'freq': 370, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 370}]}, {'bb_id': 12, 'freq': 630, 'predicted_edges': [{'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 13, 'freq': 630}]}, {'bb_id': 13, 'freq': 630, 'predicted_edges': [{'edge_to_bb_id': 14, 'freq': 0}, {'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 14, 'freq': 630}, {'edge_to_bb_id': 13, 'freq': 0}]}, {'bb_id': 14, 'freq': 630, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 630}]}, {'bb_id': 15, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 19, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 19, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 1}]}, {'bb_id': 16, 'freq': 43557, 'predicted_edges': [{'edge_to_bb_id': 18, 'freq': 0}, {'edge_to_bb_id': 17, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 18, 'freq': 1}, {'edge_to_bb_id': 17, 'freq': 43556}]}, {'bb_id': 17, 'freq': 43556, 'predicted_edges': [{'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 16, 'freq': 43556}]}, {'bb_id': 18, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 19, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 19, 'freq': 0}]}, {'bb_id': 19, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 21, 'freq': 0}, {'edge_to_bb_id': 20, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 21, 'freq': 0}, {'edge_to_bb_id': 20, 'freq': 0}]}, {'bb_id': 20, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 21, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 21, 'freq': 0}]}, {'bb_id': 21, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 0}]}, {'bb_id': 22, 'freq': 0, 'predicted_edges': [], 'actual_edges': []}]} +2024-12-05 15:58:15 - {'cfg_bbs': [{'bb_id': 0, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 2, 'freq': 0}, {'edge_to_bb_id': 1, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 2, 'freq': 1}, {'edge_to_bb_id': 1, 'freq': 0}]}, {'bb_id': 1, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 0}]}, {'bb_id': 2, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 1}]}, {'bb_id': 3, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 5, 'freq': 0}, {'edge_to_bb_id': 4, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 5, 'freq': 1}, {'edge_to_bb_id': 4, 'freq': 0}]}, {'bb_id': 4, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 0}]}, {'bb_id': 5, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 1}]}, {'bb_id': 6, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 7, 'freq': 1}]}, {'bb_id': 7, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 8, 'freq': 0}, {'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 8, 'freq': 1}, {'edge_to_bb_id': 7, 'freq': 0}]}, {'bb_id': 8, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 1}]}, {'bb_id': 9, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 1}]}, {'bb_id': 10, 'freq': 556, 'predicted_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 12, 'freq': 0}, {'edge_to_bb_id': 11, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 12, 'freq': 186}, {'edge_to_bb_id': 11, 'freq': 370}]}, {'bb_id': 11, 'freq': 370, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 370}]}, {'bb_id': 12, 'freq': 186, 'predicted_edges': [{'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 13, 'freq': 186}]}, {'bb_id': 13, 'freq': 186, 'predicted_edges': [{'edge_to_bb_id': 14, 'freq': 0}, {'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 14, 'freq': 185}, {'edge_to_bb_id': 13, 'freq': 0}]}, {'bb_id': 14, 'freq': 185, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 185}]}, {'bb_id': 15, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 19, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 19, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}]}, {'bb_id': 16, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 18, 'freq': 0}, {'edge_to_bb_id': 17, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 18, 'freq': 0}, {'edge_to_bb_id': 17, 'freq': 0}]}, {'bb_id': 17, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 16, 'freq': 0}]}, {'bb_id': 18, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 19, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 19, 'freq': 0}]}, {'bb_id': 19, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 21, 'freq': 0}, {'edge_to_bb_id': 20, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 21, 'freq': 0}, {'edge_to_bb_id': 20, 'freq': 0}]}, {'bb_id': 20, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 21, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 21, 'freq': 0}]}, {'bb_id': 21, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 0}]}, {'bb_id': 22, 'freq': 0, 'predicted_edges': [], 'actual_edges': []}]} +2024-12-05 15:58:21 - {'cfg_bbs': [{'bb_id': 0, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 2, 'freq': 0}, {'edge_to_bb_id': 1, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 2, 'freq': 1}, {'edge_to_bb_id': 1, 'freq': 0}]}, {'bb_id': 1, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 0}]}, {'bb_id': 2, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 1}]}, {'bb_id': 3, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 5, 'freq': 0}, {'edge_to_bb_id': 4, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 5, 'freq': 1}, {'edge_to_bb_id': 4, 'freq': 0}]}, {'bb_id': 4, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 0}]}, {'bb_id': 5, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 1}]}, {'bb_id': 6, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 7, 'freq': 1}]}, {'bb_id': 7, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 8, 'freq': 0}, {'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 8, 'freq': 1}, {'edge_to_bb_id': 7, 'freq': 0}]}, {'bb_id': 8, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 1}]}, {'bb_id': 9, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 1}]}, {'bb_id': 10, 'freq': 729, 'predicted_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 12, 'freq': 0}, {'edge_to_bb_id': 11, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 12, 'freq': 359}, {'edge_to_bb_id': 11, 'freq': 370}]}, {'bb_id': 11, 'freq': 370, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 370}]}, {'bb_id': 12, 'freq': 359, 'predicted_edges': [{'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 13, 'freq': 359}]}, {'bb_id': 13, 'freq': 359, 'predicted_edges': [{'edge_to_bb_id': 14, 'freq': 0}, {'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 14, 'freq': 358}, {'edge_to_bb_id': 13, 'freq': 0}]}, {'bb_id': 14, 'freq': 358, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 358}]}, {'bb_id': 15, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 19, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 19, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}]}, {'bb_id': 16, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 18, 'freq': 0}, {'edge_to_bb_id': 17, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 18, 'freq': 0}, {'edge_to_bb_id': 17, 'freq': 0}]}, {'bb_id': 17, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 16, 'freq': 0}]}, {'bb_id': 18, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 19, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 19, 'freq': 0}]}, {'bb_id': 19, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 21, 'freq': 0}, {'edge_to_bb_id': 20, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 21, 'freq': 0}, {'edge_to_bb_id': 20, 'freq': 0}]}, {'bb_id': 20, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 21, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 21, 'freq': 0}]}, {'bb_id': 21, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 0}]}, {'bb_id': 22, 'freq': 0, 'predicted_edges': [], 'actual_edges': []}]} +2024-12-05 15:58:27 - {'cfg_bbs': [{'bb_id': 0, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 2, 'freq': 0}, {'edge_to_bb_id': 1, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 2, 'freq': 1}, {'edge_to_bb_id': 1, 'freq': 0}]}, {'bb_id': 1, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 0}]}, {'bb_id': 2, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 1}]}, {'bb_id': 3, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 5, 'freq': 0}, {'edge_to_bb_id': 4, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 5, 'freq': 1}, {'edge_to_bb_id': 4, 'freq': 0}]}, {'bb_id': 4, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 0}]}, {'bb_id': 5, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 1}]}, {'bb_id': 6, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 7, 'freq': 1}]}, {'bb_id': 7, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 8, 'freq': 0}, {'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 8, 'freq': 1}, {'edge_to_bb_id': 7, 'freq': 0}]}, {'bb_id': 8, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 1}]}, {'bb_id': 9, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 1}]}, {'bb_id': 10, 'freq': 868, 'predicted_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 12, 'freq': 0}, {'edge_to_bb_id': 11, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 12, 'freq': 498}, {'edge_to_bb_id': 11, 'freq': 370}]}, {'bb_id': 11, 'freq': 370, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 370}]}, {'bb_id': 12, 'freq': 498, 'predicted_edges': [{'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 13, 'freq': 498}]}, {'bb_id': 13, 'freq': 498, 'predicted_edges': [{'edge_to_bb_id': 14, 'freq': 0}, {'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 14, 'freq': 497}, {'edge_to_bb_id': 13, 'freq': 0}]}, {'bb_id': 14, 'freq': 497, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 497}]}, {'bb_id': 15, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 19, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 19, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}]}, {'bb_id': 16, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 18, 'freq': 0}, {'edge_to_bb_id': 17, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 18, 'freq': 0}, {'edge_to_bb_id': 17, 'freq': 0}]}, {'bb_id': 17, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 16, 'freq': 0}]}, {'bb_id': 18, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 19, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 19, 'freq': 0}]}, {'bb_id': 19, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 21, 'freq': 0}, {'edge_to_bb_id': 20, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 21, 'freq': 0}, {'edge_to_bb_id': 20, 'freq': 0}]}, {'bb_id': 20, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 21, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 21, 'freq': 0}]}, {'bb_id': 21, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 0}]}, {'bb_id': 22, 'freq': 0, 'predicted_edges': [], 'actual_edges': []}]} +2024-12-05 15:58:33 - {'cfg_bbs': [{'bb_id': 0, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 2, 'freq': 0}, {'edge_to_bb_id': 1, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 2, 'freq': 1}, {'edge_to_bb_id': 1, 'freq': 0}]}, {'bb_id': 1, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 0}]}, {'bb_id': 2, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 1}]}, {'bb_id': 3, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 5, 'freq': 0}, {'edge_to_bb_id': 4, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 5, 'freq': 1}, {'edge_to_bb_id': 4, 'freq': 0}]}, {'bb_id': 4, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 0}]}, {'bb_id': 5, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 1}]}, {'bb_id': 6, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 7, 'freq': 1}]}, {'bb_id': 7, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 8, 'freq': 0}, {'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 8, 'freq': 1}, {'edge_to_bb_id': 7, 'freq': 0}]}, {'bb_id': 8, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 1}]}, {'bb_id': 9, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 1}]}, {'bb_id': 10, 'freq': 993, 'predicted_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 12, 'freq': 0}, {'edge_to_bb_id': 11, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 12, 'freq': 623}, {'edge_to_bb_id': 11, 'freq': 370}]}, {'bb_id': 11, 'freq': 370, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 370}]}, {'bb_id': 12, 'freq': 623, 'predicted_edges': [{'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 13, 'freq': 623}]}, {'bb_id': 13, 'freq': 623, 'predicted_edges': [{'edge_to_bb_id': 14, 'freq': 0}, {'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 14, 'freq': 622}, {'edge_to_bb_id': 13, 'freq': 0}]}, {'bb_id': 14, 'freq': 622, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 622}]}, {'bb_id': 15, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 19, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 19, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}]}, {'bb_id': 16, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 18, 'freq': 0}, {'edge_to_bb_id': 17, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 18, 'freq': 0}, {'edge_to_bb_id': 17, 'freq': 0}]}, {'bb_id': 17, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 16, 'freq': 0}]}, {'bb_id': 18, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 19, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 19, 'freq': 0}]}, {'bb_id': 19, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 21, 'freq': 0}, {'edge_to_bb_id': 20, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 21, 'freq': 0}, {'edge_to_bb_id': 20, 'freq': 0}]}, {'bb_id': 20, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 21, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 21, 'freq': 0}]}, {'bb_id': 21, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 0}]}, {'bb_id': 22, 'freq': 0, 'predicted_edges': [], 'actual_edges': []}]} +2024-12-05 15:58:39 - {'cfg_bbs': [{'bb_id': 0, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 2, 'freq': 0}, {'edge_to_bb_id': 1, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 2, 'freq': 1}, {'edge_to_bb_id': 1, 'freq': 0}]}, {'bb_id': 1, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 0}]}, {'bb_id': 2, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 1}]}, {'bb_id': 3, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 5, 'freq': 0}, {'edge_to_bb_id': 4, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 5, 'freq': 1}, {'edge_to_bb_id': 4, 'freq': 0}]}, {'bb_id': 4, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 0}]}, {'bb_id': 5, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 1}]}, {'bb_id': 6, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 7, 'freq': 1}]}, {'bb_id': 7, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 8, 'freq': 0}, {'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 8, 'freq': 1}, {'edge_to_bb_id': 7, 'freq': 0}]}, {'bb_id': 8, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 1}]}, {'bb_id': 9, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 1}]}, {'bb_id': 10, 'freq': 1001, 'predicted_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 12, 'freq': 0}, {'edge_to_bb_id': 11, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 15, 'freq': 1}, {'edge_to_bb_id': 12, 'freq': 630}, {'edge_to_bb_id': 11, 'freq': 370}]}, {'bb_id': 11, 'freq': 370, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 370}]}, {'bb_id': 12, 'freq': 630, 'predicted_edges': [{'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 13, 'freq': 630}]}, {'bb_id': 13, 'freq': 630, 'predicted_edges': [{'edge_to_bb_id': 14, 'freq': 0}, {'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 14, 'freq': 630}, {'edge_to_bb_id': 13, 'freq': 0}]}, {'bb_id': 14, 'freq': 630, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 630}]}, {'bb_id': 15, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 19, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 19, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 1}]}, {'bb_id': 16, 'freq': 37418, 'predicted_edges': [{'edge_to_bb_id': 18, 'freq': 0}, {'edge_to_bb_id': 17, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 18, 'freq': 0}, {'edge_to_bb_id': 17, 'freq': 37417}]}, {'bb_id': 17, 'freq': 37417, 'predicted_edges': [{'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 16, 'freq': 37417}]}, {'bb_id': 18, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 19, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 19, 'freq': 0}]}, {'bb_id': 19, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 21, 'freq': 0}, {'edge_to_bb_id': 20, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 21, 'freq': 0}, {'edge_to_bb_id': 20, 'freq': 0}]}, {'bb_id': 20, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 21, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 21, 'freq': 0}]}, {'bb_id': 21, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 0}]}, {'bb_id': 22, 'freq': 0, 'predicted_edges': [], 'actual_edges': []}]} +2024-12-05 15:58:39 - {'cfg_bbs': [{'bb_id': 0, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 2, 'freq': 0}, {'edge_to_bb_id': 1, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 2, 'freq': 1}, {'edge_to_bb_id': 1, 'freq': 0}]}, {'bb_id': 1, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 0}]}, {'bb_id': 2, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 3, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 3, 'freq': 1}]}, {'bb_id': 3, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 5, 'freq': 0}, {'edge_to_bb_id': 4, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 5, 'freq': 1}, {'edge_to_bb_id': 4, 'freq': 0}]}, {'bb_id': 4, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 0}]}, {'bb_id': 5, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 6, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 6, 'freq': 1}]}, {'bb_id': 6, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 7, 'freq': 1}]}, {'bb_id': 7, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 8, 'freq': 0}, {'edge_to_bb_id': 7, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 8, 'freq': 1}, {'edge_to_bb_id': 7, 'freq': 0}]}, {'bb_id': 8, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 1}]}, {'bb_id': 9, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 1}]}, {'bb_id': 10, 'freq': 1001, 'predicted_edges': [{'edge_to_bb_id': 15, 'freq': 0}, {'edge_to_bb_id': 12, 'freq': 0}, {'edge_to_bb_id': 11, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 15, 'freq': 1}, {'edge_to_bb_id': 12, 'freq': 630}, {'edge_to_bb_id': 11, 'freq': 370}]}, {'bb_id': 11, 'freq': 370, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 370}]}, {'bb_id': 12, 'freq': 630, 'predicted_edges': [{'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 13, 'freq': 630}]}, {'bb_id': 13, 'freq': 630, 'predicted_edges': [{'edge_to_bb_id': 14, 'freq': 0}, {'edge_to_bb_id': 13, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 14, 'freq': 630}, {'edge_to_bb_id': 13, 'freq': 0}]}, {'bb_id': 14, 'freq': 630, 'predicted_edges': [{'edge_to_bb_id': 10, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 10, 'freq': 630}]}, {'bb_id': 15, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 19, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 19, 'freq': 0}, {'edge_to_bb_id': 16, 'freq': 1}]}, {'bb_id': 16, 'freq': 43557, 'predicted_edges': [{'edge_to_bb_id': 18, 'freq': 0}, {'edge_to_bb_id': 17, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 18, 'freq': 1}, {'edge_to_bb_id': 17, 'freq': 43556}]}, {'bb_id': 17, 'freq': 43556, 'predicted_edges': [{'edge_to_bb_id': 16, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 16, 'freq': 43556}]}, {'bb_id': 18, 'freq': 1, 'predicted_edges': [{'edge_to_bb_id': 19, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 19, 'freq': 0}]}, {'bb_id': 19, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 21, 'freq': 0}, {'edge_to_bb_id': 20, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 21, 'freq': 0}, {'edge_to_bb_id': 20, 'freq': 0}]}, {'bb_id': 20, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 21, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 21, 'freq': 0}]}, {'bb_id': 21, 'freq': 0, 'predicted_edges': [{'edge_to_bb_id': 9, 'freq': 0}], 'actual_edges': [{'edge_to_bb_id': 9, 'freq': 0}]}, {'bb_id': 22, 'freq': 0, 'predicted_edges': [], 'actual_edges': []}]} diff --git a/jac/jaclang/runtimelib/gins/ghost.py b/jac/jaclang/runtimelib/gins/ghost.py index 8173129529..1f2241b7f2 100644 --- a/jac/jaclang/runtimelib/gins/ghost.py +++ b/jac/jaclang/runtimelib/gins/ghost.py @@ -358,6 +358,7 @@ def update_cfg(): self.variable_values = self.tracker.get_variable_values() self.update_cfg_deque(cfg.get_cfg_repr(), module) self.logger.info(cfg.to_json()) + print(f"CURRENT INPUTS: {self.tracker.get_inputs()}") self.finished_exception_lock.acquire() while not self.finished: diff --git a/jac/jaclang/runtimelib/gins/tracer.py b/jac/jaclang/runtimelib/gins/tracer.py index df81631995..537e32f504 100644 --- a/jac/jaclang/runtimelib/gins/tracer.py +++ b/jac/jaclang/runtimelib/gins/tracer.py @@ -48,6 +48,9 @@ def __init__(self): self.curr_variables_lock = threading.Lock() self.curr_variables = {} + #tracking inputs + self.inputs = [] + def start_tracking(self): """Start tracking branch coverage""" frame = sys._getframe() @@ -66,6 +69,14 @@ def get_exec_inst(self): return cpy + def get_inputs(self): + self.inst_lock.acquire() + cpy = copy.deepcopy(self.inputs) + self.inputs = [] + self.inst_lock.release() + + return cpy + def get_variable_values(self): self.curr_variables_lock.acquire() cpy = copy.deepcopy(self.curr_variables) @@ -73,6 +84,7 @@ def get_variable_values(self): self.curr_variables_lock.release() return cpy + def trace_callback( self, frame: types.FrameType, event: str, arg: any @@ -102,6 +114,9 @@ def trace_callback( if "__annotations__" in frame.f_locals: self.curr_variables_lock.acquire() for var_name in frame.f_locals["__annotations__"]: + if var_name == "input_val" and (len(self.inputs) == 0 or frame.f_locals[var_name] != self.inputs[-1]): + self.inputs.append(frame.f_locals[var_name]) + variable_dict[var_name] = frame.f_locals[var_name] self.curr_variables[module] = (frame.f_lasti, variable_dict) self.curr_variables_lock.release() From b8e4724abad33f98b4804a967aed4ccad0a056bc Mon Sep 17 00:00:00 2001 From: Jona Grodecki Date: Fri, 6 Dec 2024 16:31:24 -0500 Subject: [PATCH 84/84] adding tests with variable hot path iterations and variable iterations --- jac/examples/gins_scripts/acc_itr.jac | 23 ++++++++++++++++++++ jac/examples/gins_scripts/accu_hot_path.jac | 24 +++++++++++++++++++++ jac/examples/gins_scripts/exp_hot_path.jac | 24 +++++++++++++++++++++ jac/examples/gins_scripts/exp_hot_path2.jac | 24 +++++++++++++++++++++ jac/examples/gins_scripts/exp_hot_path3.jac | 24 +++++++++++++++++++++ jac/examples/gins_scripts/exp_itr.jac | 23 ++++++++++++++++++++ jac/examples/gins_scripts/exp_itr2.jac | 23 ++++++++++++++++++++ jac/examples/gins_scripts/exp_itr3.jac | 23 ++++++++++++++++++++ 8 files changed, 188 insertions(+) create mode 100644 jac/examples/gins_scripts/acc_itr.jac create mode 100644 jac/examples/gins_scripts/accu_hot_path.jac create mode 100644 jac/examples/gins_scripts/exp_hot_path.jac create mode 100644 jac/examples/gins_scripts/exp_hot_path2.jac create mode 100644 jac/examples/gins_scripts/exp_hot_path3.jac create mode 100644 jac/examples/gins_scripts/exp_itr.jac create mode 100644 jac/examples/gins_scripts/exp_itr2.jac create mode 100644 jac/examples/gins_scripts/exp_itr3.jac diff --git a/jac/examples/gins_scripts/acc_itr.jac b/jac/examples/gins_scripts/acc_itr.jac new file mode 100644 index 0000000000..2487a8aaa4 --- /dev/null +++ b/jac/examples/gins_scripts/acc_itr.jac @@ -0,0 +1,23 @@ +import:py random; + +with entry { + accu:int = 0; + itr:int = 0; + threshold:int = 500000; + series:list=[]; + meas:list=[0,0,0,0,0,0,0,0,0,0]; + for num in range(10) { + series.append(num + (num + 1)); + } + for i in range(len(series)) { + while itr < (series[i] * 100000) { + if (itr/2 < threshold) { + meas[i] += random.uniform(0.01,0.05); + } + else { + meas[i] -= random.uniform(0.01,0.05); + } + itr += 1; + } + } +} \ No newline at end of file diff --git a/jac/examples/gins_scripts/accu_hot_path.jac b/jac/examples/gins_scripts/accu_hot_path.jac new file mode 100644 index 0000000000..0b8baa10ea --- /dev/null +++ b/jac/examples/gins_scripts/accu_hot_path.jac @@ -0,0 +1,24 @@ +import:py random; + +with entry { + accu:int = 0; + itr:int = 0; + threshold:int = 500000; + series:list=[]; + meas:list=[0,0,0,0,0,0,0,0,0,0]; + for num in range(10) { + series.append(num + (num + 1)); + } + for i in range(len(series)) { + while itr < 100000 { + accu += series[i]; + if (accu < threshold) { + meas[i] += random.uniform(0.01,0.05); + } + else { + meas[i] -= random.uniform(0.01,0.05); + } + itr += 1; + } + } +} \ No newline at end of file diff --git a/jac/examples/gins_scripts/exp_hot_path.jac b/jac/examples/gins_scripts/exp_hot_path.jac new file mode 100644 index 0000000000..be40b16a0a --- /dev/null +++ b/jac/examples/gins_scripts/exp_hot_path.jac @@ -0,0 +1,24 @@ +import:py random; + +with entry { + accu:int = 0; + itr:int = 0; + threshold:int = 500000; + series:list=[]; + meas:list=[0,0,0,0,0,0,0,0,0,0]; + for num in range(10) { + series.append(num * num); + } + for i in range(len(series)){ + while itr < 100000 { + accu += series[i]; + if accu < threshold { + meas[i] += random.uniform(0.01,0.05); + } + else { + meas[i] -= random.uniform(0.01,0.05); + } + itr += 1; + } + } +} \ No newline at end of file diff --git a/jac/examples/gins_scripts/exp_hot_path2.jac b/jac/examples/gins_scripts/exp_hot_path2.jac new file mode 100644 index 0000000000..57cd701c79 --- /dev/null +++ b/jac/examples/gins_scripts/exp_hot_path2.jac @@ -0,0 +1,24 @@ +import:py random; + +with entry { + accu:int = 0; + itr:int = 0; + threshold:int = 500000; + series:list=[]; + meas:list=[0,0,0,0,0,0,0,0,0,0]; + for num in range(10) { + series.append(num * num * num); + } + for i in range(len(series)) { + while itr < 100000 { + accu += series[i]; + if accu < threshold { + meas[i] += random.uniform(0.01,0.05); + } + else { + meas[i] -= random.uniform(0.01,0.05); + } + itr += 1; + } + } +} \ No newline at end of file diff --git a/jac/examples/gins_scripts/exp_hot_path3.jac b/jac/examples/gins_scripts/exp_hot_path3.jac new file mode 100644 index 0000000000..ebaa359925 --- /dev/null +++ b/jac/examples/gins_scripts/exp_hot_path3.jac @@ -0,0 +1,24 @@ +import:py random; + +with entry { + accu:int = 0; + itr:int = 0; + threshold:int = 500000; + series:list=[]; + meas:list=[0,0,0,0,0,0,0,0,0,0]; + for num in range(10) { + series.append(num * num + num); + } + for i in range(len(series)) { + while itr < 100000 { + accu += series[i]; + if accu < threshold { + meas[i] += random.uniform(0.01,0.05); + } + else { + meas[i] -= random.uniform(0.01,0.05); + } + itr += 1; + } + } +} \ No newline at end of file diff --git a/jac/examples/gins_scripts/exp_itr.jac b/jac/examples/gins_scripts/exp_itr.jac new file mode 100644 index 0000000000..e44ae3fbea --- /dev/null +++ b/jac/examples/gins_scripts/exp_itr.jac @@ -0,0 +1,23 @@ +import:py random; + +with entry { + accu:int = 0; + itr:int = 0; + threshold:int = 500000; + series:list=[]; + meas:list=[0,0,0,0,0,0,0,0,0,0]; + for num in range(10) { + series.append(num * num); + } + for i in range(len(series)){ + while itr < (series[i] * 100000) { + if (itr/2 < threshold) { + meas[i] += random.uniform(0.01,0.05); + } + else { + meas[i] -= random.uniform(0.01,0.05); + } + itr += 1; + } + } +} \ No newline at end of file diff --git a/jac/examples/gins_scripts/exp_itr2.jac b/jac/examples/gins_scripts/exp_itr2.jac new file mode 100644 index 0000000000..cf1302750a --- /dev/null +++ b/jac/examples/gins_scripts/exp_itr2.jac @@ -0,0 +1,23 @@ +import:py random; + +with entry { + accu:int = 0; + itr:int = 0; + threshold:int = 500000; + series:list=[]; + meas:list=[0,0,0,0,0,0,0,0,0,0]; + for num in range(10) { + series.append(num * num * num); + } + for i in range(len(series)){ + while itr < (series[i] * 100000) { + if (itr/2 < threshold) { + meas[i] += random.uniform(0.01,0.05); + } + else { + meas[i] -= random.uniform(0.01,0.05); + } + itr += 1; + } + } +} \ No newline at end of file diff --git a/jac/examples/gins_scripts/exp_itr3.jac b/jac/examples/gins_scripts/exp_itr3.jac new file mode 100644 index 0000000000..e0c352bc21 --- /dev/null +++ b/jac/examples/gins_scripts/exp_itr3.jac @@ -0,0 +1,23 @@ +import:py random; + +with entry { + accu:int = 0; + itr:int = 0; + threshold:int = 500000; + series:list=[]; + meas:list=[0,0,0,0,0,0,0,0,0,0]; + for num in range(10) { + series.append(num * num + num); + } + for i in range(len(series)){ + while itr < (series[i] * 100000) { + if (itr/2 < threshold) { + meas[i] += random.uniform(0.01,0.05); + } + else { + meas[i] -= random.uniform(0.01,0.05); + } + itr += 1; + } + } +} \ No newline at end of file