From 383f369a0b9447c412d84c778692c01fd79569e7 Mon Sep 17 00:00:00 2001 From: Honglei-Qiu <1044497581@qq.com> Date: Mon, 19 Jan 2026 09:21:06 +0000 Subject: [PATCH 1/4] fix. --- graph_net/dimension_generalizer.py | 23 ++++-- .../group_ranges_from_subgraph_sources.py | 79 ++++++++++++------- 2 files changed, 69 insertions(+), 33 deletions(-) diff --git a/graph_net/dimension_generalizer.py b/graph_net/dimension_generalizer.py index da754d6d8..1a37af595 100644 --- a/graph_net/dimension_generalizer.py +++ b/graph_net/dimension_generalizer.py @@ -137,14 +137,25 @@ def _save_tensor_metas_as_weight_meta(self, to_model_path, tensor_metas): (to_model_path / "weight_meta.py").write_text(weight_meta_code) def _get_to_model_path(self, rel_model_path, symbol2example_value): - sym_dim_str = "_".join( - f"{sym_name}_{dim}" - for symbol, dim in symbol2example_value.items() - for sym_name in [symbol.name] + symbols, reified_dims = self._get_symbols_and_reified_dims( + Path(self.config["model_path_prefix"]) / rel_model_path, + DynamicDimConstraints.unserialize_from_py_file( + os.path.join( + self.config["model_path_prefix"], + rel_model_path, + "input_tensor_constraints.py", + ) + ), ) - sub_module_name = f"{os.path.basename(rel_model_path)}__{sym_dim_str}" + current_dims = tuple(symbol2example_value[symbol] for symbol in symbols) + dim_index = 0 + for i, dims in enumerate(reified_dims): + if tuple(dims) == current_dims: + dim_index = i + break + sub_module_name = f"{dim_index}" to_model_path = ( - Path(self.config["output_dir"]) / rel_model_path / sub_module_name + Path(self.config["output_dir"]) / sub_module_name / rel_model_path ) return to_model_path diff --git a/graph_net/sample_pass/group_ranges_from_subgraph_sources.py b/graph_net/sample_pass/group_ranges_from_subgraph_sources.py index eaf5be128..85cf95864 100644 --- a/graph_net/sample_pass/group_ranges_from_subgraph_sources.py +++ b/graph_net/sample_pass/group_ranges_from_subgraph_sources.py @@ -1,6 +1,7 @@ from graph_net.sample_pass.sample_pass import SamplePass from pathlib import Path import json +import re class GroupRangesFromSubgraphSources(SamplePass): @@ -10,6 +11,7 @@ def __init__(self, config=None): self.original_graph_rel_model_path2subgraph_rel_model_paths: dict[ str, list[str] ] = {} + self.original_graph_path_order = {} def declare_config( self, @@ -30,13 +32,29 @@ def __call__(self, subgraph_rel_model_path: str): ) subgraph_sources = json.load(open(model_path)) for original_graph_rel_model_path, subgraph_ranges in subgraph_sources.items(): - self._collect_original_graph_rel_model_path2ranges( - original_graph_rel_model_path, subgraph_ranges - ) - self._collect_original_graph_rel_model_path2subgraph_rel_model_path( - original_graph_rel_model_path, - [subgraph_rel_model_path] * len(subgraph_ranges), - ) + path_range = self._extract_range_from_path(subgraph_rel_model_path) + if path_range: + self._collect_original_graph_rel_model_path2ranges( + original_graph_rel_model_path, path_range + ) + self._collect_original_graph_rel_model_path2subgraph_rel_model_path( + original_graph_rel_model_path, [subgraph_rel_model_path] + ) + if original_graph_rel_model_path not in self.original_graph_path_order: + self.original_graph_path_order[original_graph_rel_model_path] = [] + if ( + path_range + not in self.original_graph_path_order[original_graph_rel_model_path] + ): + self.original_graph_path_order[ + original_graph_rel_model_path + ].append(path_range) + + def _extract_range_from_path(self, path: str) -> list[int]: + match = re.search(r"start(\d+)_end(\d+)", path) + if match: + return [int(match.group(1)), int(match.group(2))] + return None def _collect_original_graph_rel_model_path2subgraph_rel_model_path( self, @@ -46,37 +64,44 @@ def _collect_original_graph_rel_model_path2subgraph_rel_model_path( old = self.original_graph_rel_model_path2subgraph_rel_model_paths.get( original_graph_rel_model_path, [] ) + combined = old + [p for p in subgraph_rel_model_paths if p not in old] self.original_graph_rel_model_path2subgraph_rel_model_paths[ original_graph_rel_model_path - ] = [ - *old, - *subgraph_rel_model_paths, - ] + ] = combined def _collect_original_graph_rel_model_path2ranges( - self, original_graph_rel_model_path, subgraph_ranges + self, original_graph_path: str, path_range: list[int] ): old_ranges = self.original_graph_rel_model_path2ranges.get( - original_graph_rel_model_path, [] + original_graph_path, [] ) - self.original_graph_rel_model_path2ranges[original_graph_rel_model_path] = [ - *old_ranges, - *subgraph_ranges, - ] + if path_range not in old_ranges: + old_ranges.append(path_range) + self.original_graph_rel_model_path2ranges[original_graph_path] = old_ranges def END(self, rel_model_paths: list[str]): - for ( - original_graph_rel_model_path, - subgraph_ranges, - ) in self.original_graph_rel_model_path2ranges.items(): - subgraph_rel_model_paths = ( - self.original_graph_rel_model_path2subgraph_rel_model_paths[ - original_graph_rel_model_path - ] + for original_graph_rel_model_path in self.original_graph_path_order.keys(): + actual_ranges = self.original_graph_rel_model_path2ranges.get( + original_graph_rel_model_path, [] ) - self._save_json( - original_graph_rel_model_path, subgraph_ranges, subgraph_rel_model_paths + subgraph_rel_model_paths = ( + self.original_graph_rel_model_path2subgraph_rel_model_paths.get( + original_graph_rel_model_path, [] + ) ) + range_to_path = {} + for path in subgraph_rel_model_paths: + path_range = self._extract_range_from_path(path) + if path_range: + range_to_path[tuple(path_range)] = path + + sorted_ranges = sorted(actual_ranges, key=lambda x: x[0]) + sorted_paths = [ + range_to_path[tuple(r)] + for r in sorted_ranges + if tuple(r) in range_to_path + ] + self._save_json(original_graph_rel_model_path, sorted_ranges, sorted_paths) def _save_json( self, original_graph_rel_model_path, subgraph_ranges, subgraph_rel_model_paths From c0dec0eebeb33341c0486f1db79efe6dceb9c4e0 Mon Sep 17 00:00:00 2001 From: Honglei-Qiu <1044497581@qq.com> Date: Tue, 20 Jan 2026 03:47:52 +0000 Subject: [PATCH 2/4] fix s --- graph_net/dimension_generalizer.py | 25 +++++++++++++++++ .../group_ranges_from_subgraph_sources.py | 27 +++++++++++-------- 2 files changed, 41 insertions(+), 11 deletions(-) diff --git a/graph_net/dimension_generalizer.py b/graph_net/dimension_generalizer.py index 1a37af595..b49306f53 100644 --- a/graph_net/dimension_generalizer.py +++ b/graph_net/dimension_generalizer.py @@ -137,6 +137,28 @@ def _save_tensor_metas_as_weight_meta(self, to_model_path, tensor_metas): (to_model_path / "weight_meta.py").write_text(weight_meta_code) def _get_to_model_path(self, rel_model_path, symbol2example_value): + """ + 📍 关键修改1:使用索引而非符号字符串 + 📍 关键修改2:通过维值匹配找到对应索引 + 📍 关键修改3:路径结构从 model/name 变为 index/model + output_dir/ + ├── model1__symA_8_symB_16/ + ├── model1__symA_32_symB_64/ + └── model2__symA_8_symB_16/ + 修改前 + output_dir/ + ├── 0/ + │ ├── model1/ + │ └── model2/ + ├── 1/ + │ ├── model1/ + │ └── model2/ + └── 2/ + ├── model1/ + └── model2/ + 修改后 + """ + ## 关键修改1:使用索引而非符号字符串 symbols, reified_dims = self._get_symbols_and_reified_dims( Path(self.config["model_path_prefix"]) / rel_model_path, DynamicDimConstraints.unserialize_from_py_file( @@ -148,11 +170,14 @@ def _get_to_model_path(self, rel_model_path, symbol2example_value): ), ) current_dims = tuple(symbol2example_value[symbol] for symbol in symbols) + # 📍 关键修改2:通过维值匹配找到对应索引 dim_index = 0 for i, dims in enumerate(reified_dims): if tuple(dims) == current_dims: dim_index = i break + + # 📍 关键修改3:路径结构从 model/name 变为 index/model sub_module_name = f"{dim_index}" to_model_path = ( Path(self.config["output_dir"]) / sub_module_name / rel_model_path diff --git a/graph_net/sample_pass/group_ranges_from_subgraph_sources.py b/graph_net/sample_pass/group_ranges_from_subgraph_sources.py index 85cf95864..b3da497e9 100644 --- a/graph_net/sample_pass/group_ranges_from_subgraph_sources.py +++ b/graph_net/sample_pass/group_ranges_from_subgraph_sources.py @@ -11,7 +11,6 @@ def __init__(self, config=None): self.original_graph_rel_model_path2subgraph_rel_model_paths: dict[ str, list[str] ] = {} - self.original_graph_path_order = {} def declare_config( self, @@ -32,6 +31,7 @@ def __call__(self, subgraph_rel_model_path: str): ) subgraph_sources = json.load(open(model_path)) for original_graph_rel_model_path, subgraph_ranges in subgraph_sources.items(): + # 从路径提取真实的start-end范围,建立精确的一对一映射 path_range = self._extract_range_from_path(subgraph_rel_model_path) if path_range: self._collect_original_graph_rel_model_path2ranges( @@ -40,17 +40,9 @@ def __call__(self, subgraph_rel_model_path: str): self._collect_original_graph_rel_model_path2subgraph_rel_model_path( original_graph_rel_model_path, [subgraph_rel_model_path] ) - if original_graph_rel_model_path not in self.original_graph_path_order: - self.original_graph_path_order[original_graph_rel_model_path] = [] - if ( - path_range - not in self.original_graph_path_order[original_graph_rel_model_path] - ): - self.original_graph_path_order[ - original_graph_rel_model_path - ].append(path_range) def _extract_range_from_path(self, path: str) -> list[int]: + """从路径中提取start和end范围,例如:vgg16_bn_start0_end3_0 → [0,3]""" match = re.search(r"start(\d+)_end(\d+)", path) if match: return [int(match.group(1)), int(match.group(2))] @@ -61,9 +53,11 @@ def _collect_original_graph_rel_model_path2subgraph_rel_model_path( original_graph_rel_model_path: str, subgraph_rel_model_paths: list[str], ): + """收集子图路径,自动去重""" old = self.original_graph_rel_model_path2subgraph_rel_model_paths.get( original_graph_rel_model_path, [] ) + # 去重合并,保持路径唯一性 combined = old + [p for p in subgraph_rel_model_paths if p not in old] self.original_graph_rel_model_path2subgraph_rel_model_paths[ original_graph_rel_model_path @@ -72,6 +66,7 @@ def _collect_original_graph_rel_model_path2subgraph_rel_model_path( def _collect_original_graph_rel_model_path2ranges( self, original_graph_path: str, path_range: list[int] ): + """收集子图范围,自动去重""" old_ranges = self.original_graph_rel_model_path2ranges.get( original_graph_path, [] ) @@ -80,7 +75,10 @@ def _collect_original_graph_rel_model_path2ranges( self.original_graph_rel_model_path2ranges[original_graph_path] = old_ranges def END(self, rel_model_paths: list[str]): - for original_graph_rel_model_path in self.original_graph_path_order.keys(): + """最终处理:按范围排序并保存结果""" + for ( + original_graph_rel_model_path + ) in self.original_graph_rel_model_path2ranges.keys(): actual_ranges = self.original_graph_rel_model_path2ranges.get( original_graph_rel_model_path, [] ) @@ -89,23 +87,28 @@ def END(self, rel_model_paths: list[str]): original_graph_rel_model_path, [] ) ) + + # 建立范围和路径的映射关系 range_to_path = {} for path in subgraph_rel_model_paths: path_range = self._extract_range_from_path(path) if path_range: range_to_path[tuple(path_range)] = path + # 按范围的起始位置排序,确保输出的结构化 sorted_ranges = sorted(actual_ranges, key=lambda x: x[0]) sorted_paths = [ range_to_path[tuple(r)] for r in sorted_ranges if tuple(r) in range_to_path ] + self._save_json(original_graph_rel_model_path, sorted_ranges, sorted_paths) def _save_json( self, original_graph_rel_model_path, subgraph_ranges, subgraph_rel_model_paths ): + """保存最终的聚合结果到JSON文件""" model_dir = Path(self.config["output_dir"]) / original_graph_rel_model_path model_dir.mkdir(parents=True, exist_ok=True) ranges_json = self._get_ranges_json(subgraph_ranges) @@ -115,6 +118,7 @@ def _save_json( (model_dir / self.config["output_json_file_name"]).write_text(json_str) def _get_paths_json(self, subgraph_rel_model_paths: list[str]): + """生成路径部分的JSON对象""" json_obj = { self.config[ "output_json_subgraph_rel_model_path_key" @@ -123,5 +127,6 @@ def _get_paths_json(self, subgraph_rel_model_paths: list[str]): return json_obj def _get_ranges_json(self, subgraph_ranges: list[(int, int)]): + """生成范围部分的JSON对象""" json_obj = {self.config["output_json_key"]: subgraph_ranges} return json_obj From e31a26b7b5021b6353d43fad1d709a1189e35369 Mon Sep 17 00:00:00 2001 From: Honglei-Qiu <1044497581@qq.com> Date: Tue, 20 Jan 2026 03:58:00 +0000 Subject: [PATCH 3/4] fix s --- graph_net/dimension_generalizer.py | 21 +++++++++++------- .../group_ranges_from_subgraph_sources.py | 22 +++++++++---------- 2 files changed, 24 insertions(+), 19 deletions(-) diff --git a/graph_net/dimension_generalizer.py b/graph_net/dimension_generalizer.py index b49306f53..de1273d51 100644 --- a/graph_net/dimension_generalizer.py +++ b/graph_net/dimension_generalizer.py @@ -138,14 +138,17 @@ def _save_tensor_metas_as_weight_meta(self, to_model_path, tensor_metas): def _get_to_model_path(self, rel_model_path, symbol2example_value): """ - 📍 关键修改1:使用索引而非符号字符串 - 📍 关键修改2:通过维值匹配找到对应索引 - 📍 关键修改3:路径结构从 model/name 变为 index/model + Key modification 1: Use indices instead of symbol strings + Key modification 2: Find corresponding index through dimension value matching + Key modification 3: Path structure changed from model/name to index/model + + Before modification: output_dir/ ├── model1__symA_8_symB_16/ ├── model1__symA_32_symB_64/ └── model2__symA_8_symB_16/ - 修改前 + + After modification: output_dir/ ├── 0/ │ ├── model1/ @@ -156,9 +159,8 @@ def _get_to_model_path(self, rel_model_path, symbol2example_value): └── 2/ ├── model1/ └── model2/ - 修改后 """ - ## 关键修改1:使用索引而非符号字符串 + # Key modification 1: Use indices instead of symbol strings symbols, reified_dims = self._get_symbols_and_reified_dims( Path(self.config["model_path_prefix"]) / rel_model_path, DynamicDimConstraints.unserialize_from_py_file( @@ -170,14 +172,15 @@ def _get_to_model_path(self, rel_model_path, symbol2example_value): ), ) current_dims = tuple(symbol2example_value[symbol] for symbol in symbols) - # 📍 关键修改2:通过维值匹配找到对应索引 + + # Key modification 2: Find corresponding index through dimension value matching dim_index = 0 for i, dims in enumerate(reified_dims): if tuple(dims) == current_dims: dim_index = i break - # 📍 关键修改3:路径结构从 model/name 变为 index/model + # Key modification 3: Path structure changed from model/name to index/model sub_module_name = f"{dim_index}" to_model_path = ( Path(self.config["output_dir"]) / sub_module_name / rel_model_path @@ -278,6 +281,8 @@ def update_tensor_metas_by_dyn_dim_cstr( if tensor_meta.data is not None: assert isinstance(tensor_meta.data, (list, tuple)) size = functools.reduce(lambda a, b: a * b, tensor_meta.shape, 1) + + # Key improvement: Dynamic extension to handle any size requirement extended_tensor_data = list(tensor_meta.data) while len(extended_tensor_data) < size: extended_tensor_data.extend(extended_tensor_data) diff --git a/graph_net/sample_pass/group_ranges_from_subgraph_sources.py b/graph_net/sample_pass/group_ranges_from_subgraph_sources.py index b3da497e9..ae8a91d1a 100644 --- a/graph_net/sample_pass/group_ranges_from_subgraph_sources.py +++ b/graph_net/sample_pass/group_ranges_from_subgraph_sources.py @@ -31,7 +31,7 @@ def __call__(self, subgraph_rel_model_path: str): ) subgraph_sources = json.load(open(model_path)) for original_graph_rel_model_path, subgraph_ranges in subgraph_sources.items(): - # 从路径提取真实的start-end范围,建立精确的一对一映射 + # Extract actual start-end range from path, establish precise one-to-one mapping path_range = self._extract_range_from_path(subgraph_rel_model_path) if path_range: self._collect_original_graph_rel_model_path2ranges( @@ -42,7 +42,7 @@ def __call__(self, subgraph_rel_model_path: str): ) def _extract_range_from_path(self, path: str) -> list[int]: - """从路径中提取start和end范围,例如:vgg16_bn_start0_end3_0 → [0,3]""" + """Extract start and end range from path, e.g., vgg16_bn_start0_end3_0 → [0,3]""" match = re.search(r"start(\d+)_end(\d+)", path) if match: return [int(match.group(1)), int(match.group(2))] @@ -53,11 +53,11 @@ def _collect_original_graph_rel_model_path2subgraph_rel_model_path( original_graph_rel_model_path: str, subgraph_rel_model_paths: list[str], ): - """收集子图路径,自动去重""" + """Collect subgraph paths with automatic deduplication""" old = self.original_graph_rel_model_path2subgraph_rel_model_paths.get( original_graph_rel_model_path, [] ) - # 去重合并,保持路径唯一性 + # Deduplicate and merge, maintaining path uniqueness combined = old + [p for p in subgraph_rel_model_paths if p not in old] self.original_graph_rel_model_path2subgraph_rel_model_paths[ original_graph_rel_model_path @@ -66,7 +66,7 @@ def _collect_original_graph_rel_model_path2subgraph_rel_model_path( def _collect_original_graph_rel_model_path2ranges( self, original_graph_path: str, path_range: list[int] ): - """收集子图范围,自动去重""" + """Collect subgraph ranges with automatic deduplication""" old_ranges = self.original_graph_rel_model_path2ranges.get( original_graph_path, [] ) @@ -75,7 +75,7 @@ def _collect_original_graph_rel_model_path2ranges( self.original_graph_rel_model_path2ranges[original_graph_path] = old_ranges def END(self, rel_model_paths: list[str]): - """最终处理:按范围排序并保存结果""" + """Final processing: sort by range and save results""" for ( original_graph_rel_model_path ) in self.original_graph_rel_model_path2ranges.keys(): @@ -88,14 +88,14 @@ def END(self, rel_model_paths: list[str]): ) ) - # 建立范围和路径的映射关系 + # Establish mapping relationship between ranges and paths range_to_path = {} for path in subgraph_rel_model_paths: path_range = self._extract_range_from_path(path) if path_range: range_to_path[tuple(path_range)] = path - # 按范围的起始位置排序,确保输出的结构化 + # Sort by start position of ranges to ensure structured output sorted_ranges = sorted(actual_ranges, key=lambda x: x[0]) sorted_paths = [ range_to_path[tuple(r)] @@ -108,7 +108,7 @@ def END(self, rel_model_paths: list[str]): def _save_json( self, original_graph_rel_model_path, subgraph_ranges, subgraph_rel_model_paths ): - """保存最终的聚合结果到JSON文件""" + """Save final aggregated results to JSON files""" model_dir = Path(self.config["output_dir"]) / original_graph_rel_model_path model_dir.mkdir(parents=True, exist_ok=True) ranges_json = self._get_ranges_json(subgraph_ranges) @@ -118,7 +118,7 @@ def _save_json( (model_dir / self.config["output_json_file_name"]).write_text(json_str) def _get_paths_json(self, subgraph_rel_model_paths: list[str]): - """生成路径部分的JSON对象""" + """Generate JSON object for paths section""" json_obj = { self.config[ "output_json_subgraph_rel_model_path_key" @@ -127,6 +127,6 @@ def _get_paths_json(self, subgraph_rel_model_paths: list[str]): return json_obj def _get_ranges_json(self, subgraph_ranges: list[(int, int)]): - """生成范围部分的JSON对象""" + """Generate JSON object for ranges section""" json_obj = {self.config["output_json_key"]: subgraph_ranges} return json_obj From 00e492a83e3240ed166350c7f6c152e9c0f972f7 Mon Sep 17 00:00:00 2001 From: Honglei-Qiu <1044497581@qq.com> Date: Tue, 20 Jan 2026 05:44:35 +0000 Subject: [PATCH 4/4] fix --- graph_net/dimension_generalizer.py | 34 ++++++------------- .../group_ranges_from_subgraph_sources.py | 9 +++-- 2 files changed, 17 insertions(+), 26 deletions(-) diff --git a/graph_net/dimension_generalizer.py b/graph_net/dimension_generalizer.py index de1273d51..e8ac50731 100644 --- a/graph_net/dimension_generalizer.py +++ b/graph_net/dimension_generalizer.py @@ -138,29 +138,17 @@ def _save_tensor_metas_as_weight_meta(self, to_model_path, tensor_metas): def _get_to_model_path(self, rel_model_path, symbol2example_value): """ - Key modification 1: Use indices instead of symbol strings - Key modification 2: Find corresponding index through dimension value matching - Key modification 3: Path structure changed from model/name to index/model + Generates output paths organized by dimension configuration indices rather than + symbolic dimension strings. - Before modification: - output_dir/ - ├── model1__symA_8_symB_16/ - ├── model1__symA_32_symB_64/ - └── model2__symA_8_symB_16/ + Path structure transformation: + Before: model_name__symbolic_dims (e.g., 'model1__symA_8_symB_16') + After: index/model_name (e.g., '0/model1', '1/model1') - After modification: - output_dir/ - ├── 0/ - │ ├── model1/ - │ └── model2/ - ├── 1/ - │ ├── model1/ - │ └── model2/ - └── 2/ - ├── model1/ - └── model2/ + The index represents a specific dimension configuration from the reification set, + enabling systematic management of dimension variations. """ - # Key modification 1: Use indices instead of symbol strings + # Use indices instead of symbol strings symbols, reified_dims = self._get_symbols_and_reified_dims( Path(self.config["model_path_prefix"]) / rel_model_path, DynamicDimConstraints.unserialize_from_py_file( @@ -173,14 +161,14 @@ def _get_to_model_path(self, rel_model_path, symbol2example_value): ) current_dims = tuple(symbol2example_value[symbol] for symbol in symbols) - # Key modification 2: Find corresponding index through dimension value matching + # Find corresponding index through dimension value matching dim_index = 0 for i, dims in enumerate(reified_dims): if tuple(dims) == current_dims: dim_index = i break - # Key modification 3: Path structure changed from model/name to index/model + # Path structure changed from model/name to index/model sub_module_name = f"{dim_index}" to_model_path = ( Path(self.config["output_dir"]) / sub_module_name / rel_model_path @@ -281,8 +269,6 @@ def update_tensor_metas_by_dyn_dim_cstr( if tensor_meta.data is not None: assert isinstance(tensor_meta.data, (list, tuple)) size = functools.reduce(lambda a, b: a * b, tensor_meta.shape, 1) - - # Key improvement: Dynamic extension to handle any size requirement extended_tensor_data = list(tensor_meta.data) while len(extended_tensor_data) < size: extended_tensor_data.extend(extended_tensor_data) diff --git a/graph_net/sample_pass/group_ranges_from_subgraph_sources.py b/graph_net/sample_pass/group_ranges_from_subgraph_sources.py index ae8a91d1a..f776f0389 100644 --- a/graph_net/sample_pass/group_ranges_from_subgraph_sources.py +++ b/graph_net/sample_pass/group_ranges_from_subgraph_sources.py @@ -42,7 +42,13 @@ def __call__(self, subgraph_rel_model_path: str): ) def _extract_range_from_path(self, path: str) -> list[int]: - """Extract start and end range from path, e.g., vgg16_bn_start0_end3_0 → [0,3]""" + """ + Parses subgraph path names to extract the node range information. + This establishes the precise correspondence between + subgraph locations and their operational scope within the original graph. + + For example: model_startX_endY_Z -> [X, Y] + """ match = re.search(r"start(\d+)_end(\d+)", path) if match: return [int(match.group(1)), int(match.group(2))] @@ -102,7 +108,6 @@ def END(self, rel_model_paths: list[str]): for r in sorted_ranges if tuple(r) in range_to_path ] - self._save_json(original_graph_rel_model_path, sorted_ranges, sorted_paths) def _save_json(