From 47733138a34a5f123cdfcaee55ccbb62ad18c5cc Mon Sep 17 00:00:00 2001 From: Krzysztof Boronski Date: Fri, 27 May 2022 10:15:12 -0500 Subject: [PATCH] Rename symbicache to f4cache Signed-off-by: Krzysztof Boronski --- docs/f4pga/DevNotes.md | 4 +-- docs/f4pga/Usage.md | 8 +++--- f4pga/__init__.py | 59 +++++++++++++++++++++--------------------- f4pga/cache.py | 14 +++++----- 4 files changed, 42 insertions(+), 43 deletions(-) diff --git a/docs/f4pga/DevNotes.md b/docs/f4pga/DevNotes.md index de2ea74..982a928 100644 --- a/docs/f4pga/DevNotes.md +++ b/docs/f4pga/DevNotes.md @@ -58,8 +58,8 @@ particular consumer. This is necessary, because the system tries to avoid rebuil when possible and status of each file (modified/unmodified) may differ in regards to individual stages. -Keeping track of status of each file is done using `SymbiCache` class, which is -defined in `sf_cache.py` file. `SymbiCache` is used mostly inside `Flow`'s methods. +Keeping track of status of each file is done using `F4Cache` class, which is +defined in `cache.py` file. `F4Cache` is used mostly inside `Flow`'s methods. ### Internal environmental variable system diff --git a/docs/f4pga/Usage.md b/docs/f4pga/Usage.md index e4affd2..75b7a8e 100644 --- a/docs/f4pga/Usage.md +++ b/docs/f4pga/Usage.md @@ -71,21 +71,21 @@ file or derived from the paths of the dependencies taken by the module. A *flow* is set of *modules* executed in a right order to produce a *target*. -### .symbicache +### .f4cache All *dependencies* are tracked by a modification tracking system which stores hashes of the files -(directories get always `'0'` hash) in `.symbicache` file in the root of the project. +(directories get always `'0'` hash) in `.f4cache` file in the root of the project. When F4PGA constructs a *flow*, it will try to omit execution of modules which would receive the same data on their input. There is a strong _assumption_ there that a *module*'s output remains unchanged if the input configuration isn't changed, ie. *modules* are deterministic. This is might be not true for some tools and in case you really want to re-run -a stage, there's a `--nocache` option that treats the `.symbicache` file as if it was empty. +a stage, there's a `--nocache` option that treats the `.f4cache` file as if it was empty. ### Resolution A *dependency* is said to be *resolved* if it meets one of the following criteria: -* it exists on persistent storage and its hash matches the one stored in .symbicache +* it exists on persistent storage and its hash matches the one stored in .f4cache * there exists such *flow* that all of the dependencies of its modules are *resolved* and it produces the *dependency* in question. diff --git a/f4pga/__init__.py b/f4pga/__init__.py index ae795a6..4e12d5f 100755 --- a/f4pga/__init__.py +++ b/f4pga/__init__.py @@ -35,7 +35,7 @@ from f4pga.common import ( sub as common_sub ) from f4pga.module import * -from f4pga.cache import SymbiCache +from f4pga.cache import F4Cache from f4pga.flow_config import ( ProjectFlowConfig, FlowConfig, @@ -48,7 +48,7 @@ from f4pga.module_inspector import get_module_info from f4pga.stage import Stage from f4pga.argparser import setup_argparser, get_cli_flow_config -SYMBICACHEPATH = '.symbicache' +F4CACHEPATH = '.f4cache' binpath = str(Path(sys_argv[0]).resolve().parent.parent) mypath = str(Path(__file__).resolve().parent) @@ -109,9 +109,9 @@ def map_outputs_to_stages(stages: 'list[Stage]'): 'provider at most.') return os_map -def filter_existing_deps(deps: 'dict[str, ]', symbicache): +def filter_existing_deps(deps: 'dict[str, ]', f4cache): return [(n, p) for n, p in deps.items() \ - if req_exists(p)] # and not dep_differ(p, symbicache)] + if req_exists(p)] # and not dep_differ(p, f4cache)] def get_stage_values_override(og_values: dict, stage: Stage): values = og_values.copy() @@ -144,35 +144,34 @@ def prepare_stage_input(stage: Stage, values: dict, dep_paths: 'dict[str, ]', return stage_mod_cfg -def update_dep_statuses(paths, consumer: str, symbicache: SymbiCache): +def update_dep_statuses(paths, consumer: str, f4cache: F4Cache): if type(paths) is str: - return symbicache.update(Path(paths), consumer) + return f4cache.update(Path(paths), consumer) elif type(paths) is list: for p in paths: - return update_dep_statuses(p, consumer, symbicache) + return update_dep_statuses(p, consumer, f4cache) elif type(paths) is dict: for _, p in paths.items(): - return update_dep_statuses(p, consumer, symbicache) + return update_dep_statuses(p, consumer, f4cache) fatal(-1, 'WRONG PATHS TYPE') -def dep_differ(paths, consumer: str, symbicache: SymbiCache): +def dep_differ(paths, consumer: str, f4cache: F4Cache): """ Check if a dependency differs from its last version, lack of dependency is treated as "differs" """ if type(paths) is str: - s = symbicache.get_status(paths, consumer) - return symbicache.get_status(paths, consumer) != 'same' + return f4cache.get_status(paths, consumer) != 'same' elif type(paths) is list: - return True in [dep_differ(p, consumer, symbicache) for p in paths] + return True in [dep_differ(p, consumer, f4cache) for p in paths] elif type(paths) is dict: - return True in [dep_differ(p, consumer, symbicache) \ + return True in [dep_differ(p, consumer, f4cache) \ for _, p in paths.items()] return False def dep_will_differ(target: str, paths, consumer: str, os_map: 'dict[str, Stage]', run_stages: 'set[str]', - symbicache: SymbiCache): + f4cache: F4Cache): """ Check if a dependency or any of the dependencies it depends on differ from their last versions. @@ -181,8 +180,8 @@ def dep_will_differ(target: str, paths, consumer: str, provider = os_map.get(target) if provider: return (provider.name in run_stages) or \ - dep_differ(paths, consumer, symbicache) - return dep_differ(paths, consumer, symbicache) + dep_differ(paths, consumer, f4cache) + return dep_differ(paths, consumer, f4cache) def _print_unreachable_stage_message(provider: Stage, take: str): sfprint(0, ' Stage ' @@ -214,31 +213,31 @@ class Flow: run_stages: 'set[str]' # Number of stages that relied on outdated version of a (checked) dependency deps_rebuilds: 'dict[str, int]' - symbicache: 'SymbiCache | None' + f4cache: 'F4Cache | None' flow_cfg: FlowConfig def __init__(self, target: str, cfg: FlowConfig, - symbicache: 'SymbiCache | None'): + f4cache: 'F4Cache | None'): self.target = target self.os_map = map_outputs_to_stages(cfg.stages.values()) explicit_deps = cfg.get_dependency_overrides() # print(explicit_deps) - self.dep_paths = dict(filter_existing_deps(explicit_deps, symbicache)) + self.dep_paths = dict(filter_existing_deps(explicit_deps, f4cache)) self.run_stages = set() - self.symbicache = symbicache + self.f4cache = f4cache self.cfg = cfg self.deps_rebuilds = {} self._resolve_dependencies(self.target, set()) def _dep_will_differ(self, dep: str, paths, consumer: str): - if not self.symbicache: # Handle --nocache mode + if not self.f4cache: # Handle --nocache mode return True return dep_will_differ(dep, paths, consumer, self.os_map, self.run_stages, - self.symbicache) + self.f4cache) def _resolve_dependencies(self, dep: str, stages_checked: 'set[str]'): # Initialize the dependency status if necessary @@ -353,16 +352,16 @@ class Flow: else: assert(provider) - any_dep_differ = False if (self.symbicache is not None) else True + any_dep_differ = False if (self.f4cache is not None) else True for p_dep in provider.takes: if not self._build_dep(p_dep.name): assert (p_dep.spec != 'req') continue - if self.symbicache is not None: + if self.f4cache is not None: any_dep_differ |= \ update_dep_statuses(self.dep_paths[p_dep.name], - provider.name, self.symbicache) + provider.name, self.f4cache) # If dependencies remained the same, consider the dep as up-to date # For example, when changing a comment in Verilog source code, @@ -390,9 +389,9 @@ class Flow: def execute(self): self._build_dep(self.target) - if self.symbicache: + if self.f4cache: update_dep_statuses(self.dep_paths[self.target], '__target', - self.symbicache) + self.f4cache) sfprint(0, f'Target `{Style.BRIGHT + self.target + Style.RESET_ALL}` ' f'-> {self.dep_paths[self.target]}') @@ -583,7 +582,7 @@ def cmd_build(args: Namespace): flow = Flow( target=target, cfg=flow_cfg, - symbicache=SymbiCache(SYMBICACHEPATH) if not args.nocache else None + f4cache=F4Cache(F4CACHEPATH) if not args.nocache else None ) dep_print_verbosity = 0 if args.pretend else 2 @@ -600,8 +599,8 @@ def cmd_build(args: Namespace): sfprint(0, e) sfbuild_fail() - if flow.symbicache: - flow.symbicache.save() + if flow.f4cache: + flow.f4cache.save() def cmd_show_dependencies(args: Namespace): """ sfbuild's `showd` command implementation """ diff --git a/f4pga/cache.py b/f4pga/cache.py index 75a5d41..5b60e17 100755 --- a/f4pga/cache.py +++ b/f4pga/cache.py @@ -4,9 +4,9 @@ from json import dump as json_dump, load as json_load, JSONDecodeError from f4pga.common import sfprint -class SymbiCache: +class F4Cache: """ - `SymbiCache` is used to track changes among dependencies and keep the status of the files on a persistent storage. + `F4Cache` is used to track changes among dependencies and keep the status of the files on a persistent storage. Files which are tracked get their checksums calculated and stored in a file. If file's checksum differs from the one saved in a file, that means, the file has changed. """ @@ -91,13 +91,13 @@ class SymbiCache: try: with Path(self.cachefile_path).open('r') as rfptr: self.hashes = json_load(rfptr) - except JSONDecodeError as jerr: - sfprint(0, 'WARNING: .symbicache is corrupted!\n' - 'This will cause flow to re-execute from the beginning.') + except JSONDecodeError: + sfprint(0, f'WARNING: `{self.cachefile_path}` f4cache is corrupted!\n' + 'This will cause flow to re-execute from the beginning.') self.hashes = {} except FileNotFoundError: - sfprint(0, 'Couldn\'t open .symbicache cache file.\n' - 'This will cause flow to re-execute from the beginning.') + sfprint(0, f'Couldn\'t open `{self.cachefile_path}` cache file.\n' + 'This will cause flow to re-execute from the beginning.') self.hashes = {} def save(self):