marCCD frames are widened on the device
The marCCD reader read each frame's 16-bit scanlines into scratch and widened them to int32 on the worker thread (marccd::ReadInto, ~20 % of the image-loop worker CPU on 4nwv), and the 4-byte image was uploaded. ReadRawImage now reads the scanlines straight into the image's buffer and hands them over as a new read-only CompressionAlgorithm::UINT16_WIDENED (mode Int32): two bytes a pixel cross PCIe, from page-locked memory, and the preprocessing kernel widens them itself. It is not CompressedImageMode::Uint16, which calls 65535 an error pixel; a marCCD's 65535 is its saturation marker. So the kernel compares each pixel with int32's error marker and the int32 saturation cap - the comparisons are made on the pixel's value, in int64, rather than in the storage type - and decides every pixel exactly as for the int32 image the host would have widened it to. The host widening (JFJochDecompressPtr) is the CPU path. Test: ImagePreprocessorGPU_StoredEncodingsMatchCPU, with a frame carrying 65535 at a saturation of 65535, against the CPU preprocessor on the host-widened image. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EizBKhTqrAYago9KJG3dA3
This commit is contained in:
@@ -121,9 +121,11 @@ void MXAnalysisWithoutFPGA::Analyze(DataMessage &output,
|
||||
// sees the same error it saw before any of this existed - but a GPU-side problem costs speed
|
||||
// rather than the acquisition. Unless the context is lost, which the host route cannot survive.
|
||||
cuda_throw_if_context_lost();
|
||||
// The miniCBF encoding is decoded on the device whenever there is one; the host decoder is the
|
||||
// CPU path, not a slower second try. A stream the device refuses, the host refuses as well.
|
||||
if (output.image.GetCompressionAlgorithm() == CompressionAlgorithm::CBF_BYTE_OFFSET)
|
||||
// The miniCBF and marCCD encodings are decoded on the device whenever there is one; the host
|
||||
// decoder is the CPU path, not a slower second try. A stream the device refuses, the host
|
||||
// refuses as well.
|
||||
if (output.image.GetCompressionAlgorithm() == CompressionAlgorithm::CBF_BYTE_OFFSET
|
||||
|| output.image.GetCompressionAlgorithm() == CompressionAlgorithm::UINT16_WIDENED)
|
||||
throw;
|
||||
spdlog::warn("Device decoding failed ({}), falling back to host decompression", e.what());
|
||||
decoded_on_device = false;
|
||||
|
||||
Reference in New Issue
Block a user