[gdsii] misc cleanup

This commit is contained in:
Jan Petykiewicz 2026-07-09 14:21:05 -07:00
commit 520f37aa29
4 changed files with 38 additions and 56 deletions

View file

@ -39,7 +39,7 @@ from pprint import pformat
from klamath.basic import KlamathError from klamath.basic import KlamathError
import numpy import numpy
from numpy.typing import ArrayLike, NDArray from numpy.typing import NDArray
import pyarrow import pyarrow
from pyarrow.cffi import ffi 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]: 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) layer = (values >> numpy.uint32(16)).astype(numpy.uint16).view(numpy.int16)
dtype = (values & numpy.uint32(0xffff)).astype(numpy.uint16).view(numpy.int16) dtype = (values & numpy.uint32(0xffff)).astype(numpy.uint16).view(numpy.int16)

View file

@ -90,10 +90,6 @@ def is_available() -> bool:
return arrow.is_available() 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: def _open_source_buffer(path: pathlib.Path) -> _SourceBuffer:
if is_gzipped(path): if is_gzipped(path):
with gzip.open(path, mode='rb') as stream: 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: 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() cell_names = libarr['cell_names'].as_py()
cells = libarr['cells'] cells = libarr['cells']

View file

@ -22,7 +22,7 @@ from ...library import ILibraryView, OverlayLibrary
from ...library.overlay import _SourceEntry, _materialize_detached_pattern from ...library.overlay import _SourceEntry, _materialize_detached_pattern
if TYPE_CHECKING: if TYPE_CHECKING:
from collections.abc import Iterator, Mapping from collections.abc import Mapping
from ...pattern import Pattern from ...pattern import Pattern
@ -30,15 +30,6 @@ if TYPE_CHECKING:
logger = logging.getLogger(__name__) 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( def _get_write_info(
library: Mapping[str, Pattern] | ILibraryView, 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: 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 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: if infos:
unit_pairs = {(info['meters_per_unit'], info['logical_units_per_unit']) for info in infos} unit_pairs = {(info['meters_per_unit'], info['logical_units_per_unit']) for info in infos}
if len(unit_pairs) > 1: 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)) 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: def _write_pattern_struct(stream: IO[bytes], name: str, pat: Pattern) -> None:
elements: list[klamath.elements.Element] = [] elements: list[klamath.elements.Element] = []
elements += gdsii._shapes_to_elements(pat.shapes) elements += gdsii._shapes_to_elements(pat.shapes)
@ -122,8 +112,15 @@ def write(
if isinstance(library, OverlayLibrary): if isinstance(library, OverlayLibrary):
for name in library.source_order(): for name in library.source_order():
entry = library._entries[name] 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] 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)) stream.write(_raw_struct_bytes(layer.library, entry.source_name))
else: else:
_write_pattern_struct(stream, name, library._materialize_pattern(name, persist=False)) _write_pattern_struct(stream, name, library._materialize_pattern(name, persist=False))

View file

@ -487,38 +487,31 @@ def _write_top(stream: Any, cfg: FixturePreset) -> None:
_write_struct(stream, 'TOP', cell_elements) _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: def fixture_manifest(path: str | Path, preset: str, scale: float = 1.0) -> FixtureManifest:
base = PRESETS[preset] base = PRESETS[preset]
cfg = _scaled_preset(base, scale) 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 = ( flattened_box_placements = (
cfg.box_wrappers 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] + cfg.top_direct_box_refs * cfg.top_box_array[0] * cfg.top_box_array[1]
) )
flattened_poly_placements = ( flattened_poly_placements = (
cfg.poly_wrappers 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] + cfg.top_direct_poly_refs * cfg.top_poly_array[0] * cfg.top_poly_array[1]
) )
polygon_layers = max(1, cfg.polygon_layers) 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_heavy_layer=cfg.box_cells * cfg.heavy_boxes_per_cell,
hierarchical_boxes_per_regular_layer=cfg.box_cells * cfg.regular_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_polygons_total=cfg.poly_cells * cfg.polygons_per_cell,
hierarchical_paths_total=_poly_paths_total(cfg), hierarchical_paths_total=(cfg.poly_cells - 1) // cfg.path_stride + 1,
hierarchical_texts_total=_poly_texts_total(cfg), hierarchical_texts_total=(cfg.poly_cells - 1) // cfg.text_stride + 1,
flattened_box_placements=flattened_box_placements, flattened_box_placements=flattened_box_placements,
flattened_poly_placements=flattened_poly_placements, flattened_poly_placements=flattened_poly_placements,
estimated_flat_boxes_per_heavy_layer=flattened_box_placements * cfg.heavy_boxes_per_cell, estimated_flat_boxes_per_heavy_layer=flattened_box_placements * cfg.heavy_boxes_per_cell,