diffract-core 0.2.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- diffract/__init__.py +52 -0
- diffract/configs/fast_speed_without_disk.ini +48 -0
- diffract/configs/hybrid.ini +74 -0
- diffract/configs/sqlite.ini +62 -0
- diffract/containers.py +405 -0
- diffract/core/__init__.py +23 -0
- diffract/core/cache/__init__.py +24 -0
- diffract/core/cache/containers.py +93 -0
- diffract/core/cache/interface.py +117 -0
- diffract/core/cache/redis_manager.py +464 -0
- diffract/core/cache/simple_manager.py +478 -0
- diffract/core/compute/__init__.py +46 -0
- diffract/core/compute/config.py +48 -0
- diffract/core/compute/containers.py +81 -0
- diffract/core/compute/decorator.py +125 -0
- diffract/core/compute/exceptions.py +31 -0
- diffract/core/compute/execution/__init__.py +14 -0
- diffract/core/compute/execution/_types.py +70 -0
- diffract/core/compute/execution/aggregation.py +74 -0
- diffract/core/compute/execution/aggregation_runner.py +362 -0
- diffract/core/compute/execution/enums.py +38 -0
- diffract/core/compute/execution/executor.py +125 -0
- diffract/core/compute/execution/parameter_runner.py +125 -0
- diffract/core/compute/execution/restrictions.py +61 -0
- diffract/core/compute/execution/strategy.py +118 -0
- diffract/core/compute/execution/utils.py +112 -0
- diffract/core/compute/extensions/__init__.py +0 -0
- diffract/core/compute/extensions/power_law.py +1051 -0
- diffract/core/compute/extensions/rmt.py +150 -0
- diffract/core/compute/extensions/utils.py +36 -0
- diffract/core/compute/field_signature.py +183 -0
- diffract/core/compute/kernels/__init__.py +48 -0
- diffract/core/compute/kernels/alignment.py +106 -0
- diffract/core/compute/kernels/heavy_tailed.py +394 -0
- diffract/core/compute/kernels/marchenko_pastur.py +99 -0
- diffract/core/compute/kernels/mat_decomposition.py +101 -0
- diffract/core/compute/kernels/mat_properties.py +53 -0
- diffract/core/compute/kernels/model_quality.py +27 -0
- diffract/core/compute/kernels/norms.py +88 -0
- diffract/core/compute/kernels/ranks.py +35 -0
- diffract/core/compute/kernels/tracy_widom.py +36 -0
- diffract/core/compute/metadata.py +67 -0
- diffract/core/compute/registry.py +485 -0
- diffract/core/constants.py +147 -0
- diffract/core/data/__init__.py +32 -0
- diffract/core/data/interface.py +304 -0
- diffract/core/data/metadata/__init__.py +15 -0
- diffract/core/data/metadata/containers.py +60 -0
- diffract/core/data/metadata/interface.py +208 -0
- diffract/core/data/metadata/sqlite_index.py +604 -0
- diffract/core/data/nn/__init__.py +43 -0
- diffract/core/data/nn/aggregates/__init__.py +35 -0
- diffract/core/data/nn/aggregates/metadata.py +96 -0
- diffract/core/data/nn/aggregates/proxy.py +57 -0
- diffract/core/data/nn/aggregates/repository.py +87 -0
- diffract/core/data/nn/aggregates/view.py +307 -0
- diffract/core/data/nn/containers.py +86 -0
- diffract/core/data/nn/extractors/__init__.py +49 -0
- diffract/core/data/nn/extractors/base.py +300 -0
- diffract/core/data/nn/extractors/factory.py +234 -0
- diffract/core/data/nn/extractors/flax.py +112 -0
- diffract/core/data/nn/extractors/handlers/__init__.py +39 -0
- diffract/core/data/nn/extractors/handlers/base.py +110 -0
- diffract/core/data/nn/extractors/handlers/flax_handlers.py +71 -0
- diffract/core/data/nn/extractors/handlers/numpy_handlers.py +63 -0
- diffract/core/data/nn/extractors/handlers/onnx_handlers.py +67 -0
- diffract/core/data/nn/extractors/handlers/tensorflow_handlers.py +82 -0
- diffract/core/data/nn/extractors/handlers/torch_handlers.py +124 -0
- diffract/core/data/nn/extractors/interface.py +56 -0
- diffract/core/data/nn/extractors/numpy.py +94 -0
- diffract/core/data/nn/extractors/onnx.py +108 -0
- diffract/core/data/nn/extractors/tensorflow.py +99 -0
- diffract/core/data/nn/extractors/torch.py +204 -0
- diffract/core/data/nn/params/__init__.py +27 -0
- diffract/core/data/nn/params/interface.py +402 -0
- diffract/core/data/nn/params/metadata.py +110 -0
- diffract/core/data/nn/params/proxy.py +93 -0
- diffract/core/data/nn/params/repository.py +45 -0
- diffract/core/data/nn/params/schema.py +82 -0
- diffract/core/data/nn/params/view.py +393 -0
- diffract/core/data/proxy.py +246 -0
- diffract/core/data/repository.py +227 -0
- diffract/core/data/utils.py +33 -0
- diffract/core/data/view.py +389 -0
- diffract/core/export/__init__.py +27 -0
- diffract/core/export/containers.py +47 -0
- diffract/core/export/exporters.py +191 -0
- diffract/core/export/formatters/__init__.py +23 -0
- diffract/core/export/formatters/base.py +68 -0
- diffract/core/export/formatters/dict_formatter.py +38 -0
- diffract/core/export/formatters/json_formatter.py +58 -0
- diffract/core/export/formatters/list_formatter.py +41 -0
- diffract/core/export/formatters/pandas_formatter.py +86 -0
- diffract/core/export/formatters/polars_formatter.py +86 -0
- diffract/core/export/formatters/registry.py +84 -0
- diffract/core/export/interface.py +105 -0
- diffract/core/parallel/__init__.py +21 -0
- diffract/core/parallel/containers.py +57 -0
- diffract/core/parallel/execution.py +91 -0
- diffract/core/parallel/runtime.py +91 -0
- diffract/core/storage/__init__.py +35 -0
- diffract/core/storage/base_manager.py +330 -0
- diffract/core/storage/containers.py +122 -0
- diffract/core/storage/hdf5_manager.py +856 -0
- diffract/core/storage/hybrid_manager.py +218 -0
- diffract/core/storage/interface.py +222 -0
- diffract/core/storage/metadata.py +89 -0
- diffract/core/storage/ram_manager.py +159 -0
- diffract/core/storage/sqlite_manager.py +1062 -0
- diffract/core/storage/zarr_manager.py +992 -0
- diffract/core/utils/__init__.py +45 -0
- diffract/core/utils/build.py +46 -0
- diffract/core/utils/exceptions.py +11 -0
- diffract/core/utils/hashing.py +90 -0
- diffract/core/utils/imports.py +292 -0
- diffract/core/utils/math.py +15 -0
- diffract/py.typed +0 -0
- diffract/session/__init__.py +24 -0
- diffract/session/errors.py +17 -0
- diffract/session/field_cache.py +216 -0
- diffract/session/namespaces/__init__.py +15 -0
- diffract/session/namespaces/compute/__init__.py +219 -0
- diffract/session/namespaces/models/__init__.py +282 -0
- diffract/session/namespaces/models/parameters/__init__.py +133 -0
- diffract/session/namespaces/models/parameters/meta_patcher.py +167 -0
- diffract/session/namespaces/results/__init__.py +378 -0
- diffract/session/namespaces/results/eraser.py +129 -0
- diffract/session/namespaces/results/injester.py +249 -0
- diffract/session/namespaces/utils/__init__.py +141 -0
- diffract/session/namespaces/utils/merger.py +295 -0
- diffract/session/namespaces/viz/__init__.py +91 -0
- diffract/session/namespaces/viz/_utils.py +14 -0
- diffract/session/namespaces/viz/box.py +207 -0
- diffract/session/namespaces/viz/grid.py +160 -0
- diffract/session/namespaces/viz/heatmap.py +164 -0
- diffract/session/namespaces/viz/scatter.py +202 -0
- diffract/session/namespaces/viz/sparkline.py +270 -0
- diffract/session/namespaces/viz/violin.py +212 -0
- diffract/session/session.py +260 -0
- diffract/session/utils.py +81 -0
- diffract/viz/__init__.py +42 -0
- diffract/viz/data/__init__.py +34 -0
- diffract/viz/data/detection.py +57 -0
- diffract/viz/data/extraction.py +117 -0
- diffract/viz/data/filtering.py +57 -0
- diffract/viz/data/ordering.py +129 -0
- diffract/viz/data/provider.py +99 -0
- diffract/viz/data/types.py +98 -0
- diffract/viz/plots/__init__.py +37 -0
- diffract/viz/plots/base/__init__.py +20 -0
- diffract/viz/plots/base/axis.py +219 -0
- diffract/viz/plots/base/coloraxis.py +133 -0
- diffract/viz/plots/base/configurator.py +18 -0
- diffract/viz/plots/base/jitter.py +368 -0
- diffract/viz/plots/base/line.py +197 -0
- diffract/viz/plots/base/marker.py +278 -0
- diffract/viz/plots/base/overlay.py +14 -0
- diffract/viz/plots/base/plot.py +110 -0
- diffract/viz/plots/base/update.py +50 -0
- diffract/viz/plots/boxplot.py +283 -0
- diffract/viz/plots/cluster.py +374 -0
- diffract/viz/plots/heatmap.py +168 -0
- diffract/viz/plots/scatter.py +233 -0
- diffract/viz/plots/sparkline.py +405 -0
- diffract/viz/plots/subplots/__init__.py +32 -0
- diffract/viz/plots/subplots/coloraxis.py +339 -0
- diffract/viz/plots/subplots/factory.py +713 -0
- diffract/viz/plots/subplots/grid.py +214 -0
- diffract/viz/plots/subplots/layout.py +370 -0
- diffract/viz/plots/subplots/spec.py +39 -0
- diffract/viz/plots/violin.py +298 -0
- diffract/viz/renderer.py +513 -0
- diffract/viz/styling/__init__.py +78 -0
- diffract/viz/styling/palettes/__init__.py +20 -0
- diffract/viz/styling/palettes/bundle.py +16 -0
- diffract/viz/styling/palettes/color.py +83 -0
- diffract/viz/styling/palettes/dashes.py +27 -0
- diffract/viz/styling/palettes/symbols.py +42 -0
- diffract/viz/styling/resolvers/__init__.py +11 -0
- diffract/viz/styling/resolvers/categorical.py +68 -0
- diffract/viz/styling/resolvers/color.py +77 -0
- diffract/viz/styling/resolvers/numeric.py +108 -0
- diffract/viz/styling/sources.py +27 -0
- diffract/viz/styling/theme/__init__.py +29 -0
- diffract/viz/styling/theme/applier.py +114 -0
- diffract/viz/styling/theme/components.py +66 -0
- diffract/viz/styling/theme/presets.py +58 -0
- diffract/viz/styling/theme/theme.py +36 -0
- diffract_core-0.2.1.dist-info/METADATA +530 -0
- diffract_core-0.2.1.dist-info/RECORD +193 -0
- diffract_core-0.2.1.dist-info/WHEEL +4 -0
- diffract_core-0.2.1.dist-info/licenses/LICENSE +201 -0
- diffract_core-0.2.1.dist-info/licenses/NOTICE +2 -0
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"""Metadata for aggregate entities.
|
|
2
|
+
|
|
3
|
+
This module provides the AggregateMetadata class for representing
|
|
4
|
+
aggregated data between parameters/models computed by aggregation kernels.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
import json
|
|
10
|
+
from dataclasses import dataclass, field
|
|
11
|
+
from typing import Any, Self
|
|
12
|
+
|
|
13
|
+
from diffract.core.utils.hashing import get_unique_id
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@dataclass(frozen=True, kw_only=True)
|
|
17
|
+
class AggregateMetadata:
|
|
18
|
+
"""Immutable metadata container for aggregate entities.
|
|
19
|
+
|
|
20
|
+
An aggregate represents computed data involving multiple models or parameters,
|
|
21
|
+
such as overlap metrics between two models or correlation between parameters.
|
|
22
|
+
|
|
23
|
+
Attributes:
|
|
24
|
+
uid: Unique identifier automatically generated if not provided.
|
|
25
|
+
field_name: Base field name of the computed aggregate (e.g., "l_overlap").
|
|
26
|
+
context_models: Tuple of model IDs participating in this aggregate.
|
|
27
|
+
context_params: Tuple of parameter names participating in this aggregate.
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
uid: str = field(default_factory=get_unique_id)
|
|
31
|
+
field_name: str
|
|
32
|
+
context_models: tuple[str, ...] = ()
|
|
33
|
+
context_params: tuple[str, ...] = ()
|
|
34
|
+
|
|
35
|
+
def to_dict(self) -> dict[str, Any]:
|
|
36
|
+
"""Serialize metadata to dictionary.
|
|
37
|
+
|
|
38
|
+
Returns:
|
|
39
|
+
Dictionary representation suitable for storage/reconstruction.
|
|
40
|
+
"""
|
|
41
|
+
return {
|
|
42
|
+
"uid": self.uid,
|
|
43
|
+
"field_name": self.field_name,
|
|
44
|
+
"context_models": json.dumps(list(self.context_models)),
|
|
45
|
+
"context_params": json.dumps(list(self.context_params)),
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
@classmethod
|
|
49
|
+
def from_dict(cls, data: dict[str, Any]) -> Self:
|
|
50
|
+
"""Deserialize metadata from dictionary.
|
|
51
|
+
|
|
52
|
+
Args:
|
|
53
|
+
data: Dictionary with metadata fields.
|
|
54
|
+
|
|
55
|
+
Returns:
|
|
56
|
+
AggregateMetadata instance.
|
|
57
|
+
"""
|
|
58
|
+
# Handle both list format (from to_dict) and JSON string format (from index)
|
|
59
|
+
context_models = data.get("context_models", [])
|
|
60
|
+
if isinstance(context_models, str):
|
|
61
|
+
context_models = json.loads(context_models)
|
|
62
|
+
|
|
63
|
+
context_params = data.get("context_params", [])
|
|
64
|
+
if isinstance(context_params, str):
|
|
65
|
+
context_params = json.loads(context_params)
|
|
66
|
+
|
|
67
|
+
return cls(
|
|
68
|
+
uid=data["uid"],
|
|
69
|
+
field_name=data["field_name"],
|
|
70
|
+
context_models=tuple(context_models),
|
|
71
|
+
context_params=tuple(context_params),
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
@classmethod
|
|
75
|
+
def create_uid_from_context(
|
|
76
|
+
cls,
|
|
77
|
+
field_name: str,
|
|
78
|
+
context_models: tuple[str, ...],
|
|
79
|
+
context_params: tuple[str, ...],
|
|
80
|
+
) -> str:
|
|
81
|
+
"""Create a deterministic UID from the aggregate context.
|
|
82
|
+
|
|
83
|
+
This allows deduplication of aggregates with the same context.
|
|
84
|
+
Uses the same format as contextual field names in constants.py.
|
|
85
|
+
|
|
86
|
+
Args:
|
|
87
|
+
field_name: Base field name of the aggregate.
|
|
88
|
+
context_models: Tuple of model IDs.
|
|
89
|
+
context_params: Tuple of parameter names.
|
|
90
|
+
|
|
91
|
+
Returns:
|
|
92
|
+
A deterministic UID string based on the context.
|
|
93
|
+
"""
|
|
94
|
+
from diffract.core.constants import format_contextual_field_name
|
|
95
|
+
|
|
96
|
+
return format_contextual_field_name(field_name, context_models, context_params)
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"""Proxy for aggregate entities.
|
|
2
|
+
|
|
3
|
+
This module provides the AggregateProxy class for accessing
|
|
4
|
+
aggregated data stored in the aggregates table.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from dataclasses import dataclass, field
|
|
10
|
+
from typing import TYPE_CHECKING
|
|
11
|
+
|
|
12
|
+
from diffract.core.constants import TABLE_AGGREGATES
|
|
13
|
+
from diffract.core.data.proxy import DataProxy
|
|
14
|
+
|
|
15
|
+
from .metadata import AggregateMetadata
|
|
16
|
+
|
|
17
|
+
if TYPE_CHECKING:
|
|
18
|
+
from .repository import AggregateRepository
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@dataclass(kw_only=True)
|
|
22
|
+
class AggregateProxy(DataProxy[AggregateMetadata]):
|
|
23
|
+
"""Lazy-loading proxy for aggregate data.
|
|
24
|
+
|
|
25
|
+
Extends the generic DataProxy with aggregate-specific configuration.
|
|
26
|
+
Aggregates are stored in the TABLE_AGGREGATES table and represent
|
|
27
|
+
computed aggregations between models/parameters.
|
|
28
|
+
|
|
29
|
+
Attributes:
|
|
30
|
+
meta: Immutable aggregate metadata.
|
|
31
|
+
_repository: Repository that owns storage/cache managers.
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
meta: AggregateMetadata
|
|
35
|
+
_repository: AggregateRepository = field(repr=False)
|
|
36
|
+
|
|
37
|
+
@classmethod
|
|
38
|
+
def get_table(cls) -> str:
|
|
39
|
+
"""Return the storage table name for aggregates."""
|
|
40
|
+
return TABLE_AGGREGATES
|
|
41
|
+
|
|
42
|
+
@classmethod
|
|
43
|
+
def create_and_store(
|
|
44
|
+
cls,
|
|
45
|
+
meta: AggregateMetadata,
|
|
46
|
+
repository: AggregateRepository,
|
|
47
|
+
) -> AggregateProxy:
|
|
48
|
+
"""Create aggregate proxy and store metadata in index.
|
|
49
|
+
|
|
50
|
+
Args:
|
|
51
|
+
meta: Aggregate metadata.
|
|
52
|
+
repository: Repository owning storage, cache, and metadata managers.
|
|
53
|
+
|
|
54
|
+
Returns:
|
|
55
|
+
New aggregate proxy with metadata stored.
|
|
56
|
+
"""
|
|
57
|
+
return super().create_and_store(meta=meta, repository=repository)
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"""Repository for aggregate entities.
|
|
2
|
+
|
|
3
|
+
This module provides the AggregateRepository class for managing
|
|
4
|
+
aggregate data storage and membership.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from typing import ClassVar
|
|
10
|
+
|
|
11
|
+
from diffract.core.constants import TABLE_AGGREGATES
|
|
12
|
+
from diffract.core.data.repository import DataRepository
|
|
13
|
+
|
|
14
|
+
from .metadata import AggregateMetadata
|
|
15
|
+
from .proxy import AggregateProxy
|
|
16
|
+
from .view import AggregateView
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class AggregateRepository(DataRepository[AggregateMetadata, AggregateProxy]):
|
|
20
|
+
"""Repository owning storage/cache/metadata and managing aggregate membership.
|
|
21
|
+
|
|
22
|
+
Extends the generic DataRepository with aggregate-specific configuration
|
|
23
|
+
for metadata class, proxy class, view class, storage table, and metadata schema.
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
METADATA_CLASS = AggregateMetadata
|
|
27
|
+
PROXY_CLASS = AggregateProxy
|
|
28
|
+
VIEW_CLASS = AggregateView
|
|
29
|
+
TABLE = TABLE_AGGREGATES
|
|
30
|
+
|
|
31
|
+
# Schema for MetadataIndex
|
|
32
|
+
METADATA_COLUMNS: ClassVar[dict[str, type]] = {
|
|
33
|
+
"field_name": str,
|
|
34
|
+
"context_models": str, # JSON-serialized tuple
|
|
35
|
+
"context_params": str, # JSON-serialized tuple
|
|
36
|
+
}
|
|
37
|
+
METADATA_INDEXES: ClassVar[list[str]] = ["field_name"]
|
|
38
|
+
|
|
39
|
+
def get_or_create(
|
|
40
|
+
self,
|
|
41
|
+
field_name: str,
|
|
42
|
+
context_models: tuple[str, ...],
|
|
43
|
+
context_params: tuple[str, ...],
|
|
44
|
+
) -> AggregateProxy:
|
|
45
|
+
"""Get existing aggregate by context or create a new one.
|
|
46
|
+
|
|
47
|
+
This method provides deduplication for aggregates with the same context.
|
|
48
|
+
|
|
49
|
+
Args:
|
|
50
|
+
field_name: Base field name of the aggregate.
|
|
51
|
+
context_models: Tuple of model IDs participating in this aggregate.
|
|
52
|
+
context_params: Tuple of parameter names participating in this aggregate.
|
|
53
|
+
|
|
54
|
+
Returns:
|
|
55
|
+
Existing or newly created AggregateProxy.
|
|
56
|
+
"""
|
|
57
|
+
# Create deterministic UID
|
|
58
|
+
uid = AggregateMetadata.create_uid_from_context(
|
|
59
|
+
field_name=field_name,
|
|
60
|
+
context_models=context_models,
|
|
61
|
+
context_params=context_params,
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
# Check if already exists in cache or index
|
|
65
|
+
if uid in self._proxy_cache:
|
|
66
|
+
return self._proxy_cache[uid]
|
|
67
|
+
|
|
68
|
+
if self.has_uid(uid):
|
|
69
|
+
return self.get_proxy(uid)
|
|
70
|
+
|
|
71
|
+
# Create new aggregate
|
|
72
|
+
meta = AggregateMetadata(
|
|
73
|
+
uid=uid,
|
|
74
|
+
field_name=field_name,
|
|
75
|
+
context_models=context_models,
|
|
76
|
+
context_params=context_params,
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
return AggregateProxy.create_and_store(meta=meta, repository=self)
|
|
80
|
+
|
|
81
|
+
def create_view(self) -> AggregateView:
|
|
82
|
+
"""Create a view over all aggregates in this repository.
|
|
83
|
+
|
|
84
|
+
Returns:
|
|
85
|
+
AggregateView containing all aggregates.
|
|
86
|
+
"""
|
|
87
|
+
return AggregateView(repository=self, uids=None)
|
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
"""View for aggregate entities.
|
|
2
|
+
|
|
3
|
+
This module provides the AggregateView class for batch operations
|
|
4
|
+
on filtered aggregate collections.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
import re
|
|
10
|
+
from collections.abc import Iterator
|
|
11
|
+
from typing import TYPE_CHECKING
|
|
12
|
+
|
|
13
|
+
from diffract.core.constants import REGEX_PREFIX, TABLE_AGGREGATES
|
|
14
|
+
from diffract.core.data.interface import EntityUID
|
|
15
|
+
from diffract.core.data.utils import build_matcher
|
|
16
|
+
from diffract.core.data.view import DataView
|
|
17
|
+
|
|
18
|
+
from .metadata import AggregateMetadata
|
|
19
|
+
from .proxy import AggregateProxy
|
|
20
|
+
|
|
21
|
+
if TYPE_CHECKING:
|
|
22
|
+
from .repository import AggregateRepository
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class AggregateView(DataView[AggregateMetadata, AggregateProxy]):
|
|
26
|
+
"""A numpy-like view over a subset of aggregates owned by a repository.
|
|
27
|
+
|
|
28
|
+
Extends the generic DataView with aggregate-specific filtering methods.
|
|
29
|
+
Uses SQL-based filtering via MetadataIndex for efficiency.
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
def __init__(
|
|
33
|
+
self,
|
|
34
|
+
*,
|
|
35
|
+
repository: AggregateRepository,
|
|
36
|
+
uids: list[EntityUID] | None = None,
|
|
37
|
+
) -> None:
|
|
38
|
+
super().__init__(repository=repository, uids=uids)
|
|
39
|
+
|
|
40
|
+
def __iter__(self) -> Iterator[AggregateProxy]:
|
|
41
|
+
"""Iterate aggregate proxies in view order."""
|
|
42
|
+
return super().__iter__()
|
|
43
|
+
|
|
44
|
+
def _sort_in_place(self) -> None:
|
|
45
|
+
"""Sort UIDs by field_name, context for deterministic ordering."""
|
|
46
|
+
uids = self._ensure_uids()
|
|
47
|
+
uids.sort(
|
|
48
|
+
key=lambda uid: (
|
|
49
|
+
self._repository.get_proxy(uid).meta.field_name,
|
|
50
|
+
",".join(sorted(self._repository.get_proxy(uid).meta.context_models)),
|
|
51
|
+
",".join(sorted(self._repository.get_proxy(uid).meta.context_params)),
|
|
52
|
+
uid,
|
|
53
|
+
)
|
|
54
|
+
)
|
|
55
|
+
self._sorted = True
|
|
56
|
+
|
|
57
|
+
def filter_by_field_name(
|
|
58
|
+
self, *names: str, inverse_mask: bool = False
|
|
59
|
+
) -> AggregateView:
|
|
60
|
+
"""Filter aggregates by field name.
|
|
61
|
+
|
|
62
|
+
Args:
|
|
63
|
+
*names: Field names to match. Use "re:" prefix for regex patterns.
|
|
64
|
+
inverse_mask: If True, return aggregates NOT matching the names.
|
|
65
|
+
|
|
66
|
+
Returns:
|
|
67
|
+
New view with filtered aggregates.
|
|
68
|
+
"""
|
|
69
|
+
# Separate exact matches from regex patterns
|
|
70
|
+
exact_names: list[str] = []
|
|
71
|
+
regex_patterns: list[re.Pattern[str]] = []
|
|
72
|
+
for name in names:
|
|
73
|
+
if name.startswith(REGEX_PREFIX):
|
|
74
|
+
regex_patterns.append(re.compile(name.removeprefix(REGEX_PREFIX)))
|
|
75
|
+
else:
|
|
76
|
+
exact_names.append(name)
|
|
77
|
+
|
|
78
|
+
# If only exact matches and no inverse, use SQL
|
|
79
|
+
if exact_names and not regex_patterns and not inverse_mask:
|
|
80
|
+
current_uids = self._uids
|
|
81
|
+
if current_uids is None:
|
|
82
|
+
# Query directly from index
|
|
83
|
+
filtered = self._repository.metadata_index.query(
|
|
84
|
+
TABLE_AGGREGATES,
|
|
85
|
+
where_in={"field_name": exact_names},
|
|
86
|
+
)
|
|
87
|
+
else:
|
|
88
|
+
# Filter within current UIDs
|
|
89
|
+
filtered = self._repository.metadata_index.query(
|
|
90
|
+
TABLE_AGGREGATES,
|
|
91
|
+
where_in={"field_name": exact_names, "uid": current_uids},
|
|
92
|
+
)
|
|
93
|
+
return AggregateView(repository=self._repository, uids=filtered)
|
|
94
|
+
|
|
95
|
+
# Fall back to in-memory filtering for regex or inverse
|
|
96
|
+
if not self._sorted:
|
|
97
|
+
self._sort_in_place()
|
|
98
|
+
|
|
99
|
+
uids = self._ensure_uids()
|
|
100
|
+
matches = build_matcher(names)
|
|
101
|
+
|
|
102
|
+
if not inverse_mask:
|
|
103
|
+
filtered = [
|
|
104
|
+
uid
|
|
105
|
+
for uid in uids
|
|
106
|
+
if matches(self._repository.get_proxy(uid).meta.field_name)
|
|
107
|
+
]
|
|
108
|
+
else:
|
|
109
|
+
filtered = [
|
|
110
|
+
uid
|
|
111
|
+
for uid in uids
|
|
112
|
+
if not matches(self._repository.get_proxy(uid).meta.field_name)
|
|
113
|
+
]
|
|
114
|
+
|
|
115
|
+
return AggregateView(repository=self._repository, uids=filtered)
|
|
116
|
+
|
|
117
|
+
def filter_by_context_models(
|
|
118
|
+
self, *model_ids: str, require_all: bool = False
|
|
119
|
+
) -> AggregateView:
|
|
120
|
+
"""Filter aggregates by participating models.
|
|
121
|
+
|
|
122
|
+
Args:
|
|
123
|
+
*model_ids: Model IDs that must be in the aggregate's context_models.
|
|
124
|
+
require_all: If True, all model_ids must be present. If False,
|
|
125
|
+
at least one must be present.
|
|
126
|
+
|
|
127
|
+
Returns:
|
|
128
|
+
New view with filtered aggregates.
|
|
129
|
+
"""
|
|
130
|
+
exact_names: set[str] = set()
|
|
131
|
+
regex_patterns: list[re.Pattern[str]] = []
|
|
132
|
+
for model_id in model_ids:
|
|
133
|
+
if model_id.startswith(REGEX_PREFIX):
|
|
134
|
+
regex_patterns.append(re.compile(model_id.removeprefix(REGEX_PREFIX)))
|
|
135
|
+
else:
|
|
136
|
+
exact_names.add(model_id)
|
|
137
|
+
|
|
138
|
+
if not self._sorted:
|
|
139
|
+
self._sort_in_place()
|
|
140
|
+
|
|
141
|
+
uids = self._ensure_uids()
|
|
142
|
+
|
|
143
|
+
def _matches(context_models: tuple[str, ...]) -> bool:
|
|
144
|
+
context_set = set(context_models)
|
|
145
|
+
|
|
146
|
+
if exact_names:
|
|
147
|
+
if require_all:
|
|
148
|
+
if not exact_names <= context_set:
|
|
149
|
+
return False
|
|
150
|
+
elif not (exact_names & context_set):
|
|
151
|
+
return False
|
|
152
|
+
|
|
153
|
+
if regex_patterns:
|
|
154
|
+
if require_all:
|
|
155
|
+
for pattern in regex_patterns:
|
|
156
|
+
if not any(
|
|
157
|
+
pattern.fullmatch(cm) is not None for cm in context_models
|
|
158
|
+
):
|
|
159
|
+
return False
|
|
160
|
+
elif not any(
|
|
161
|
+
any(pattern.fullmatch(cm) is not None for pattern in regex_patterns)
|
|
162
|
+
for cm in context_models
|
|
163
|
+
):
|
|
164
|
+
return False
|
|
165
|
+
|
|
166
|
+
return True
|
|
167
|
+
|
|
168
|
+
filtered = [
|
|
169
|
+
uid
|
|
170
|
+
for uid in uids
|
|
171
|
+
if _matches(self._repository.get_proxy(uid).meta.context_models)
|
|
172
|
+
]
|
|
173
|
+
|
|
174
|
+
return AggregateView(repository=self._repository, uids=filtered)
|
|
175
|
+
|
|
176
|
+
def filter_by_context_params(
|
|
177
|
+
self, *param_names: str, require_all: bool = False
|
|
178
|
+
) -> AggregateView:
|
|
179
|
+
"""Filter aggregates by participating parameters.
|
|
180
|
+
|
|
181
|
+
Args:
|
|
182
|
+
*param_names: Parameter names that must be in the aggregate's
|
|
183
|
+
context_params.
|
|
184
|
+
require_all: If True, all param_names must be present. If False,
|
|
185
|
+
at least one must be present.
|
|
186
|
+
|
|
187
|
+
Returns:
|
|
188
|
+
New view with filtered aggregates.
|
|
189
|
+
"""
|
|
190
|
+
exact_names: set[str] = set()
|
|
191
|
+
regex_patterns: list[re.Pattern[str]] = []
|
|
192
|
+
for param_name in param_names:
|
|
193
|
+
if param_name.startswith(REGEX_PREFIX):
|
|
194
|
+
regex_patterns.append(re.compile(param_name.removeprefix(REGEX_PREFIX)))
|
|
195
|
+
else:
|
|
196
|
+
exact_names.add(param_name)
|
|
197
|
+
|
|
198
|
+
if not self._sorted:
|
|
199
|
+
self._sort_in_place()
|
|
200
|
+
|
|
201
|
+
uids = self._ensure_uids()
|
|
202
|
+
|
|
203
|
+
def _matches(context_params: tuple[str, ...]) -> bool:
|
|
204
|
+
context_set = set(context_params)
|
|
205
|
+
|
|
206
|
+
if exact_names:
|
|
207
|
+
if require_all:
|
|
208
|
+
if not exact_names <= context_set:
|
|
209
|
+
return False
|
|
210
|
+
elif not (exact_names & context_set):
|
|
211
|
+
return False
|
|
212
|
+
|
|
213
|
+
if regex_patterns:
|
|
214
|
+
if require_all:
|
|
215
|
+
for pattern in regex_patterns:
|
|
216
|
+
if not any(
|
|
217
|
+
pattern.fullmatch(cp) is not None for cp in context_params
|
|
218
|
+
):
|
|
219
|
+
return False
|
|
220
|
+
elif not any(
|
|
221
|
+
any(pattern.fullmatch(cp) is not None for pattern in regex_patterns)
|
|
222
|
+
for cp in context_params
|
|
223
|
+
):
|
|
224
|
+
return False
|
|
225
|
+
|
|
226
|
+
return True
|
|
227
|
+
|
|
228
|
+
filtered = [
|
|
229
|
+
uid
|
|
230
|
+
for uid in uids
|
|
231
|
+
if _matches(self._repository.get_proxy(uid).meta.context_params)
|
|
232
|
+
]
|
|
233
|
+
|
|
234
|
+
return AggregateView(repository=self._repository, uids=filtered)
|
|
235
|
+
|
|
236
|
+
def filter_by_exact_context(
|
|
237
|
+
self,
|
|
238
|
+
*,
|
|
239
|
+
models: tuple[str, ...] | None = None,
|
|
240
|
+
params: tuple[str, ...] | None = None,
|
|
241
|
+
) -> AggregateView:
|
|
242
|
+
"""Filter aggregates by exact context match.
|
|
243
|
+
|
|
244
|
+
Unlike filter_by_context_models/params which use set intersection,
|
|
245
|
+
this method requires exact equality of the context tuples.
|
|
246
|
+
|
|
247
|
+
Args:
|
|
248
|
+
models: Exact context_models tuple to match. If None, any models match.
|
|
249
|
+
params: Exact context_params tuple to match. If None, any params match.
|
|
250
|
+
|
|
251
|
+
Returns:
|
|
252
|
+
New view with aggregates matching the exact context.
|
|
253
|
+
"""
|
|
254
|
+
if not self._sorted:
|
|
255
|
+
self._sort_in_place()
|
|
256
|
+
|
|
257
|
+
uids = self._ensure_uids()
|
|
258
|
+
|
|
259
|
+
def _matches(proxy: AggregateProxy) -> bool:
|
|
260
|
+
if models is not None and proxy.meta.context_models != models:
|
|
261
|
+
return False
|
|
262
|
+
return not (params is not None and proxy.meta.context_params != params)
|
|
263
|
+
|
|
264
|
+
filtered = [uid for uid in uids if _matches(self._repository.get_proxy(uid))]
|
|
265
|
+
|
|
266
|
+
return AggregateView(repository=self._repository, uids=filtered)
|
|
267
|
+
|
|
268
|
+
def erase_fields(self, *fields: str) -> None:
|
|
269
|
+
"""Erase fields from all aggregates in this view."""
|
|
270
|
+
uids = self._ensure_uids()
|
|
271
|
+
if not uids:
|
|
272
|
+
return
|
|
273
|
+
|
|
274
|
+
with self:
|
|
275
|
+
for field in fields:
|
|
276
|
+
self._repository.storage_manager.erase_field_for_all(
|
|
277
|
+
field, table=TABLE_AGGREGATES
|
|
278
|
+
)
|
|
279
|
+
if self._repository.cache_manager is not None:
|
|
280
|
+
self._repository.cache_manager.erase_field_for_all(field)
|
|
281
|
+
|
|
282
|
+
def clear(self, erase: bool = False) -> None:
|
|
283
|
+
"""Clear this view and optionally erase corresponding data.
|
|
284
|
+
|
|
285
|
+
Args:
|
|
286
|
+
erase: If True, also erase underlying storage data.
|
|
287
|
+
If False, only clear membership (metadata index).
|
|
288
|
+
"""
|
|
289
|
+
uids = self._ensure_uids()
|
|
290
|
+
|
|
291
|
+
if erase and self._repository.cache_manager is not None:
|
|
292
|
+
self._repository.cache_manager.clear()
|
|
293
|
+
|
|
294
|
+
with self._repository:
|
|
295
|
+
for uid in list(uids):
|
|
296
|
+
self._repository._proxy_cache.pop(uid, None)
|
|
297
|
+
self._repository.metadata_index.delete(TABLE_AGGREGATES, uid)
|
|
298
|
+
if erase:
|
|
299
|
+
self._repository.storage_manager.erase_obj(
|
|
300
|
+
uid, table=TABLE_AGGREGATES
|
|
301
|
+
)
|
|
302
|
+
|
|
303
|
+
if self._uids is not None:
|
|
304
|
+
self._uids.clear()
|
|
305
|
+
else:
|
|
306
|
+
self._uids = []
|
|
307
|
+
self._sorted = True
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
"""Dependency injection containers for model parameter management.
|
|
2
|
+
|
|
3
|
+
This module provides dependency injection configuration for model parameter
|
|
4
|
+
extraction and collection management using the dependency-injector library.
|
|
5
|
+
It integrates parameter extractors, storage managers, metadata index, and
|
|
6
|
+
cache managers for comprehensive parameter lifecycle management.
|
|
7
|
+
|
|
8
|
+
The container provides factory methods for creating parameter extractors
|
|
9
|
+
and initializing parameter collections, ensuring proper dependency
|
|
10
|
+
injection and configuration management.
|
|
11
|
+
|
|
12
|
+
Example:
|
|
13
|
+
>>> container = ModelParametersContainer()
|
|
14
|
+
>>> container.config.extractor.framework.from_value("pytorch")
|
|
15
|
+
>>> container.storage_manager.override(storage_instance)
|
|
16
|
+
>>> container.metadata_index.override(metadata_instance)
|
|
17
|
+
>>> container.cache_manager.override(cache_instance)
|
|
18
|
+
>>> collection = container.parameter_repository()
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
from __future__ import annotations
|
|
22
|
+
|
|
23
|
+
from dependency_injector import containers, providers
|
|
24
|
+
|
|
25
|
+
from diffract.core.data.metadata.interface import IMetadataIndex
|
|
26
|
+
from diffract.core.parallel import ParallelContext
|
|
27
|
+
from diffract.core.storage.interface import IStorageManager
|
|
28
|
+
from diffract.core.utils.build import build_with_defaults
|
|
29
|
+
|
|
30
|
+
from .aggregates.repository import AggregateRepository
|
|
31
|
+
from .extractors.factory import create_extractor
|
|
32
|
+
from .params.repository import ParameterRepository
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class ModelParametersContainer(containers.DeclarativeContainer):
|
|
36
|
+
"""Dependency injection container for model parameter components.
|
|
37
|
+
|
|
38
|
+
Provides comprehensive dependency injection setup for parameter extraction,
|
|
39
|
+
collection management, and data lifecycle operations. The container manages
|
|
40
|
+
the integration between parameter extractors, storage systems, metadata index,
|
|
41
|
+
and caching mechanisms.
|
|
42
|
+
|
|
43
|
+
The container uses external dependencies for storage, metadata index, and
|
|
44
|
+
cache managers, allowing flexible backend configuration while maintaining
|
|
45
|
+
consistent parameter extraction and collection interfaces.
|
|
46
|
+
|
|
47
|
+
Attributes:
|
|
48
|
+
config: Configuration provider for parameter extraction settings.
|
|
49
|
+
storage_manager: External dependency for persistent storage.
|
|
50
|
+
metadata_index: External dependency for structured metadata.
|
|
51
|
+
cache_manager: External dependency for temporary caching.
|
|
52
|
+
extractor_factory: Factory for creating parameter extractors.
|
|
53
|
+
parameter_repository: Singleton for parameter repository.
|
|
54
|
+
aggregate_repository: Singleton for aggregate repository.
|
|
55
|
+
"""
|
|
56
|
+
|
|
57
|
+
config = providers.Configuration()
|
|
58
|
+
|
|
59
|
+
# External dependencies (injected from parent containers)
|
|
60
|
+
storage_manager = providers.Dependency(instance_of=IStorageManager)
|
|
61
|
+
metadata_index = providers.Dependency(instance_of=IMetadataIndex)
|
|
62
|
+
cache_manager = providers.Dependency()
|
|
63
|
+
parallel = providers.Dependency(instance_of=ParallelContext)
|
|
64
|
+
|
|
65
|
+
parameter_repository = providers.Singleton(
|
|
66
|
+
ParameterRepository.initialize,
|
|
67
|
+
storage_manager=storage_manager,
|
|
68
|
+
metadata_index=metadata_index,
|
|
69
|
+
cache_manager=cache_manager,
|
|
70
|
+
parallel=parallel,
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
aggregate_repository = providers.Singleton(
|
|
74
|
+
AggregateRepository.initialize,
|
|
75
|
+
storage_manager=storage_manager,
|
|
76
|
+
metadata_index=metadata_index,
|
|
77
|
+
cache_manager=cache_manager,
|
|
78
|
+
parallel=parallel,
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
# Parameter extractor factories
|
|
82
|
+
extractor_factory = providers.Factory(
|
|
83
|
+
build_with_defaults,
|
|
84
|
+
create_extractor,
|
|
85
|
+
config.extractor.as_(dict),
|
|
86
|
+
)
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"""Parameter extraction framework for neural network models.
|
|
2
|
+
|
|
3
|
+
This module provides a comprehensive framework for extracting parameters from
|
|
4
|
+
neural network models across different deep learning frameworks. It uses a
|
|
5
|
+
handler-based architecture for extensible and framework-specific parameter
|
|
6
|
+
processing.
|
|
7
|
+
|
|
8
|
+
Key Features:
|
|
9
|
+
- Framework-agnostic parameter extraction interface
|
|
10
|
+
- Handler-based processing for different parameter types
|
|
11
|
+
- Factory pattern for automatic extractor creation
|
|
12
|
+
- Override system for custom parameter metadata
|
|
13
|
+
- Extensible architecture for new frameworks and parameter types
|
|
14
|
+
|
|
15
|
+
Supported Frameworks:
|
|
16
|
+
- NumPy: dict[str, numpy.ndarray] mappings (no framework required)
|
|
17
|
+
- PyTorch: nn.Module and state_dict extraction
|
|
18
|
+
- Extensible design for additional frameworks
|
|
19
|
+
|
|
20
|
+
Example:
|
|
21
|
+
>>> from diffract.core.data.nn.extractors import create_extractor
|
|
22
|
+
>>> extractor = create_extractor(pytorch_model)
|
|
23
|
+
>>> parameters = extractor.extract_parameters(storage, cache)
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
from .base import BaseParameterExtractor, ExtractorOverrides, ParameterOverrides
|
|
27
|
+
from .factory import create_extractor, get_supported_frameworks, get_supported_types
|
|
28
|
+
from .flax import FlaxParamsExtractor
|
|
29
|
+
from .interface import IParameterExtractor
|
|
30
|
+
from .numpy import NumpyDictExtractor
|
|
31
|
+
from .onnx import OnnxModelExtractor
|
|
32
|
+
from .tensorflow import TensorFlowModelExtractor
|
|
33
|
+
from .torch import TorchModuleExtractor, TorchStateDictExtractor
|
|
34
|
+
|
|
35
|
+
__all__ = [
|
|
36
|
+
"BaseParameterExtractor",
|
|
37
|
+
"ExtractorOverrides",
|
|
38
|
+
"FlaxParamsExtractor",
|
|
39
|
+
"IParameterExtractor",
|
|
40
|
+
"NumpyDictExtractor",
|
|
41
|
+
"OnnxModelExtractor",
|
|
42
|
+
"ParameterOverrides",
|
|
43
|
+
"TensorFlowModelExtractor",
|
|
44
|
+
"TorchModuleExtractor",
|
|
45
|
+
"TorchStateDictExtractor",
|
|
46
|
+
"create_extractor",
|
|
47
|
+
"get_supported_frameworks",
|
|
48
|
+
"get_supported_types",
|
|
49
|
+
]
|