Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
109 commits
Select commit Hold shift + click to select a range
eab8494
BUG: Preserve cumulative parallel storage requirements
jmarquisbq Sep 29, 2026
9502eaa
BUG: Preserve array selection storage constraints
jmarquisbq Sep 29, 2026
6f76b9b
BUG: Validate KMeans cluster counts and default to one
jmarquisbq Sep 29, 2026
42248cf
BUG: Report checked store flush failures
jmarquisbq Sep 30, 2026
4c61ae6
BUG: Report pipeline completion and recovery write failures
jmarquisbq Oct 1, 2026
3d76500
ENH: Add caller-owned HDF5 chunk-shape scratch
jmarquisbq Oct 2, 2026
613273d
BUG: Validate HDF5 write selections before transfer
jmarquisbq Oct 2, 2026
c6211d6
BUG: Plan selected imports against the complete destination
jmarquisbq Oct 2, 2026
b870ff1
BUG: Check Avizo output and close streams on failure
jmarquisbq Oct 3, 2026
6eb1a4c
BUG: Add budgeted numeric extent reads for sampled ranges
jmarquisbq Oct 3, 2026
64cc60c
BUG: Validate OOC thresholds and retain startup corrections
jmarquisbq Oct 3, 2026
4ddcb33
PERF: Batch Identify Sample YZ transfers
jmarquisbq Oct 3, 2026
6f01a1c
COMP: Use aggregate initialization for the Avizo test handler
jmarquisbq Oct 5, 2026
a2ac458
COMP: Avoid inherited field shadowing in Avizo writer tests
jmarquisbq Oct 5, 2026
b721029
COMP: Make Identify Sample test fixture types explicit
jmarquisbq Oct 5, 2026
743bd3f
COMP: Fix Linux compiler error
imikejackson Oct 5, 2026
fea2914
COMP: Fix compiler warning in MacOS.
imikejackson Oct 5, 2026
3ecbad1
COMP: Avoid streaming file-clock durations in import tests
imikejackson Oct 5, 2026
dc46b5b
TEST: Match recovery warnings to import validation order
imikejackson Oct 5, 2026
1fc1d6c
TEST: Fix failing CI Test
imikejackson Oct 5, 2026
eb75eab
COMP: Accept reviewed Apple libc++ 18.1 for bounded reads
imikejackson Oct 6, 2026
b839590
TEST: Guard bounded result access before front()
imikejackson Oct 6, 2026
c5e2e5f
COMP: Accept reviewed GCC 11.4 libstdc++ for bounded reads
imikejackson Oct 7, 2026
354c266
PERF: Bulk-load Laplacian Smoothing data for out-of-core stores
imikejackson Oct 7, 2026
8356a73
TEST: Stop running network-dependent citation check in CTest
imikejackson Oct 7, 2026
e5844b4
PERF: Add a block-sequential out-of-core path for triangle normals
imikejackson Oct 7, 2026
7cdbf80
PERF: Add a block-sequential out-of-core path for triangle dihedral a…
imikejackson Oct 7, 2026
9d418d6
PERF: Add a block-sequential out-of-core path for face IPF coloring
imikejackson Oct 7, 2026
a47fc17
PERF: Add a block-sequential out-of-core path for feature face misori…
imikejackson Oct 7, 2026
50f9ad7
PERF: Add a block-sequential out-of-core path for shared feature faces
imikejackson Oct 7, 2026
03921a5
PERF: Stage winding repair connectivity in scratch records for out-of…
imikejackson Oct 7, 2026
d6071ca
BUG: Preserve numeric growth initialization across store types
jmarquisbq Oct 6, 2026
4eb8733
DOC: Describe sampler fixed-memory observation data
jmarquisbq Oct 6, 2026
e70a589
STY: Remove trailing whitespace from Identify Sample test
jmarquisbq Oct 8, 2026
7e72079
COMP: Support reviewed GCC 13 bounded-read allocations
jmarquisbq Oct 8, 2026
3c27c99
COMP: Temporarily capture native CI library headers
jmarquisbq Oct 8, 2026
47b564c
COMP: Admit reviewed Apple libc++ bounded reads
jmarquisbq Oct 8, 2026
f2f5c81
TEST: Verify Laplacian smoothing with analytic coordinates
jmarquisbq Oct 8, 2026
5bf95fb
TEST: Cover Laplacian transfer failures and cancellation
jmarquisbq Oct 8, 2026
14308be
TEST: Verify Triangle Normal algorithm paths and resident stores
jmarquisbq Oct 9, 2026
bb0ad2a
TEST: Verify Triangle Dihedral Angle paths and resident stores
jmarquisbq Oct 9, 2026
0ed0868
TEST: Isolate public test runner preferences
jmarquisbq Oct 9, 2026
a47bc41
TEST: Verify shared feature face algorithm and store paths
jmarquisbq Oct 9, 2026
2faca14
TEST: Verify winding normal repair paths and resident stores
jmarquisbq Oct 9, 2026
fc8980e
TEST: Cover resident Face IPF algorithm scenarios
jmarquisbq Oct 9, 2026
3f2e4e1
TEST: Cover resident face misorientation algorithm scenarios
jmarquisbq Oct 9, 2026
4a83b33
TEST: Reject wrong-backend stores in nullable factory tests
jmarquisbq Oct 9, 2026
e40bd0b
TEST: Share Catch execution and Application cleanup helpers
jmarquisbq Oct 9, 2026
7ddef46
TEST: Move Face IPF disk coverage to the private OOC suite
jmarquisbq Oct 9, 2026
2da4dee
TEST: Move face misorientation disk coverage to the OOC suite
jmarquisbq Oct 9, 2026
0453067
TEST: Cover IdentifySample orthogonal failures and cancellation
jmarquisbq Oct 9, 2026
8229fad
TEST: Verify public algorithm scope restoration after throws
jmarquisbq Oct 9, 2026
9ce05d1
TEST: Compare complete INL writer output and reject bad tails
jmarquisbq Oct 9, 2026
98fb91d
TEST: Cover neighbor misorientations with averaging disabled
jmarquisbq Oct 9, 2026
adc4404
TEST: Cover c-axis misalignments with averaging disabled
jmarquisbq Oct 9, 2026
d898f6c
TEST: Cover buffered triangle winding transfers and cancellation
jmarquisbq Oct 9, 2026
4ccf8c0
TEST: Check geometry normal utility values and cancellation
jmarquisbq Oct 9, 2026
a02cc8a
TEST: Cover triangle normal block transfers and cancellation
jmarquisbq Oct 9, 2026
db6ac82
TEST: Cover dihedral angle block transfers and cancellation
jmarquisbq Oct 9, 2026
6b9224c
TEST: Verify average-orientation voxel ordering on both paths
jmarquisbq Oct 9, 2026
aaec3f5
TEST: Verify complete ASCII structured-points output
jmarquisbq Oct 9, 2026
27269b0
TEST: Reject watershed markers without temporary storage support
jmarquisbq Oct 9, 2026
095873a
TEST: Reject watershed without temporary storage support
jmarquisbq Oct 9, 2026
81bd60d
TEST: Check analytical interior surface metrics
jmarquisbq Oct 10, 2026
4aa712a
TEST: Verify resident stores throughout image contouring
jmarquisbq Oct 10, 2026
7d15cb2
TEST: Preserve normals when winding-only repair is selected
jmarquisbq Oct 10, 2026
fec2826
TEST: Reject mismatched NaNs in floating-array comparisons
jmarquisbq Oct 10, 2026
535c5ba
DOC: Correct MultiThresholdObjects verification inventory
jmarquisbq Oct 12, 2026
a328bf0
COMP: Remove temporary native toolchain capture
jmarquisbq Oct 12, 2026
445e2fa
ENH: Reserve optional working memory without cache eviction
jmarquisbq Oct 13, 2026
e0b6649
BUG: Compute exact arithmetic centroids across periodic boundaries
jmarquisbq Oct 15, 2026
adf935c
PERF: Batch out-of-core triangle winding volume and reversal
jmarquisbq Oct 16, 2026
6fa2256
BUG: Reject invalid vertices in buffered triangle calculations
jmarquisbq Oct 19, 2026
446b2c9
BUG: Bound new out-of-core mesh working buffers
jmarquisbq Oct 19, 2026
a445744
COMP: Use explicit types for centroid test budgets
jmarquisbq Oct 19, 2026
4a1136f
REV: Match KMeans default test to float64 means
jmarquisbq Oct 19, 2026
30b4eb6
TEST: Correct H5Oina batch-tail raster coordinates
jmarquisbq Oct 20, 2026
7b0b0ca
COMP: Fix MSVC test builds and remove unused includes
jmarquisbq Oct 20, 2026
3d45c4c
DOC: Clarify bounded mesh buffer contracts
jmarquisbq Oct 20, 2026
1f3b449
BUG: Bound OOC face orientation lookup buffers
jmarquisbq Oct 20, 2026
b08517e
BUG: Stream OOC shared face metadata through admitted blocks
jmarquisbq Oct 20, 2026
001ffc8
REV: Restore the owning default resolver after test scopes
jmarquisbq Oct 21, 2026
3b7c1ab
REV: Remap geometry references for each imported alias
jmarquisbq Oct 21, 2026
4274daa
REV: Share algorithm override precedence with triangle winding
jmarquisbq Oct 21, 2026
b59ea3b
REV: Apply the shared algorithm policy to mesh smoothing
jmarquisbq Oct 21, 2026
933296f
REV: Honor override precedence in Zero Crossing
jmarquisbq Oct 21, 2026
b24a94e
REV: Make bounded-read ownership explicit
jmarquisbq Oct 21, 2026
5ea0175
REV: Clarify HDF5 codec and chunk helper contracts
jmarquisbq Oct 21, 2026
08ed84e
REV: Clarify private import and publication helpers
jmarquisbq Oct 21, 2026
928deb8
REV: Clarify pipeline diagnostics and core helper ownership
jmarquisbq Oct 21, 2026
b840459
REV: Clarify bounded orientation lookup helpers
jmarquisbq Oct 21, 2026
75108b6
REV: Clarify centroid working-buffer ownership
jmarquisbq Oct 21, 2026
d131d55
REV: Include KMeans declaration providers directly
jmarquisbq Oct 21, 2026
367d302
REV: Clarify component-labeling helper state
jmarquisbq Oct 21, 2026
2633608
REV: Clarify bounded mesh helper ownership and diagnostics
jmarquisbq Oct 21, 2026
2c06df7
REV: Use fixed scratch arrays for triangle angles
jmarquisbq Oct 21, 2026
1da1c94
REV: Clarify Avizo writer state and diagnostics
jmarquisbq Oct 21, 2026
0bd02e9
REV: Make regression fixture contracts explicit
jmarquisbq Oct 21, 2026
5fc3872
REV: Make geometry remapper ownership explicit
jmarquisbq Oct 21, 2026
ac02e25
TEST: Restore the incoming resolver after selected-import tests
jmarquisbq Oct 22, 2026
f3c63f4
REV: Declare special members for scoped helpers and fixtures
jmarquisbq Oct 22, 2026
67bdc2c
REV: Use standard arrays for hexadecimal lookup tables
jmarquisbq Oct 22, 2026
ec235c1
TEST: Avoid shadowing the saved resolver capture
jmarquisbq Oct 22, 2026
3aa2129
REV: Use pointer suffixes in selected-import tests
jmarquisbq Oct 22, 2026
96a0a69
REV: Keep import publication and rollback in DataStructure
jmarquisbq Oct 22, 2026
8b5304d
STY: Declare special members for new core helpers
jmarquisbq Oct 22, 2026
98022e9
REV: Address review findings for the OOC review fixes
joeykleingers Oct 27, 2026
2d6cc01
ENH: Store the out-of-core size thresholds in GB
joeykleingers Oct 28, 2026
1fc079b
COMP: Compare file times as bool in the GB preference test
joeykleingers Oct 28, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,7 @@ set(SIMPLNX_HDRS
${SIMPLNX_SOURCE_DIR}/Common/Constants.hpp
${SIMPLNX_SOURCE_DIR}/Common/DataTypeUtilities.hpp
${SIMPLNX_SOURCE_DIR}/Common/DataVector.hpp
${SIMPLNX_SOURCE_DIR}/Common/BoundedRead.hpp
${SIMPLNX_SOURCE_DIR}/Common/Extent.hpp
${SIMPLNX_SOURCE_DIR}/Common/EulerAngle.hpp
${SIMPLNX_SOURCE_DIR}/Common/Filesystem.hpp
Expand Down Expand Up @@ -868,6 +869,7 @@ set(SIMPLNX_SRCS
${SIMPLNX_SOURCE_DIR}/Utilities/Parsing/HDF5/ChunkShapePolicy.cpp
${SIMPLNX_SOURCE_DIR}/Utilities/Parsing/HDF5/DeflateEligibility.cpp
${SIMPLNX_SOURCE_DIR}/Utilities/Parsing/HDF5/ParallelChunkCodec.cpp
${SIMPLNX_SOURCE_DIR}/Utilities/Parsing/HDF5/BoundedChunkRead.cpp

${SIMPLNX_SOURCE_DIR}/Utilities/Parsing/HDF5/IO/DatasetIO.cpp
${SIMPLNX_SOURCE_DIR}/Utilities/Parsing/HDF5/IO/FileIO.cpp
Expand Down Expand Up @@ -1021,6 +1023,30 @@ foreach(plugin ${SIMPLNX_PLUGIN_LIST})
simplnx_add_plugin(PLUGIN_NAME ${plugin})
endforeach()

# Register the completion acceptance cases after their real fixture/writer plugins exist.
if(BUILD_TESTING AND SIMPLNX_BUILD_TESTS AND SIMPLNX_PLUGIN_ENABLE_TestOne AND SIMPLNX_ENABLE_SimplnxCore AND SIMPLNX_PLUGIN_ENABLE_SimplnxCore)
foreach(_completion_target IN ITEMS nxrunner TestOne SimplnxCore)
if(NOT TARGET ${_completion_target})
message(FATAL_ERROR "Completion CLI tests require target '${_completion_target}' after plugin registration")
endif()
endforeach()
add_dependencies(nxrunner TestOne SimplnxCore)
foreach(_completion_mode IN ITEMS unarmed flush execute_and_flush allocation snapshot root_snapshot snapshot_allocation)
add_test(NAME "nxrunner_pipeline_flush_${_completion_mode}"
COMMAND ${CMAKE_COMMAND}
"-DNXRUNNER_EXECUTABLE=$<TARGET_FILE:nxrunner>"
"-DTEST_MODE=${_completion_mode}"
"-DSCRATCH_ROOT=${simplnx_BINARY_DIR}/CTestPipelineFlush/${_completion_mode}/$<CONFIG>"
-P "${simplnx_SOURCE_DIR}/src/nxrunner/test/PipelineFlushReachesUserTest.cmake"
)
set_tests_properties("nxrunner_pipeline_flush_${_completion_mode}" PROPERTIES
RUN_SERIAL TRUE
TIMEOUT 120
WORKING_DIRECTORY $<TARGET_FILE_DIR:nxrunner>
)
endforeach()
endif()

# Benchmarking utility
if(SIMPLNX_ENABLE_BENCHMARK_UTILITY)
add_subdirectory(utilities/benchmark)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
#pragma once

#include "simplnx/Core/Preferences.hpp"

#include <nlohmann/json.hpp>

#include <stdexcept>

namespace ip_bench
{
/**
* @brief Restores exact explicit storage preferences after a benchmark scope.
*
* The benchmark tools do not link UnitTestCommon. This guard changes only the
* in-memory Preferences object and does not save a preferences file.
*/
class BenchmarkPreferenceSnapshot
{
public:
/**
* @brief Validates and applies a temporary storage mode and threshold.
* @param preferences Preference object to change and restore.
* @param mode Temporary storage mode.
* @param temporaryThreshold Signed temporary threshold in bytes.
*/
BenchmarkPreferenceSnapshot(nx::core::Preferences& preferences, nx::core::DataStorageMode mode, nx::core::int64 temporaryThreshold = 0)
: m_Preferences(preferences)
, m_HadMode(preferences.contains(nx::core::Preferences::k_DataStorageMode_Key))
, m_OriginalMode(preferences.value(nx::core::Preferences::k_DataStorageMode_Key))
, m_HadThreshold(preferences.contains(nx::core::Preferences::k_LargeDataSize_Key))
, m_OriginalThreshold(preferences.value(nx::core::Preferences::k_LargeDataSize_Key))
{
const nlohmann::json proposed(temporaryThreshold);
const auto validation = nx::core::Preferences::ValidateOocSizeValue(nx::core::Preferences::k_LargeDataSize_Key, proposed);
if(validation.invalid())
{
throw std::invalid_argument(validation.errors().front().message);
}
m_Preferences.setDataStorageMode(mode);
m_Preferences.setValue(nx::core::Preferences::k_LargeDataSize_Key, proposed);
}

~BenchmarkPreferenceSnapshot()
{
if(m_HadThreshold)
{
m_Preferences.setValue(nx::core::Preferences::k_LargeDataSize_Key, m_OriginalThreshold);
}
else
{
m_Preferences.removeValue(nx::core::Preferences::k_LargeDataSize_Key);
}
if(m_HadMode)
{
m_Preferences.setValue(nx::core::Preferences::k_DataStorageMode_Key, m_OriginalMode);
}
else
{
m_Preferences.removeValue(nx::core::Preferences::k_DataStorageMode_Key);
}
}

BenchmarkPreferenceSnapshot(const BenchmarkPreferenceSnapshot&) = delete;
BenchmarkPreferenceSnapshot(BenchmarkPreferenceSnapshot&&) = delete;
BenchmarkPreferenceSnapshot& operator=(const BenchmarkPreferenceSnapshot&) = delete;
BenchmarkPreferenceSnapshot& operator=(BenchmarkPreferenceSnapshot&&) = delete;

private:
nx::core::Preferences& m_Preferences;
bool m_HadMode = false;
nlohmann::json m_OriginalMode;
bool m_HadThreshold = false;
nlohmann::json m_OriginalThreshold;
};
} // namespace ip_bench
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#define CATCH_CONFIG_MAIN

#include "BenchmarkPreferenceSnapshot.hpp"

#include <catch2/catch.hpp>

#include <limits>
#include <stdexcept>

using namespace nx::core;

TEST_CASE("Benchmark preference snapshot restores exact JSON and key presence", "[Core][Preferences][OocThreshold]")
{
for(const auto& original : {nlohmann::json(int64{0}), nlohmann::json(int64{37}), nlohmann::json(uint64{0}), nlohmann::json(uint64{37}), nlohmann::json(std::numeric_limits<uint64>::max())})
{
DYNAMIC_SECTION(original.dump() << " type=" << static_cast<int>(original.type()))
{
Preferences preferences;
preferences.setValue(Preferences::k_LargeDataSize_Key, original);
preferences.setDataStorageMode(DataStorageMode::Adaptive);
const auto mode = preferences.value(Preferences::k_DataStorageMode_Key);
{
ip_bench::BenchmarkPreferenceSnapshot snapshot(preferences, DataStorageMode::ForceInCore, 19);
CHECK(preferences.valueAs<uint64>(Preferences::k_LargeDataSize_Key) == 19);
CHECK(preferences.dataStorageMode() == DataStorageMode::ForceInCore);
}
const auto restored = preferences.value(Preferences::k_LargeDataSize_Key);
REQUIRE(preferences.contains(Preferences::k_LargeDataSize_Key));
REQUIRE(restored.type() == original.type());
CHECK(restored.get<uint64>() == original.get<uint64>());
CHECK(preferences.value(Preferences::k_DataStorageMode_Key) == mode);
CHECK(preferences.value(Preferences::k_DataStorageMode_Key).type() == mode.type());
CHECK(preferences.contains(Preferences::k_DataStorageMode_Key));
}
}

Preferences absent;
absent.removeValue(Preferences::k_LargeDataSize_Key);
absent.removeValue(Preferences::k_DataStorageMode_Key);
{
ip_bench::BenchmarkPreferenceSnapshot snapshot(absent, DataStorageMode::ForceOutOfCore);
CHECK(absent.valueAs<uint64>(Preferences::k_LargeDataSize_Key) == 0);
}
CHECK_FALSE(absent.contains(Preferences::k_LargeDataSize_Key));
CHECK_FALSE(absent.contains(Preferences::k_DataStorageMode_Key));
}

TEST_CASE("Benchmark preference snapshot rejects a negative threshold before mode mutation", "[Core][Preferences][OocThreshold]")
{
Preferences preferences;
preferences.setValue(Preferences::k_LargeDataSize_Key, std::numeric_limits<uint64>::max());
preferences.setDataStorageMode(DataStorageMode::Adaptive);
const auto originalThreshold = preferences.value(Preferences::k_LargeDataSize_Key);
const auto originalMode = preferences.value(Preferences::k_DataStorageMode_Key);
REQUIRE_THROWS_AS(ip_bench::BenchmarkPreferenceSnapshot(preferences, DataStorageMode::ForceOutOfCore, -1), std::invalid_argument);
CHECK(preferences.value(Preferences::k_LargeDataSize_Key) == originalThreshold);
CHECK(preferences.value(Preferences::k_LargeDataSize_Key).type() == originalThreshold.type());
CHECK(preferences.value(Preferences::k_DataStorageMode_Key) == originalMode);
CHECK(preferences.value(Preferences::k_DataStorageMode_Key).type() == originalMode.type());
CHECK(preferences.contains(Preferences::k_LargeDataSize_Key));
CHECK(preferences.contains(Preferences::k_DataStorageMode_Key));

Preferences absent;
REQUIRE_THROWS_AS(ip_bench::BenchmarkPreferenceSnapshot(absent, DataStorageMode::ForceOutOfCore, -1), std::invalid_argument);
CHECK_FALSE(absent.contains(Preferences::k_LargeDataSize_Key));
CHECK_FALSE(absent.contains(Preferences::k_DataStorageMode_Key));
}
40 changes: 5 additions & 35 deletions src/Plugins/ImageProcessing/benchmark/BenchmarkRunner.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "BenchmarkRunner.hpp"
#include "BenchmarkPreferenceSnapshot.hpp"

#include "BenchmarkTiling.hpp"

Expand Down Expand Up @@ -38,37 +39,6 @@ std::string FirstErrorMessage(const std::vector<Error>& errors)
return errors.empty() ? "(no message)" : errors.front().message;
}

// RAII sentinel that mirrors UnitTest::PreferencesSentinel (save mode + large_data_size, apply, restore on
// destruction). Re-implemented locally because this standalone tool deliberately does NOT link the UnitTestCommon
// .cpp that defines PreferencesSentinel's ctor/dtor (see benchmark/CMakeLists.txt). This one restores in-memory only
// -- it never writes the preferences file to disk.
class BenchPreferencesSentinel
{
public:
BenchPreferencesSentinel(DataStorageMode mode, int64 largeDataSize)
{
auto* prefs = Application::Instance()->getPreferences();
m_OriginalMode = prefs->dataStorageMode();
m_OriginalSize = prefs->valueAs<int64>(Preferences::k_LargeDataSize_Key);
prefs->setDataStorageMode(mode);
prefs->setValue(Preferences::k_LargeDataSize_Key, largeDataSize);
}
~BenchPreferencesSentinel()
{
auto* prefs = Application::Instance()->getPreferences();
prefs->setDataStorageMode(m_OriginalMode);
prefs->setValue(Preferences::k_LargeDataSize_Key, m_OriginalSize);
}
BenchPreferencesSentinel(const BenchPreferencesSentinel&) = delete;
BenchPreferencesSentinel(BenchPreferencesSentinel&&) = delete;
BenchPreferencesSentinel& operator=(const BenchPreferencesSentinel&) = delete;
BenchPreferencesSentinel& operator=(BenchPreferencesSentinel&&) = delete;

private:
DataStorageMode m_OriginalMode;
int64 m_OriginalSize;
};

// Removes every DataObject NOT present in @p baseline (the set of IDs snapshotted right after the tiled input was
// built). Handles both in-place-output filters (an array under the shared cell AM) and new-geometry-output filters
// like MaximumProjection (a whole new ImageGeom). removeData recurses into children and is a no-op for IDs already
Expand Down Expand Up @@ -397,7 +367,7 @@ BenchmarkRow RunFilterBenchmark(const BenchmarkFilterSpec& spec, const SweepOpti
DataStructure dsInCore;
DataPath inputPath;
{
const BenchPreferencesSentinel sentinel(DataStorageMode::ForceInCore, 0);
const ip_bench::BenchmarkPreferenceSnapshot sentinel(*Application::Instance()->getPreferences(), DataStorageMode::ForceInCore);
Result<DataPath> r = PrepareBenchmarkInput(dsInCore, spec, geom, cellAmName, inArrayName, opts.targetVoxels, opts.minZSlices, opts.force2D, DataStorageMode::ForceInCore);
if(r.invalid())
{
Expand All @@ -418,7 +388,7 @@ BenchmarkRow RunFilterBenchmark(const BenchmarkFilterSpec& spec, const SweepOpti
// --- new-in-core ---
if(!opts.oocOnly)
{
const BenchPreferencesSentinel sentinel(DataStorageMode::ForceInCore, 0);
const ip_bench::BenchmarkPreferenceSnapshot sentinel(*Application::Instance()->getPreferences(), DataStorageMode::ForceInCore);
std::string note;
row.newIncoreMs = RunConfig(filterList, spec.newFilterUuid, dsInCore, baseInCore, spec, geom, inputPath, outName, opts.warmup, opts.repeats, opts.projectionAxis, note);
if(!note.empty())
Expand All @@ -435,7 +405,7 @@ BenchmarkRow RunFilterBenchmark(const BenchmarkFilterSpec& spec, const SweepOpti
DataPath oocInput;
bool built = false;
{
const BenchPreferencesSentinel sentinel(DataStorageMode::ForceOutOfCore, opts.oocThreshold);
const ip_bench::BenchmarkPreferenceSnapshot sentinel(*Application::Instance()->getPreferences(), DataStorageMode::ForceOutOfCore, opts.oocThreshold);
Result<DataPath> r = PrepareBenchmarkInput(dsOoc, spec, geom, cellAmName, inArrayName, opts.targetVoxels, opts.minZSlices, opts.force2D, DataStorageMode::ForceOutOfCore);
if(r.invalid())
{
Expand All @@ -450,7 +420,7 @@ BenchmarkRow RunFilterBenchmark(const BenchmarkFilterSpec& spec, const SweepOpti
if(built)
{
const std::unordered_set<DataObject::IdType> baseOoc = SnapshotIds(dsOoc);
const BenchPreferencesSentinel sentinel(DataStorageMode::ForceOutOfCore, opts.oocThreshold);
const ip_bench::BenchmarkPreferenceSnapshot sentinel(*Application::Instance()->getPreferences(), DataStorageMode::ForceOutOfCore, opts.oocThreshold);
std::string note;
row.newOocMs = RunConfig(filterList, spec.newFilterUuid, dsOoc, baseOoc, spec, geom, oocInput, outName, opts.warmup, opts.repeats, opts.projectionAxis, note);
if(!note.empty())
Expand Down
33 changes: 3 additions & 30 deletions src/Plugins/ImageProcessing/benchmark/WriteImageBenchmark.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include "BenchmarkPreferenceSnapshot.hpp"
#include "ImageProcessing/Filters/WriteImageFilter.hpp"

#include "simplnx/Common/Result.hpp"
Expand Down Expand Up @@ -29,6 +30,7 @@
#include <fstream>
#include <memory>
#include <optional>
#include <stdexcept>
#include <string>
#include <string_view>
#include <system_error>
Expand Down Expand Up @@ -92,35 +94,6 @@ struct TimingRow
OocCounters counterDelta;
};

class PreferencesSentinel
{
public:
explicit PreferencesSentinel(DataStorageMode storageMode)
: m_Preferences(Application::Instance()->getPreferences())
, m_OriginalMode(m_Preferences->dataStorageMode())
, m_OriginalLargeDataSize(m_Preferences->valueAs<int64>(Preferences::k_LargeDataSize_Key))
{
m_Preferences->setDataStorageMode(storageMode);
m_Preferences->setValue(Preferences::k_LargeDataSize_Key, int64{0});
}

~PreferencesSentinel()
{
m_Preferences->setDataStorageMode(m_OriginalMode);
m_Preferences->setValue(Preferences::k_LargeDataSize_Key, m_OriginalLargeDataSize);
}

PreferencesSentinel(const PreferencesSentinel&) = delete;
PreferencesSentinel(PreferencesSentinel&&) = delete;
PreferencesSentinel& operator=(const PreferencesSentinel&) = delete;
PreferencesSentinel& operator=(PreferencesSentinel&&) = delete;

private:
Preferences* m_Preferences = nullptr;
DataStorageMode m_OriginalMode = DataStorageMode::Adaptive;
int64 m_OriginalLargeDataSize = 0;
};

std::string FirstError(const Result<>& result)
{
return result.errors().empty() ? "operation failed without an error message" : result.errors().front().message;
Expand Down Expand Up @@ -275,7 +248,7 @@ Result<> BuildInput(DataStructure& dataStructure, DataStorageMode storageMode)

std::shared_ptr<AbstractDataStore<T>> store;
{
PreferencesSentinel preferences(storageMode);
ip_bench::BenchmarkPreferenceSnapshot preferences(*Application::Instance()->getPreferences(), storageMode);
store = DataStoreUtilities::CreateDataStore<T>(dataStructure, k_InputArrayPath, {k_DimZ, k_DimY, k_DimX}, {1});
}
if(store == nullptr)
Expand Down
14 changes: 14 additions & 0 deletions src/Plugins/ImageProcessing/test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -156,3 +156,17 @@ foreach(example_name IN LISTS ${PLUGIN_NAME}_EXAMPLE_PIPELINE_NAMES)
endforeach()

create_pipeline_tests(PLUGIN_NAME ${PLUGIN_NAME} PIPELINE_LIST ${PREBUILT_PIPELINE_NAMES})

# VerifyExamplePipelineCitations.py resolves every citation over the network (doi.org and publisher sites),
# so it depends on external services and on each agent's certificate store. It is not registered with CTest;
# run it manually when pipeline citations change.

target_sources(${PLUGIN_NAME}UnitTest PRIVATE "${simplnx_SOURCE_DIR}/test/ProfileIsolationContract.cpp")

add_test(NAME "${PLUGIN_NAME}_test_profile_isolation"
COMMAND ${CMAKE_COMMAND}
"-DPROFILE_TEST_EXECUTABLE=$<TARGET_FILE:${PLUGIN_NAME}UnitTest>"
"-DPROFILE_TEST_ROOT=${CMAKE_CURRENT_BINARY_DIR}/ProfileIsolation"
-DPROFILE_RUNNER_ONLY=TRUE
-P "${simplnx_SOURCE_DIR}/test/VerifyTestProfileLifecycle.cmake")
set_tests_properties("${PLUGIN_NAME}_test_profile_isolation" PROPERTIES RUN_SERIAL TRUE TIMEOUT 60)
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
// Catch2 recommends placing these lines by themselves in a translation unit
// which will help reduce unnecessary recompilations of the expensive Catch main
#define CATCH_CONFIG_MAIN
#define CATCH_CONFIG_RUNNER
#include <catch2/catch.hpp>

#include "simplnx/UnitTest/OwnedCatchRunner.hpp"

int main(int argc, char* argv[])
{
return nx::core::UnitTest::RunOwnedCatchSession(argc, argv);
}
Loading
Loading