Skip to content

Commit e8f27a2

Browse files
committed
Truncate compression dict training if it gets too big.
1 parent bd930ef commit e8f27a2

3 files changed

Lines changed: 26 additions & 1 deletion

File tree

doc/changes/DM-55232.bugfix.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix zstd failure in `butler aggregate-graph` when logs are really huge.

python/lsst/pipe/base/quantum_graph/aggregator/_config.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,11 @@ class AggregatorConfig(pydantic.BaseModel):
136136
logs, and metadata blocks encountered.
137137
"""
138138

139+
zstd_dict_input_max_bytes: int = 1_048_576
140+
"""Maximum total size of the ZStandard compression dictionary training
141+
sample.
142+
"""
143+
139144
mock_storage_classes: bool = False
140145
"""Enable support for storage classes by created by the
141146
lsst.pipe.base.tests.mocks package.

python/lsst/pipe/base/quantum_graph/aggregator/_writer.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,15 +172,34 @@ def make_compression_dictionary(self) -> zstandard.ZstdCompressionDict:
172172
# chop out the datastore records since those don't appear in the
173173
# provenance graph.
174174
n_pred_quanta: int = 0
175+
training_sample_size: int = 0
175176
for predicted_quantum in self.predicted.quantum_datasets.values():
176177
if len(training_inputs) == self.comms.config.zstd_dict_n_inputs:
177178
break
178179
predicted_quantum.datastore_records.clear()
179-
training_inputs.append(predicted_quantum.model_dump_json().encode())
180+
block = predicted_quantum.model_dump_json().encode()
181+
training_sample_size += len(block)
182+
if training_sample_size >= self.comms.config.zstd_dict_input_max_bytes:
183+
self.comms.log.warning(
184+
"Reached compression dict training sample size limit at %d predicted quanta.",
185+
len(training_inputs),
186+
)
187+
break
188+
training_inputs.append(block)
189+
training_sample_size += len(block)
180190
n_pred_quanta += 1
181191
# Add the provenance quanta, metadata, and logs we've accumulated.
182192
for write_request in self.pending_compression_training:
183193
assert not write_request.is_compressed, "We can't compress without the compression dictionary."
194+
training_sample_size += len(write_request.quantum)
195+
training_sample_size += len(write_request.metadata)
196+
training_sample_size += len(write_request.logs)
197+
if training_sample_size >= self.comms.config.zstd_dict_input_max_bytes:
198+
self.comms.log.warning(
199+
"Reached compression dict training sample size limit at %d blocks.",
200+
len(training_inputs),
201+
)
202+
break
184203
training_inputs.append(write_request.quantum)
185204
training_inputs.append(write_request.metadata)
186205
training_inputs.append(write_request.logs)

0 commit comments

Comments
 (0)