get things working with a LazyLibrary hack while we think about cycles
This commit is contained in:
parent
f4537a0feb
commit
d9fe295f4f
5 changed files with 32 additions and 12 deletions
|
|
@ -1,9 +1,12 @@
|
|||
from typing import Dict
|
||||
from typing import Dict, TypeVar
|
||||
#from typing import Union, Optional, MutableMapping, TYPE_CHECKING
|
||||
import copy
|
||||
import logging
|
||||
|
||||
from numpy.typing import ArrayLike
|
||||
|
||||
#from .pattern import Pattern
|
||||
from .ref import Ref
|
||||
from .ports import PortList, Port
|
||||
|
||||
#if TYPE_CHECKING:
|
||||
|
|
|
|||
|
|
@ -207,7 +207,7 @@ class Builder(PortList):
|
|||
names.
|
||||
"""
|
||||
if library is None:
|
||||
if hasattr(source, 'library') and isinstance(source, MutableLibrary):
|
||||
if hasattr(source, 'library') and isinstance(source.library, MutableLibrary):
|
||||
library = source.library
|
||||
else:
|
||||
raise BuildError('No library provided (and not present in `source.library`')
|
||||
|
|
|
|||
|
|
@ -53,7 +53,9 @@ def dev2pat(pattern: Pattern, layer: layer_t) -> Pattern:
|
|||
def pat2dev(
|
||||
layers: Sequence[layer_t],
|
||||
library: Mapping[str, Pattern],
|
||||
pattern: Pattern,
|
||||
pattern: Pattern, # Pattern is good since we don't want to do library[name] to avoid infinite recursion.
|
||||
# LazyLibrary protects against library[ref.target] causing a circular lookup.
|
||||
# For others, maybe check for cycles up front? TODO
|
||||
name: Optional[str] = None,
|
||||
max_depth: int = 999_999,
|
||||
skip_subcells: bool = True,
|
||||
|
|
@ -94,20 +96,24 @@ def pat2dev(
|
|||
if (skip_subcells and pattern.ports) or max_depth == 0:
|
||||
return pattern
|
||||
|
||||
# Load ports for all subpatterns
|
||||
for target in set(rr.target for rr in pat.refs):
|
||||
# Load ports for all subpatterns, and use any we find
|
||||
found_ports = False
|
||||
for target in set(rr.target for rr in pattern.refs):
|
||||
pp = pat2dev(
|
||||
layers=layers,
|
||||
library=library,
|
||||
pattern=library[target],
|
||||
name=target,
|
||||
max_depth=max_depth-1,
|
||||
max_depth=max_depth - 1,
|
||||
skip_subcells=skip_subcells,
|
||||
blacklist=blacklist + {name},
|
||||
)
|
||||
found_ports |= bool(pp.ports)
|
||||
|
||||
for ref in pat.refs:
|
||||
if not found_ports:
|
||||
return pattern
|
||||
|
||||
for ref in pattern.refs:
|
||||
aa = library.abstract(ref.target)
|
||||
if not aa.ports:
|
||||
continue
|
||||
|
|
|
|||
|
|
@ -713,11 +713,13 @@ class LazyLibrary(MutableLibrary):
|
|||
"""
|
||||
dict: Dict[str, Callable[[], 'Pattern']]
|
||||
cache: Dict[str, 'Pattern']
|
||||
_lookups_in_progress: Set[str]
|
||||
enable_cache: bool = True
|
||||
|
||||
def __init__(self) -> None:
|
||||
self.dict = {}
|
||||
self.cache = {}
|
||||
self._lookups_in_progress = set()
|
||||
|
||||
def __setitem__(self, key: str, value: Callable[[], 'Pattern']) -> None:
|
||||
self.dict[key] = value
|
||||
|
|
@ -735,8 +737,17 @@ class LazyLibrary(MutableLibrary):
|
|||
logger.debug(f'found {key} in cache')
|
||||
return self.cache[key]
|
||||
|
||||
if key in self._lookups_in_progress:
|
||||
raise LibraryError(
|
||||
f'Detected multiple simultaneous lookups of "{key}".\n'
|
||||
'This may be caused by an invalid (cyclical) reference, or buggy code.\n'
|
||||
'If you are lazy-loading a file, try a non-lazy load and check for refernce cycles.' # TODO give advice on finding cycles
|
||||
)
|
||||
|
||||
self._lookups_in_progress.add(key)
|
||||
func = self.dict[key]
|
||||
pat = func()
|
||||
self._lookups_in_progress.remove(key)
|
||||
self.cache[key] = pat
|
||||
return pat
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue