Files
Jungfraujoch/rugnux/RugnuxLive.cpp
T
leonarski_f 7ed32b899f
Build Packages / Create release (push) Successful in 7s
Build Packages / build:portable:macos-arm64:nocuda (push) Successful in 4m53s
Build Packages / build:rugnux:linux-aarch64:cuda (push) Successful in 9m27s
Build Packages / build:portable:linux-x86_64:nocuda (push) Successful in 15m0s
Build Packages / build:portable:linux-x86_64:cuda (push) Successful in 20m4s
Build Packages / build:portable:windows-x86_64:nocuda (push) Successful in 21m33s
Build Packages / build:jfjoch:ubuntu2204:nocuda (push) Successful in 22m4s
Build Packages / build:jfjoch:rocky8:nocuda (push) Successful in 25m16s
Build Packages / build:portable:windows-x86_64:cuda (push) Successful in 26m14s
Build Packages / build:jfjoch:rocky9:nocuda (push) Successful in 27m26s
Build Packages / HDF5 consumer tests (DIALS, XDS) (push) Successful in 30m26s
Build Packages / build:jfjoch:ubuntu2404:nocuda (push) Successful in 22m20s
Build Packages / Generate python client (push) Successful in 32s
Build Packages / Build documentation (push) Successful in 1m20s
Build Packages / build:jfjoch:rocky8:cuda-sls9 (push) Successful in 23m28s
Build Packages / build:jfjoch:rocky9:cuda-sls9 (push) Successful in 26m23s
Build Packages / build:jfjoch:ubuntu2204:cuda (push) Successful in 20m35s
Build Packages / build:jfjoch:rocky8:cuda (push) Successful in 25m59s
Build Packages / build:jfjoch:rocky9:cuda (push) Successful in 26m27s
Build Packages / build:jfjoch:ubuntu2404:cuda (push) Successful in 22m15s
Build Packages / Unit tests (push) Successful in 1h26m38s
Build Packages / Validation Battery (push) Successful in 32m11s
v1.0.0-rc.177 (#87)
* jfjoch_broker: Faster live Rugnux analysis, with the GPU indexers prepared at the start of a collection and kept between collections; Rugnux no longer writes `.ccp4` maps (the map coefficients are in `<prefix>_maps.mtz`).

Reviewed-on: #87
Co-authored-by: Filip Leonarski <filip.leonarski@psi.ch>
2026-10-19 16:07:31 +02:00

92 lines
3.6 KiB
C++

// SPDX-FileCopyrightText: 2026 Filip Leonarski, Paul Scherrer Institute <filip.leonarski@psi.ch>
// SPDX-License-Identifier: GPL-3.0-only
#include "RugnuxLive.h"
#include <future>
#include "RugnuxDefaults.h"
#include "../common/CUDAWrapper.h"
#include "../image_analysis/indexing/IndexerThreadPool.h"
#ifdef JFJOCH_USE_CUDA
#include "../image_analysis/geom_refinement/BeamCenterFFTGPU.h"
#endif
RugnuxLiveSetup MakeRugnuxLiveSetup(const JFJochReaderDataset &dataset, int nthreads,
std::shared_ptr<const RugnuxModel> model) {
RugnuxLiveSetup s;
// The experiment as rugnux_cli.cpp sets it up for a rotation sweep with no options given.
DiffractionExperiment &x = s.experiment;
x = dataset.experiment;
ApplyRugnuxExperimentDefaults(x);
x.NumTriggers(1);
ClearStoredCrystal(x);
x.MaxSpotCount(RUGNUX_MAX_SPOT_COUNT);
IndexingSettings indexing;
indexing.Algorithm(IndexingAlgorithmEnum::Auto);
indexing.RotationIndexing(true);
indexing.GeomRefinementAlgorithm(GeomRefinementAlgorithmEnum::BeamCenter);
indexing.IndexIceRings(false);
x.ImportIndexingSettings(indexing);
x.DetectIceRings(RugnuxDetectIceRings(dataset.file_detect_ice_rings, true));
ScalingSettings scaling = RugnuxDefaultScalingSettings(true);
scaling.ScaleFulls(true);
scaling.RelativeBDegrees(0.0);
scaling.MergeFriedel(true);
scaling.MinPartiality(0.02);
scaling.MinCCForImage(0.0);
x.ImportScalingSettings(scaling);
ProcessConfig &c = s.config;
c.mode = ProcessMode::FullAnalysis;
c.nthreads = nthreads;
// As a bare `rugnux` with no -N: the per-image loop keeps to what a card can take (ImagePass).
c.nthreads_auto = true;
c.export_unmerged = false;
c.spot_finding = RugnuxDefaultSpotFinding(true);
c.rotation_indexing = true;
c.two_pass_rotation = true;
c.rotation_postrefine_geometry = true;
c.rotation_indexing_image_count = RUGNUX_ROTATION_INDEXING_IMAGES;
c.detect_beam_stop = RUGNUX_DETECT_BEAM_STOP_FRAMES;
c.beam_center_check = true;
c.measure_spot_budget = true;
c.run_scaling = true;
c.model = std::move(model);
c.live = true;
c.fast_live = true;
// Decided late, on the whole sweep, as it re-checks its radius there - which fast_live does not.
c.adaptive_integration_radius = false;
return s;
}
void WarmUpRugnuxLiveGPU(const RugnuxLiveSetup &setup) {
#ifdef JFJOCH_USE_CUDA
// As Rugnux sets them for its first-pass pool (the measured centre's indexing and pass 2 use it as
// well) and its short-axis pool. Should they part, the run builds its own, as without this.
IndexingSettings first_pass = setup.experiment.GetIndexingSettings();
first_pass.RefineThreads(std::clamp(setup.config.nthreads / 2, 1, MAX_REFINE_THREADS));
IndexingSettings short_axis = first_pass;
short_axis.FFT_MinUnitCell_A(IndexingSettings::fft_min_unit_cell_limit_A);
// Each pool has two workers, on consecutive cards.
const int gpus = get_gpu_count();
const int per_card = gpus == 1 ? 2 : 1;
std::vector<std::future<void>> cards;
for (int32_t i = 0; i < gpus; i++)
cards.push_back(std::async(std::launch::async, [&, i] {
ScopedGpuPin pin(i);
KeepFFTIndexers(first_pass, per_card);
KeepFFTIndexers(short_axis, per_card);
// Sizing the capture's work area makes its two plans (CudaFFTPlan::WorkBytes).
BeamCenterFFTGPU::DeviceMemoryNeeded(setup.experiment.GetXPixelsNumConv(),
setup.experiment.GetYPixelsNumConv());
}));
for (auto &c: cards)
c.get();
#endif
}