Build Packages / build:viewer-tgz:cpu (push) Successful in 11m35s
Build Packages / build:windows:nocuda (push) Successful in 16m52s
Build Packages / build:windows:cuda (push) Successful in 20m24s
Build Packages / build:rugnux-tgz (x86_64) (push) Successful in 18m38s
Build Packages / build:rugnux:windows (push) Successful in 10m38s
Build Packages / build:rugnux:aarch64 (cross) (push) Successful in 9m4s
Build Packages / build:viewer-tgz:cuda (push) Successful in 14m44s
Build Packages / build:rpm (ubuntu2404_nocuda) (push) Successful in 20m46s
Build Packages / build:rpm (rocky9_nocuda) (push) Successful in 21m24s
Build Packages / build:rpm (rocky8_nocuda) (push) Successful in 24m13s
Build Packages / build:rpm (ubuntu2204_nocuda) (push) Successful in 26m2s
Build Packages / build:rpm (rocky9_sls9) (push) Successful in 18m34s
Build Packages / build:rpm (rocky8_sls9) (push) Successful in 23m55s
Build Packages / build:rpm (rocky9) (push) Successful in 21m9s
Build Packages / XDS test (durin plugin) (push) Successful in 12m8s
Build Packages / build:rpm (ubuntu2404) (push) Successful in 20m6s
Build Packages / build:rpm (rocky8) (push) Successful in 25m46s
Build Packages / Generate python client (push) Successful in 38s
Build Packages / Create release (push) Skipped
Build Packages / Build documentation (push) Successful in 58s
Build Packages / build:rpm (ubuntu2204) (push) Successful in 24m36s
Build Packages / XDS test (JFJoch plugin) (push) Successful in 8m44s
Build Packages / XDS test (neggia plugin) (push) Successful in 7m17s
Build Packages / DIALS test (push) Successful in 19m45s
Build Packages / Unit tests (push) Successful in 1h26m13s
* rugnux is substantially faster - a corpus of 145 rotation datasets processes in about two thirds of the time - with identical results. * A crystal whose lattice looks more symmetric than it is because the beam centre is off is no longer processed on the wrong cell. * rugnux prints at startup, and writes at the foot of every results report, a short acknowledgement of the X-ray research community whose methods it implements and of the open-source projects it builds on; `ACKNOWLEDGEMENT.md` now ships in every package beside `LICENSE` and `THIRD_PARTY_NOTICES.md`. Reviewed-on: #78 Co-authored-by: Filip Leonarski <filip.leonarski@psi.ch>
61 lines
3.4 KiB
C++
61 lines
3.4 KiB
C++
// SPDX-FileCopyrightText: 2026 Filip Leonarski, Paul Scherrer Institute <filip.leonarski@psi.ch>
|
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
|
|
#pragma once
|
|
|
|
#include <memory>
|
|
|
|
#include "ImagePreprocessor.h"
|
|
#include "BSLZ4DecoderGPU.h"
|
|
#include "../indexing/CUDAMemHelpers.h"
|
|
#include "../indexing/CudaSharedTables.h"
|
|
|
|
class ImagePreprocessorGPU : public ImagePreprocessor {
|
|
std::shared_ptr<CudaStream> stream;
|
|
const bool copy_image_to_host;
|
|
int threads;
|
|
int blocks;
|
|
// Geometry-only, so one copy per GPU shared with every other engine on it (CudaSharedTables.h).
|
|
std::shared_ptr<CudaDevicePtr<uint8_t>> gpu_mask;
|
|
// Landing buffer for the HOST-upload path only. The device-decode path un-transposes straight
|
|
// into the preprocessed image, so it never needs this - and at 4 bytes per pixel it is worth a
|
|
// frame per worker, so it is allocated on first use rather than always.
|
|
CudaDevicePtr<uint8_t> gpu_decompressed_image;
|
|
CudaDevicePtr<ImageStatistics> gpu_stats;
|
|
|
|
std::vector<ImageStatistics> cpu_stats;
|
|
CudaRegisteredVector<ImageStatistics> cpu_stats_reg;
|
|
CudaRegisteredVector<uint8_t> input_reg; // page-locks the caller's decompression buffer
|
|
// The uncompressed-image counterpart of input_reg: the region PinInputRegion last page-locked.
|
|
const void *pinned_input = nullptr;
|
|
size_t pinned_input_bytes = 0;
|
|
|
|
std::vector<int32_t> cpu_image;
|
|
|
|
// Built on first use: a decoder that can serve this engine's images, sized to the frame.
|
|
std::unique_ptr<BSLZ4DecoderGPU> bslz4_decoder;
|
|
|
|
template <class T> ImageStatistics Analyze(ImagePreprocessorBuffer &processed_image, const uint8_t *input, T err_value, T sat_value);
|
|
// Preprocess an image already sitting in gpu_decompressed_image (the host-upload path).
|
|
template <class T> ImageStatistics AnalyzeOnDevice(ImagePreprocessorBuffer &processed_image, T err_value, T sat_value);
|
|
// Preprocess straight out of the bitshuffled bytes (the device-decode path). Same per-pixel
|
|
// decision and same statistics as AnalyzeOnDevice, with the un-transpose folded in.
|
|
template <class T, int ES> ImageStatistics UntransposeAndAnalyze(ImagePreprocessorBuffer &processed_image,
|
|
const BSLZ4ShuffledImage &shuffled,
|
|
T err_value, T sat_value);
|
|
public:
|
|
// copy_image_to_host copies the preprocessed image back after every frame. It is only needed when
|
|
// something on the CPU reads it - the GPU engines all work off the device buffer - and at 4 bytes
|
|
// per pixel it is the single largest transfer in the pipeline, so the caller says whether it wants it.
|
|
ImagePreprocessorGPU(const DiffractionExperiment &experiment, const PixelMask &mask, std::shared_ptr<CudaStream> stream,
|
|
bool copy_image_to_host = true);
|
|
~ImagePreprocessorGPU() override;
|
|
ImageStatistics Analyze(ImagePreprocessorBuffer &processed_image, const uint8_t *decompressed_image, CompressedImageMode image_mode) override;
|
|
bool AnalyzeCompressed(ImagePreprocessorBuffer &processed_image, const CompressedImage &image,
|
|
ImageStatistics &stats) override;
|
|
[[nodiscard]] float GetLastDecompressionTime_s() const override;
|
|
void PinInputBuffer(std::vector<uint8_t> &buffer, size_t size) override;
|
|
void PinInputRegion(const void *ptr, size_t bytes) override;
|
|
};
|
|
|