Metal: a frame with a handed-over radial curve in use is integrated by the CPU engine
With a curve from the whole frame (RadialBackgroundFromRings) the ring's high-side clip follows it (RadialClipOffset) on the CPU and CUDA; the Metal clip kernel did not, so a Mac run of such a frame differed from both. It now goes to the CPU engine, which gives that result exactly - the precedent is the trimmed mean. Frames without a handed-over curve are unchanged. Not compiled here (no macOS); BraggIntegrationEngineMetal_HandedOverRadialCurveStaysOnCPU checks it on the Mac CI job. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015CeEGgpKdfkCTJb3YNMJcu (cherry picked from commit 36be3b8f13dbde2616fe7add3acc3d073ef082af)
This commit is contained in:
1 parent
6940718cf5
commit
3467c21919
2 files changed
+28
-2
No files matched your search
@@ -253,6 +253,30 @@ TEST_CASE("BraggIntegrationEngineMetal_BitIdenticalToCPU", "[portable][Integrati
|
||||
}
|
||||
}
|
||||
|
||||
// A radial curve handed over from the whole frame (RadialBackgroundFromRings) makes the ring's clip follow
|
||||
// it, which the clip kernel does not: such a frame is integrated by the CPU engine, so the result is the
|
||||
// CPU's exactly and no frame goes to the GPU.
|
||||
TEST_CASE("BraggIntegrationEngineMetal_HandedOverRadialCurveStaysOnCPU", "[portable][Integration][Metal]") {
|
||||
Case c;
|
||||
c.radial = true;
|
||||
const DiffractionExperiment x = MakeExperiment(DetJF(2), c);
|
||||
const PixelMask mask(x);
|
||||
BraggIntegrationEngineCPU cpu(x, mask);
|
||||
BraggIntegrationEngineMetal metal(x, mask);
|
||||
std::vector<float> rings(400);
|
||||
for (size_t i = 0; i < rings.size(); ++i)
|
||||
rings[i] = 1.0f + 0.002f * static_cast<float>(i * i);
|
||||
cpu.RadialBackgroundFromRings(rings, static_cast<int32_t>(rings.size()), 0.05f, 0.01f);
|
||||
metal.RadialBackgroundFromRings(rings, static_cast<int32_t>(rings.size()), 0.05f, 0.01f);
|
||||
ImagePreprocessorBuffer image(x.GetPixelsNum());
|
||||
const Frame f = RandomFrame(x, 7, {});
|
||||
std::copy(f.image.begin(), f.image.end(), image.data());
|
||||
const auto out_cpu = cpu.Run(image, f.predicted, f.predicted.size(), 0);
|
||||
RequireSame(out_cpu, metal.Run(image, f.predicted, f.predicted.size(), 0));
|
||||
CHECK(out_cpu.size() > 1000);
|
||||
CHECK(metal.FramesOnGPU() == 0);
|
||||
}
|
||||
|
||||
// The trimmed-mean background sorts each ring, which only the CPU engine does: such a run keeps the CPU
|
||||
// engine (MXAnalysisWithoutFPGA asks Available).
|
||||
TEST_CASE("BraggIntegrationEngineMetal_TrimmedMeanStaysOnCPU", "[portable][Integration][Metal]") {
|
||||
|
||||
Reference in new issue
Block a user