mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-05 23:41:44 +00:00
IfcGeom: make no-parallel-mapping and permissive-shape-reuse usable with threads #6712
Iterator::initialize() disabled mapping caching whenever the iterator was constructed with more than one thread, including in no-parallel-mapping mode where all mapping happens upfront on the calling thread. Without the cache, the shared representation of a mapped item was remapped once per product (9210 times in the first attachment of #6712), so initialize() appeared to hang, and the permissive-shape-reuse folding, which merges tasks by cached item pointer identity, silently never folded. Both effects were reported in the issue thread. Caching is now only disabled when parallel mapping will actually run in the worker threads. In no-parallel-mapping mode the iterator falls back to sequential processing, since cache-shared taxonomy items are not yet safe to convert concurrently (cf. the immutability todo). Additionally, permissive-shape-reuse now implies no-parallel-mapping inside the iterator itself, mirroring what IfcConvert already forced, so library users get the folding without knowing about the coupling. With this, the reporter's configuration (permissive-shape-reuse with hardware_concurrency threads) completes the 12 MB attachment in 1.4 s instead of hanging; output is identical to the previously working single-threaded configuration. Generated with the assistance of an AI coding tool.
This commit is contained in:
@@ -23,10 +23,26 @@ bool IfcGeom::Iterator::initialize() {
|
||||
}
|
||||
|
||||
time_points[0] = high_resolution_clock::now();
|
||||
|
||||
if (settings_.get<ifcopenshell::geometry::settings::PermissiveShapeReuse>().get() && !settings_.get<ifcopenshell::geometry::settings::NoParallelMapping>().get()) {
|
||||
// Folding tasks based on permissive shape reuse requires the upfront mapping
|
||||
settings_.get<ifcopenshell::geometry::settings::NoParallelMapping>().value = true;
|
||||
logger_.Notice("SYS", 36, "Enabled no-parallel-mapping due to permissive-shape-reuse");
|
||||
}
|
||||
|
||||
std::vector<ifcopenshell::geometry::geometry_conversion_task> reps;
|
||||
if (num_threads_ != 1) {
|
||||
// @todo this shouldn't be necessary with properly immutable taxonomy items
|
||||
converter_->mapping()->use_caching() = false;
|
||||
if (!settings_.get<ifcopenshell::geometry::settings::NoParallelMapping>().get()) {
|
||||
// @todo this shouldn't be necessary with properly immutable taxonomy items
|
||||
converter_->mapping()->use_caching() = false;
|
||||
} else {
|
||||
// The upfront mapping below runs on this thread with caching, which is
|
||||
// what makes instance reuse (and the permissive-shape-reuse folding)
|
||||
// effective, but cache-shared taxonomy items cannot be converted
|
||||
// concurrently yet, cf. the immutability @todo above
|
||||
num_threads_ = 1;
|
||||
logger_.Notice("SYS", 37, "Processing sequentially due to no-parallel-mapping");
|
||||
}
|
||||
}
|
||||
try {
|
||||
converter_->mapping()->get_representations(reps, filters_);
|
||||
|
||||
Reference in New Issue
Block a user