image_analysis: query the current device, and upload the resolution mask on the engine stream

Two leftovers from earlier fixes of the same shape. BraggIntegrationEngineGPU still read
device 0's shared-memory size to decide whether its profile grid fits; workers are pinned
round-robin across GPUs, so on a heterogeneous node that check can pass on a different
card than the one the kernel launches on. SpotExtractorGPU still uploaded its default
resolution mask with a pageable copy on the NULL stream, which is not ordered against the
engine stream now that streams are created non-blocking.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-03 14:14:24 +02:00
co-authored by Claude Opus 5
parent 32ecc296b8
commit 4b1c611bdf
2 changed files with 10 additions and 2 deletions
@@ -424,8 +424,12 @@ BraggIntegrationEngineGPU::BraggIntegrationEngineGPU(const DiffractionExperiment
const int max_Gf = 2 * max_Rf + 1;
fit_shared_bytes = static_cast<size_t>(max_Gf) * max_Gf * sizeof(float);
// The current device, not device 0: workers are pinned round-robin across GPUs, so device 0's
// shared-memory size can belong to a different card than the one these kernels launch on.
int device = 0;
cuda_err(cudaGetDevice(&device));
cudaDeviceProp prop{};
cuda_err(cudaGetDeviceProperties(&prop, 0));
cuda_err(cudaGetDeviceProperties(&prop, device));
if (fit_shared_bytes > prop.sharedMemPerBlock)
throw JFJochException(JFJochExceptionCategory::GPUCUDAError,
"BraggIntegrationEngineGPU: profile grid exceeds shared memory (r2 too large)");
@@ -296,7 +296,11 @@ SpotExtractorGPU::SpotExtractorGPU(int32_t in_width, int32_t in_height, std::sha
const size_t npixel = static_cast<size_t>(in_width) * in_height;
if (npixel % 32 != 0)
mask.back() = ~((1u << (npixel % 32)) - 1u);
cuda_err(cudaMemcpy(gpu_res_mask, mask.data(), nwords * sizeof(uint32_t), cudaMemcpyHostToDevice));
// On this engine's stream, then synchronised - the default stream is non-blocking, so a NULL-stream
// copy is not ordered against the kernels that read this mask.
cuda_err(cudaMemcpyAsync(gpu_res_mask, mask.data(), nwords * sizeof(uint32_t),
cudaMemcpyHostToDevice, *stream));
cuda_err(cudaStreamSynchronize(*stream));
}
void SpotExtractorGPU::SetResolutionMask(const std::vector<uint32_t> &packed_mask) {