From 520f37aa292bee9087c6d63baba80526fda5017a Mon Sep 17 00:00:00 2001 From: Jan Petykiewicz Date: Thu, 9 Jul 2026 14:21:05 -0700 Subject: [PATCH] [gdsii] misc cleanup --- masque/file/gdsii/arrow.py | 6 +---- masque/file/gdsii/lazy_arrow.py | 6 +---- masque/file/gdsii/lazy_write.py | 41 +++++++++++++++------------------ masque/file/gdsii/perf.py | 41 ++++++++++++++------------------- 4 files changed, 38 insertions(+), 56 deletions(-) diff --git a/masque/file/gdsii/arrow.py b/masque/file/gdsii/arrow.py index 2fcc7c9..c0d9c61 100644 --- a/masque/file/gdsii/arrow.py +++ b/masque/file/gdsii/arrow.py @@ -39,7 +39,7 @@ from pprint import pformat from klamath.basic import KlamathError import numpy -from numpy.typing import ArrayLike, NDArray +from numpy.typing import NDArray import pyarrow from pyarrow.cffi import ffi @@ -80,10 +80,6 @@ path_cap_map = { } -def rint_cast(val: ArrayLike) -> NDArray[numpy.int32]: - return numpy.rint(val).astype(numpy.int32) - - def _packed_layer_u32_to_pairs(values: NDArray[numpy.unsignedinteger[Any]]) -> NDArray[numpy.int16]: layer = (values >> numpy.uint32(16)).astype(numpy.uint16).view(numpy.int16) dtype = (values & numpy.uint32(0xffff)).astype(numpy.uint16).view(numpy.int16) diff --git a/masque/file/gdsii/lazy_arrow.py b/masque/file/gdsii/lazy_arrow.py index 6d14f0a..5a0da0f 100644 --- a/masque/file/gdsii/lazy_arrow.py +++ b/masque/file/gdsii/lazy_arrow.py @@ -90,10 +90,6 @@ def is_available() -> bool: return arrow.is_available() -def _read_header(libarr: pyarrow.StructScalar) -> dict[str, Any]: - return arrow._read_header(libarr) - - def _open_source_buffer(path: pathlib.Path) -> _SourceBuffer: if is_gzipped(path): with gzip.open(path, mode='rb') as stream: @@ -106,7 +102,7 @@ def _open_source_buffer(path: pathlib.Path) -> _SourceBuffer: def _extract_scan_payload(libarr: pyarrow.StructScalar) -> _ScanPayload: - library_info = _read_header(libarr) + library_info = arrow._read_header(libarr) cell_names = libarr['cell_names'].as_py() cells = libarr['cells'] diff --git a/masque/file/gdsii/lazy_write.py b/masque/file/gdsii/lazy_write.py index 8cb167a..225787a 100644 --- a/masque/file/gdsii/lazy_write.py +++ b/masque/file/gdsii/lazy_write.py @@ -22,7 +22,7 @@ from ...library import ILibraryView, OverlayLibrary from ...library.overlay import _SourceEntry, _materialize_detached_pattern if TYPE_CHECKING: - from collections.abc import Iterator, Mapping + from collections.abc import Mapping from ...pattern import Pattern @@ -30,15 +30,6 @@ if TYPE_CHECKING: logger = logging.getLogger(__name__) -def _iter_library_infos(library: Mapping[str, Pattern] | ILibraryView) -> Iterator[dict[str, Any]]: - info = getattr(library, 'library_info', None) - if isinstance(info, dict): - yield info - if isinstance(library, OverlayLibrary): - for layer in library._layers: - yield from _iter_library_infos(layer.library) - - def _get_write_info( library: Mapping[str, Pattern] | ILibraryView, *, @@ -49,7 +40,16 @@ def _get_write_info( if meters_per_unit is not None and logical_units_per_unit is not None and library_name is not None: return meters_per_unit, logical_units_per_unit, library_name - infos = list(_iter_library_infos(library)) + infos: list[dict[str, Any]] = [] + stack: list[Mapping[str, Pattern] | ILibraryView] = [library] + while stack: + current = stack.pop() + info = getattr(current, 'library_info', None) + if isinstance(info, dict): + infos.append(info) + if isinstance(current, OverlayLibrary): + stack.extend(reversed([layer.library for layer in current._layers])) + if infos: unit_pairs = {(info['meters_per_unit'], info['logical_units_per_unit']) for info in infos} if len(unit_pairs) > 1: @@ -79,16 +79,6 @@ def _raw_struct_bytes(library: Mapping[str, Pattern] | ILibraryView, name: str) return cast('bytes', reader(name)) -def _can_copy_overlay_cell(library: OverlayLibrary, name: str, entry: _SourceEntry) -> bool: - layer = library._layers[entry.layer_index] - if name != entry.source_name: - return False - if not _can_copy_raw_cell(layer.library, entry.source_name): - return False - children = layer.child_graph.get(entry.source_name, set()) - return all(library._effective_target(layer, child) == child for child in children) - - def _write_pattern_struct(stream: IO[bytes], name: str, pat: Pattern) -> None: elements: list[klamath.elements.Element] = [] elements += gdsii._shapes_to_elements(pat.shapes) @@ -122,8 +112,15 @@ def write( if isinstance(library, OverlayLibrary): for name in library.source_order(): entry = library._entries[name] - if isinstance(entry, _SourceEntry) and _can_copy_overlay_cell(library, name, entry): + can_copy_overlay = False + if isinstance(entry, _SourceEntry) and name == entry.source_name: layer = library._layers[entry.layer_index] + children = layer.child_graph.get(entry.source_name, set()) + can_copy_overlay = ( + _can_copy_raw_cell(layer.library, entry.source_name) + and all(library._effective_target(layer, child) == child for child in children) + ) + if can_copy_overlay: stream.write(_raw_struct_bytes(layer.library, entry.source_name)) else: _write_pattern_struct(stream, name, library._materialize_pattern(name, persist=False)) diff --git a/masque/file/gdsii/perf.py b/masque/file/gdsii/perf.py index 339d1e0..64bd7ab 100644 --- a/masque/file/gdsii/perf.py +++ b/masque/file/gdsii/perf.py @@ -487,38 +487,31 @@ def _write_top(stream: Any, cfg: FixturePreset) -> None: _write_struct(stream, 'TOP', cell_elements) -def _poly_paths_total(cfg: FixturePreset) -> int: - return (cfg.poly_cells - 1) // cfg.path_stride + 1 - - -def _poly_texts_total(cfg: FixturePreset) -> int: - return (cfg.poly_cells - 1) // cfg.text_stride + 1 - - -def _ref_instances_per_box_cluster(cfg: FixturePreset) -> int: - array_refs = min(cfg.box_cluster_refs, max(1, (3 * cfg.box_cluster_refs) // 4)) - array_mult = cfg.box_cluster_array[0] * cfg.box_cluster_array[1] - return array_refs * array_mult + (cfg.box_cluster_refs - array_refs) - - -def _ref_instances_per_poly_cluster(cfg: FixturePreset) -> int: - array_refs = min(cfg.poly_cluster_refs, cfg.poly_cluster_refs // 2) - array_mult = cfg.poly_cluster_array[0] * cfg.poly_cluster_array[1] - return array_refs * array_mult + (cfg.poly_cluster_refs - array_refs) - - def fixture_manifest(path: str | Path, preset: str, scale: float = 1.0) -> FixtureManifest: base = PRESETS[preset] cfg = _scaled_preset(base, scale) + box_cluster_array_refs = min(cfg.box_cluster_refs, max(1, (3 * cfg.box_cluster_refs) // 4)) + box_cluster_array_mult = cfg.box_cluster_array[0] * cfg.box_cluster_array[1] + box_cluster_ref_instances = ( + box_cluster_array_refs * box_cluster_array_mult + + (cfg.box_cluster_refs - box_cluster_array_refs) + ) + poly_cluster_array_refs = min(cfg.poly_cluster_refs, cfg.poly_cluster_refs // 2) + poly_cluster_array_mult = cfg.poly_cluster_array[0] * cfg.poly_cluster_array[1] + poly_cluster_ref_instances = ( + poly_cluster_array_refs * poly_cluster_array_mult + + (cfg.poly_cluster_refs - poly_cluster_array_refs) + ) + flattened_box_placements = ( cfg.box_wrappers - + cfg.box_clusters * _ref_instances_per_box_cluster(cfg) + + cfg.box_clusters * box_cluster_ref_instances + cfg.top_direct_box_refs * cfg.top_box_array[0] * cfg.top_box_array[1] ) flattened_poly_placements = ( cfg.poly_wrappers - + cfg.poly_clusters * _ref_instances_per_poly_cluster(cfg) + + cfg.poly_clusters * poly_cluster_ref_instances + cfg.top_direct_poly_refs * cfg.top_poly_array[0] * cfg.top_poly_array[1] ) polygon_layers = max(1, cfg.polygon_layers) @@ -545,8 +538,8 @@ def fixture_manifest(path: str | Path, preset: str, scale: float = 1.0) -> Fixtu hierarchical_boxes_per_heavy_layer=cfg.box_cells * cfg.heavy_boxes_per_cell, hierarchical_boxes_per_regular_layer=cfg.box_cells * cfg.regular_boxes_per_cell, hierarchical_polygons_total=cfg.poly_cells * cfg.polygons_per_cell, - hierarchical_paths_total=_poly_paths_total(cfg), - hierarchical_texts_total=_poly_texts_total(cfg), + hierarchical_paths_total=(cfg.poly_cells - 1) // cfg.path_stride + 1, + hierarchical_texts_total=(cfg.poly_cells - 1) // cfg.text_stride + 1, flattened_box_placements=flattened_box_placements, flattened_poly_placements=flattened_poly_placements, estimated_flat_boxes_per_heavy_layer=flattened_box_placements * cfg.heavy_boxes_per_cell,