bbb341a566b8ad6fbbe7fa80d7815d960993e96b
419
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
8d199cceba |
ModelValidationTest: the CPU density is gemmi's to rounding, the same on any number of threads
The density's walk now places its points in single precision (the Metal density series), so it is no longer gemmi's bit for bit: the two gridding tests compare it to gemmi within 1e-5 relative plus four cutoff-sized terms (a point at a radius' edge can fall on the other side), and check that 1 and 4 threads give the same grid bit for bit. The solvent mask is still compared to gemmi's bit for bit. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PXc1zD1yxHqaR1DGdCTHL4 |
||
|
|
0e73543a20 |
Merge mac-mr-metal (density series) into rc176: Metal model density, bit-identical to the CPU; the CPU density walk in single precision (RESULT-CHANGING at the last bit); autorelease-pool leak fix in the Metal rotation function
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PXc1zD1yxHqaR1DGdCTHL4 |
||
|
|
868ad0c8f2 |
ModelGrid: the model density on the Apple GPU (Metal), bit-identical to the CPU
On macOS, where a Metal device may be used (not under --no-gpu), PutModelDensityOnGrid puts the density on the grid with a Metal gather (ModelDensityMetal), as ModelDensityGPU.cu does under CUDA: the grid in bricks of 4^3 points, one threadgroup each; every point adds, in model order, each atom whose box holds it and whose radius reaches it. No float atomics. The arithmetic is the CPU walk's of the previous commit, spelled out in ModelDensityMetal.metal - the point's place in single precision in the same order, gemmi's float expapprox ported as is, fast math and contraction off - so the grid is the CPU's bit for bit (ModelDensityMetal_BitIdenticalToCPU, [portable][Metal]: a triclinic cell and a P 21 21 21 one, a quarter of the atoms anisotropic, boxes wrapping at every face). The symmetrize stays on the CPU. - Each brick's atoms: (brick, atom) pairs counted and filled on the CPU in parallel over slabs of w, each worker taking the atoms in order, so the lists keep model order; at most the atoms' boxes' bricks. - The kernel writes straight into the grid FFTW reads where its pages can be handed to the GPU (large vectors are page-aligned on macOS), into its own buffer and copied otherwise. - 4^3 bricks rather than CUDA's 8^3: every point tests each atom reaching its brick, and the smaller brick took a half to a third of the kernel time. The box test is a subtraction against a start the host wraps. - Every grid goes to the GPU: giving it only grids of 256k points or more, or models of 8000 atoms or more, left 9s02's MR 0.8 s slower. - A box wider than the cell (an atom reaching a point through two images) stays on the CPU, whose walk adds both. A Metal failure puts that grid and every later one on the CPU, with one warning. - Each call runs in an autorelease pool of its own (see the rotation function's). Apple M6 (16 GB), alternating with the rotation-function build (the previous commit but one), two each: - 4nwv: wall 295.8/292.6 -> 275.2/277.8 s; model validation 48.9/49.0 -> 41.0/40.9 s; MR 130.2/130.3 -> 121.4/122.5 s (rescoring 40.9/40.3 -> 35.6/36.5 s, null 31.7/32.1 -> 26.8/26.6 s); user CPU 1998/2011 -> 1692/1681 s; peak footprint 17.8/18.5 -> 17.2/18.6 GB. The density's CPU time, sampled over a whole run, 316 CPU-s (16% of the busy samples) -> none, the pairs' sort 31 CPU-s. - 9s02: wall 76.7/76.5 -> 72.9/73.1 s; MR 16.9/16.8 -> 13.5/13.4 s. - 9zlo: wall 70.4/70.7 -> 69.8/69.6 s; MR 3.1/3.1 -> 2.2/2.2 s. p.hkl, the placed model and the maps are byte-identical to the previous commit's (density on the CPU) on all three, and so are the MR and validation logs but for their timings. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018My7tqt8a4LyKKjP3FhScT |
||
|
|
627d1c7ed0 |
Revert "Merge anderson-solver into rc176": Anderson-accelerated scaling loops taken out for this release
The full battery (rc176-1bdce7e56-full) traced three changes to it, all reproduced with the anderson-solver
binary alone: an in-house insulin set lost its cubic group (I 2 3 -> I 2 2 2, the cut moving 1.63 -> 1.75 A),
a weak split myoglobin set fell in CC1/2 (0.70 -> 0.60) and R_free (0.438 -> 0.456), and 9gdj took a third
first pass (+10 s): pushed further on the measured-centre arm's poor lattice, the scaling moved both arms'
statistics so the early beam-centre comparison no longer called the loss beyond its noise. Kept on branch
anderson-solver (
|
||
|
|
1bdce7e565 |
Merge anderson-solver into rc176: the per-frame scaling loops are Anderson-accelerated, 3-4x fewer iterations and closer to their fixed point (RESULT-CHANGING, ISa within 0.03 on the 44-set battery)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PXc1zD1yxHqaR1DGdCTHL4 |
||
|
|
747a30dbaa |
RotationScaleMerge: Anderson-accelerate the per-frame scaling loops (RESULT-CHANGING)
The partials and fulls scaling loops are alternating least squares that converge linearly: over the rc176 battery's 2527 loops a round shrinks the step by a median 0.86 (partials) and 0.93 (fulls), up to 0.98, so the 1e-3 step tolerance stopped them 0.6% / 1.4% (median) and up to 17% (fulls p90) short of their fixed point, and 313 of them were stopped as "stalled" when they were only slow - a stalled fulls loop also skipped ShrinkToRestrained. Each round is now accelerated in log G by type-II Anderson mixing (Walker & Ni 2011), depth 5, each frame weighted by its observation count as in the step test; frames below the credible floor take the plain round's scale. The history is dropped when the weighted residual grows or the set of fitted frames changes (new AndersonMixing class, unit-tested on a synthetic slow ALS loop). The mixed scales are gauge-pinned again before the rescale, and the stop test is unchanged: it reads the round's residual F(x) - x, so "stalled" now means a loop that does not settle under acceleration either. Measured (CPU, -N 8): 4nwv 311 -> 82 iterations over 9 loops, 9v16 76 iterations over 11 loops, the same counts as the env-gated prototype on tail-solver; no history restart fired on either. Depth 3/5/8 give 92/91/90 iterations on 4nwv. A restart on a change of the fulls loop's cross-validated lambda was tried and gave nothing (83 vs 82). Same space group and merging statistics on 4nwv and 9v16. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PXc1zD1yxHqaR1DGdCTHL4 |
||
|
|
00fff118bc |
Merge failed-perimage into rc176: a rotation run that finds no lattice still reports every image (spots, resolution, background; not indexed), live and offline
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PXc1zD1yxHqaR1DGdCTHL4 |
||
|
|
e2296a5e9d |
rugnux: the no-lattice per-image pass says its images did not index
The per-image pass of a run that found no lattice left indexing_result unset, so the live scan result and the per-image arrays showed "not asked" rather than "not indexed". Set it false there: GET /result/scan now gives index 0 for every image and /entry/MX/imageIndexed is 0, as a collection without rugnux reports a frame that failed to index. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PXc1zD1yxHqaR1DGdCTHL4 |
||
|
|
c6b69d5bd5 |
Merge pol-header into rc176: the polarization a miniCBF or d*TREK header states is read; 0.99 only where the file states none (RESULT-CHANGING: lab-source d*TREK sets corrected as unpolarized)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PXc1zD1yxHqaR1DGdCTHL4 |
||
|
|
04655bd8bf |
MolecularReplacement: the rotation function on the Apple GPU (Metal), equal to rounding
On macOS, where a Metal device may be used (not under --no-gpu), each merge's rotation stage - the sphere and the peaks' refinement - runs on the GPU: the same trilinear interpolation of the same transform in float, one threadgroup per orientation, every bin's sums of |F|^2, |F|^4 and |F|^2 (E^2 - 1) in a fixed order, and the correlation made of them in double on the host. The GPU reads its own copy of the transform in 2 x 2 x 2 bricks (1.3x faster than the grid's rows, as the eight corners then lie on fewer cache lines), made for the rotation stage and given back before the translation function; the seeds' orientations later on stay on the CPU. Where the GPU fails, the stage goes on on the CPU with a warning. The kernel is MolecularReplacementMetal.metal, carried in the binary as the Bragg integration's are. Elsewhere nothing changes. Measured on an Apple M6 (16 GB), alternating with rc176 + the CPU prefetch, two runs each: - 4nwv (the timing benchmark's moved model): rotation 78.9 -> 30.7 s, wall 344.5 -> 298.8 s; peak footprint 16.1-16.8 -> 18.5 GB. - 9s02: rotation 2.99 -> 0.28 s, wall 79.2 -> 76.4 s. p.hkl, the placed model and the maps are identical to the CPU's on both, and so is every line of the molecular-replacement log (RF Z, TF Z, R values). The RF itself agrees with the CPU's to 1e-4, with the same best orientation (MolecularReplacementMetal_MatchesCPU, [portable]). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018My7tqt8a4LyKKjP3FhScT |
||
|
|
96a8ed3e4e |
rugnux: a run that finds no lattice still reports every image
A rotation run whose first pass found no lattice threw NoLatticeFound before any canonical pass, so no image was ever reported as the canonical pass: the live scan result and the master file's per-image arrays were empty, and the CLI wrote nothing per image. Run() now catches it, runs one output pass over every frame with spot finding and the per-image analysis but indexing off (SpotFindingPass: header geometry, the run's spot finding, pre-scan mask kept; the first pass, supercell probe, rotation finalize and merge skip a pass with indexing off), reports it through the observer as the canonical pass, hands the result back on the exception (NoLatticeFound::per_image) and rethrows - the verdict and the report are unchanged. Skipped when cancelled and when Run has no observer (the live lattice probe). The CLI writes that result where a run that indexed nothing puts its per-image analysis: the _process.h5 (streamed by the sink with --no-merge or --write-process-h5, otherwise written from the end message) and the _plot.txt; the exit status stays 1. An output pass with no sink now fills the end message's per-image arrays (ScanResultGenerator) for that file, which it claimed to carry but did not. The no-lattice hint no longer points at --mode azint for the per-image analysis. Measured offline on two 16M no-crystal controls (1800 frames): the extra pass is 1.6 s, wall +1.2-2.3 s. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PXc1zD1yxHqaR1DGdCTHL4 |
||
|
|
b17b643bd9 |
Readers: polarization from miniCBF and d*TREK headers (RESULT-CHANGING)
No reader parsed a polarization, and ApplyRugnuxExperimentDefaults then set
P = 0.99 (an undulator value) unconditionally, so laboratory-source data were
corrected as if from a synchrotron. Every d*TREK (Rigaku Saturn/A200) header in
the open arm states SOURCE_POLARZ=0.5 1 0 0, i.e. unpolarized; at Cu K-alpha and
2 A the wrong factor puts a +-33% azimuthal modulation on the intensities.
- d*TREK SMV: SOURCE_POLARZ is the fraction f followed by the plane normal (as
dxtbx's FormatSMVRigaku reads it); stored as degree 2f - 1, negative where the
normal lies along lab x (plane containing y).
- miniCBF: "# Polarization f" is the fraction in the horizontal plane; stored as
2f - 1 ("None" or a missing line leave it unset).
- ApplyRugnuxExperimentDefaults sets 0.99 only where the file stated none;
--polarization still overrides. ADSC SMV, marCCD and NXmx state nothing and
keep 0.99.
- The "Header:" log line reports the stated polarization.
RESULT-CHANGING: d*TREK home-source sets (0.99 -> 0), one Rigaku miniCBF set
(0.99 -> 0), miniCBF sets stating 0.99 (0.99 -> 0.98).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PXc1zD1yxHqaR1DGdCTHL4
|
||
|
|
78c2a69267 |
Merge broker-rugnux-live into rc176: rugnux in jfjoch_broker as a live thread during a DECTRIS rotation collection (off by default), the rugnux library without file I/O (results in ProcessResult::outputs, the CLI writes them through JFJochRugnuxOutput), END carrying the merged table, map coefficients and placed model
Branch reviewed at |
||
|
|
55184eb096 |
tests: the parallel unmerged MTZ table is compared bitwise again
UnmergedMtzTable's columns hold NaN for missing values, and vector<float> == compares NaN unequal to itself, so the serial-vs-parallel check could fail spuriously. Each column is compared with memcmp, as the test did before the MtzTable change. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
e16db07ffd |
broker rugnux live: no files, END built from the result in memory, and review fixes
No files. The receiver no longer makes a /tmp scratch directory or reads rugnux's files back: AddToEndMessage moves the merged MtzTable and the map coefficients out of ProcessResult::outputs and converts the placed model with PlacedModelFromStructure (now given the data cell, as WritePlacedModel is). FillRugnuxResultBlocks and MtzTableFromFile are gone; their test now builds the blocks from the same in-memory outputs and still checks the writer reproduces rugnux's own files byte for byte. The live status report is built from the result with the writer's file prefix as its label. AddToEndMessage never throws: a failure is logged and the END goes without the blocks. Review fixes: - MakeRugnuxLiveSetup sets nthreads_auto, as a bare `rugnux` does, so the per-image loop keeps to GPUWorkersPerCard per card instead of starting one GPU worker per CPU thread; the 60-degree probe gets a quarter of the threads (at least 2). - A failure setting rugnux up (start message, reader, thread start) marks the live status Failed and nothing else; the collection goes on as in Lite. MeasurementThread and ForwardThread also catch std::exception, so no exception skips the latch or the reader's Ended(). - The ParallelFor pool is lowered to nice 10 only where it can be raised back (CAP_SYS_NICE, or RLIMIT_NICE reaching 0); otherwise it is left alone and that is logged once. - The preview and metadata sockets get the END without the result blocks. - Receiver plots and scan result are fed only from the canonical pass (RugnuxObserver::OnImagePass): the pre-pass reports [0, E) again at the header geometry and the plots accumulate, so it would count those images twice. The canonical pass reads every image once. - A collection the image buffer cannot hold is still not analysed, and now says so in the broker status (Warning) as well as the rugnux status. With rugnux live off nothing changes: the extra END resets are of empty blocks and analysis_warning is empty. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
d356cc5da5 |
ImageBuffer reader: one waiting thread at a time looks at the buffer
Every rugnux worker waiting for an image called ImageBuffer::GetImage every millisecond, and GetStatus every 100 polls. Each call takes the buffer's mutex and scans every slot, so sixteen waiting workers contended with the forward threads for the lock they put the images in under (GetImageSlot, ReadyToSend). Now one waiting thread at a time asks the buffer, at most every 2 ms, with a single GetStatus, and notes the images it holds in a per-reader bitmap; the other waiters sleep on a condition variable and are woken when it is refreshed or the collection ends. GetImage is called once, for an image known to be there (or given up on). MAX_IMAGE_LAG and Ended() mean what they did. ImageBuffer itself is unchanged. The test gains eight readers waiting at once. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
9c9b987928 |
Merge host-mem-2 into rc176: a host-memory budget from the machine's total RAM decides what runs side by side, the CPU ingest reads the reflections in place (24 B per partial), merge scratch is really freed, and CPU MR/validation workers are bounded by their bytes; output unchanged
Peak live heap, CPU path -N10, before -> after: 4nwv scaling 14.8 -> 11.9 GiB, analyses 13.5 -> 7.3; 8qaw scaling 34.0 -> 27.1; 9v16 17.2 -> 13.5; 9zlo/9gjx/9s02 7.7/7.4/8.9 -> 6.3/6.3/7.5. With the budget of a 16 GB machine, 4nwv validation 18.4 -> 10.8-12.3 and MR ~17 -> 12.5. GPU 4nwv 16.2 -> 14.8. Byte-identical to its base on GPU and --no-gpu (timing standard + inhouse, 4nwv/8qaw/9v16/ lyso_x06da_ref/cytc_x10sa), at the machine's budget and with a 16 GB one. Conflict in RugnuxScaleMerge.cpp: perf-8gb-cpu's card-byte declaration of the merge and this branch's host-budget decisions on the post-refinement and the all-observation arm, kept both, in that order. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PXc1zD1yxHqaR1DGdCTHL4 |
||
|
|
5f731db81d |
rugnux: the library returns its outputs in memory; the callers write the files
The rugnux library wrote its results itself: _process.h5 through a FileWriter, the merged/twin/_mr reflection files, the unmerged MTZs, the maps and their MTZ, the placed models, _detector.jpg and _plot.txt, and on a doubled cell it renamed files on disk. It now writes none of them. - MtzTable (common/MtzTable.h): an MTZ file's header, columns and batch headers with no file behind it. It replaces MergedReflectionsMessage and MapCoefficientsMessage in the END message, with one CBOR encoding. WriteMtz (writer/WriteRugnuxFiles.h) is the one serialiser, used by rugnux and jfjoch_writer alike; it refuses a table whose columns differ in length, name a missing dataset, carry a malformed batch header or name a space group gemmi does not know. MergedMtzTable and UnmergedMtzTable build the tables the old writers built. - ProcessResult::outputs (RugnuxOutputs) holds, for the output pass only: the answer's merge (MTZ table plus what the .cif/.hkl are written from), the twin hypothesis' and the model's choice's merges, the unmerged and unmerged-partials tables, the maps (coefficients always; the grids only with ProcessConfig::keep_map_grids), the placed models, the detector JPEG and the per-image plot table, and the start message of the no-lattice _process.h5. Map RMS is taken from the grid in memory, as the CCP4 header stated it, whether or not the map is kept. - The per-image analysis goes to a caller-supplied RugnuxImageSink; rugnux and the viewer give a FileWriter-based ProcessFileSink. The geometry pre-pass no longer makes a _01_process.h5. - The doubled cell keeps both output sets: the answer's in outputs, the other's in DoubledCell::other_outputs with its suffix; the report names files by suffix after the caller's prefix. - The output prefix, write_process_h5 and the observation dump path are gone from ProcessConfig; --dump-observations is a callback. - What used to be gated on having files to write (model validation and MR, the twin-hypothesis merges, the finalist ledger, the scaled fulls, the unmerged tables) is gated on the output pass instead, so a caller with no prefix gets the same results. - RugnuxOutputFiles (new library JFJochRugnuxOutput, linked by rugnux, the viewer and the tests) writes every file from the result with the names and formats rugnux has always used. The viewer writes its job's files the same way. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
4bf41983ed |
rugnux: the model is parsed by the caller and handed in as RugnuxModel
The analysis read the --model file itself, four to five times per run (the model kind, every validation, molecular replacement, the stills reference intensities) and located the PAE sidecar from the file name. The library is to do no file I/O, so the model now arrives in memory: - RugnuxModel (image_analysis/structure_refinement/RugnuxModel.h): the gemmi structure as read, whether it is ModelCIF, the PAE matrix where a prediction came with one, and the name the report gives it. - ParseRugnuxModel / ReadRugnuxModelFile (writer/RugnuxModelFile.h, in JFJochRugnuxFiles): bytes in, gzip by magic, PDB/mmCIF by content, _ma_qa_metric detection as before; the file reader takes the PAE JSON from the same place PaePathFor named. - ProcessConfig::model replaces model_path; PrepareSearchModel, RunMolecularReplacement, ValidateAgainstModel and ModelReferenceIntensities take the model; result fields name it by model_name. - rugnux reads the model before the run starts and stops with an error where the file holds no model (it used to run and report the model as not validated). The viewer reads it when the job is set up. - The broker parses an uploaded model at once and answers 400 where it is not one; it keeps the parsed model in memory, with no temporary directory or file. It takes no PAE. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
b6f3e3b928 |
Merge sf-ceil into rc176: the GPU spot finder's local-box test, count threshold and sigma-clip bounds are the CPU's to the bit
RESULT-CHANGING in principle, unchanged in practice: diagnostic builds counted 0 disagreements of the SNR and count tests over ~1.9e10 first-pass and 2.9e7 candidate tests on lyso_x06da_ref, cytc_x10sa, myob_x10sa, yag_x10sa_20keV, 4nwv and thau_bl1a_3p8keV, and 2 clip-bound flips each on lyso, yag and 4nwv; p.hkl bit-identical before and after on all six. New knife-edge parity test fails on the old GPU code in both directions. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PXc1zD1yxHqaR1DGdCTHL4 |
||
|
|
0903e35f73 |
Merge perf-8gb-cpu into rc176: the geometry probe beside the merge is decided on bytes, the GPU rotation prediction walks only the l that can cross the sphere, and the mmCIF/SHELX numbers use std::to_chars; output unchanged
Byte-identical to an rc176 base on GPU and --no-gpu: standard and inhouse timing benchmarks and a run of lyso_x06da_ref, cytc_x10sa, myob_x10sa, yag_x10sa_20keV, 4nwv. With the card faked to 8.55 GB the geometry check drops 0.81 -> 0.17 s (myob) and 0.44 -> 0.09 s (lyso); the GPU Bragg prediction kernel on 4nwv 1968 -> 415 ms on an RTX 5080 (loaded box, kernel time). A merge above ~9 GB (8qaw class) now makes the probe wait for it on a 16 GB card too. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PXc1zD1yxHqaR1DGdCTHL4 |
||
|
|
c8c33b79e0 |
Merge twin-isa into rc176: the space-group search asks the twin-immune zone of a lattice-holohedral candidate and no longer reads centring absences as screws; reference_mismatch is a report note
RESULT-CHANGING. 3r6o I4122 -> I41 (fail -> pass; ISa 4.15 -> 7.77, R-free 0.303 -> 0.270); 8c3e P622 -> P321 (fail -> unscored: the c screw is undeterminable from its sweep, the point group is right). Unchanged on the other 18 sets of a GPU battery (run 20261017-1241_520254_twin-isa-t2b vs 20261016-0057) and on a CPU screen of 53 controls. The reference_mismatch key on 3mc4 and 3r6o is a note in the report only: nothing is skipped or re-scored. The report.py conflict was the note column, which now carries both the SHELXL R_free note and the reference note. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PXc1zD1yxHqaR1DGdCTHL4 |
||
|
|
f215300a07 |
ImageBuffer reader: give up on an image MAX_IMAGE_LAG (100) behind the newest, and a unit test
Images reach the buffer in order give or take a few, so one still missing when the buffer holds an image 100 past it is lost, not late: the read returns false instead of waiting for the end of the collection. The newest image number comes from ImageBuffer::GetStatus, which scans every slot under the buffer's lock, so it is asked only every 100 polls (~10 Hz). The test puts CBOR images into an ImageBuffer the way the receiver does and checks read-back of the pixels, waiting for an image not yet there, the lag limit, the end of the collection and the bounds. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
9c4e22465a |
ImageSpotFinderGPU: the local-box test is the CPU's to the bit (RESULT-CHANGING)
RESULT-CHANGING for the GPU spot finder (classic and adaptive, which shares this kernel for its local-box passes) - only on pixels where the two used to disagree. Two differences between pixel_result and the CPU's StrongInWindow: - SNR test. Both form T = float(var) * strong2 in float. The CPU compares the int64 square (in_minus_mean)^2 with (int64) ceil(T); the GPU compared it with T directly, which converts the square to float. Below 2^24 the two differ only when the square equals ceil(T) with T not an integer (an exact-integer strong2 such as 9 or 16 never gives that); past 2^24, where T is an integer, the GPU's rounded square can land on T and fail a pixel the CPU accepts. The GPU now uses the CPU's integer-vs-ceil comparison. - Count threshold. At photon_count_threshold = 0 the CPU still requires val > 0; the GPU took 0 as "no threshold". It matters only for a pixel <= 0 above a negative local mean (a pedestal-subtracted detector); the adaptive finder always runs this pass with threshold 0. The GPU now applies val > threshold unconditionally, with the threshold carried as int64 like the setting. Measured: a diagnostic build evaluating both semantics in every pixel_result found zero disagreements in ~2e10 first-pass and ~2.9e7 candidate tests over lyso_x06da_ref, cytc_x10sa, myob_x10sa, yag_x10sa_20keV, 4nwv and thau_bl1a_3p8keV (JUNGFRAU); the battery GPU runs before and after give bit-identical p.hkl on all six sets. The new knife-edge test constructs both cases (a checkerboard window whose square is var * 25 exactly and rounds onto the float threshold; a 0 above a negative checkerboard) and failed on the GPU before this change. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PXc1zD1yxHqaR1DGdCTHL4 |
||
|
|
7c1befd484 |
SearchSpaceGroup: ask the twin-immune zone of a lattice-holohedral candidate too, and do not read centring absences as screws
RESULT-CHANGING. A tetragonal crystal in 4 twinned ~0.3 by k,h,-l (3r6o, I4_1) was merged in I4_122. Since the beam-stop fix both search arms passed 422 (H ratio 1.51 < 1.85); before it the Lorentz-filtered arm refused at 2.13x and was overridden by the all-observation arm. Either way the twin-immune zone - the one reading a twin cannot fake - was never asked: the Stage A zone gate skipped any candidate that holds every rotation of its lattice, on the argument that no twin law exists for such a group. But the subgroup's twin law is one of the candidate's own operators, so the holohedral promotion is exactly the commonest merohedral-twin case (4 -> 422, 3 -> 32 on a rhombohedral lattice, 321 -> 622), and the L-test-under-merge gate leaves such a twin in the higher group by design. The gate now runs whenever the P1 merge reads twinned (<|L|> in [0.375, 0.44)), holohedral or not. 3r6o reads 422 over 4 at -58 nats (acentric). With 422 refused, the all-observation arm took 222 over 4: the same-order tie-break credits a group's axial two-folds with the screw evidence of their rows, and on a body-centred crystal the I centring kills the odd class of every principal row (30 nats each), so a 222 of the real 2-fold plus two twin laws beat the crystal's own 4. Rows whose odd class a centring extinguishes are no longer counted where the merge reads that centring on its general reflections (the centring class at < 0.25 of the rest's mean E^2; measured 0.11-0.13 for I on 3r6o, 0.97-1.00 for the absent centrings). Changed (CPU screen of 53 sets against the kept rc175 run 20261016-0057, plus 3r6o): - 3r6o: I4_122 -> I4_1 (deposited I4_1), TWINNING INDICATED, twin law h,-k,-l ~0.32; ISa 4.15 -> 7.77, R_meas 0.218 -> 0.146, CC1/2 0.989 -> 0.993. - 8c3e: P622 -> P321 with P3_121 | P3_221 as alternatives, screw on c undetermined (deposited P3_121, twinned): 622 refused at -70.8 nats; ISa 5.69 -> 6.91. Unchanged: 3mc4, 5j23, 6toc, 6oww, 6iu5/6/9, 2wnn, 2xfw, 4bwl, 5ebi, 2wnq, 6vww, 7k1l, 6pxb, 8xte, 8xtg, 9i80, 5uth, 6h5t, 8k1g, 6moj, 7kcn, 5vml, 3p85, 7rji, 8xtf, 9h0q, 7l84, 6v2r, 7t5t, 5m17, 6p8p, 3meb, 5cc8, 9lxl, 8v4j, 6zqr, 9fcf, 5src, 11if, cuhf2, lyso_x06da_ref, lyso_x10sa_90deg_1, thau_x10sa_16keV, thau_bl1a_6p5keV, insu_H_x06da_twin/notwin, insu_I_x06da_ref, cytc_x06da_1, myob_x06da_split, kdp_x10sa_20keV (space group identical, ISa within run noise; 7l84/5src/11if differ only by the model-adopted enantiomorph label). Test: a body-centred 4 twinned at 0.45, given its cell, stays in 4 (222 without the centring rule). [SearchSpaceGroup], [twinning], [twin] pass. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PXc1zD1yxHqaR1DGdCTHL4 |
||
|
|
f117484592 |
GPU rotation prediction walks only the l of each column that can cross the Ewald sphere
bragg_rot_kernel_3d ran one thread for every (h, k, l) of the box on every frame, while the CPU predictor already skips the l of an (h, k) column whose phi solution cannot lie within the rocking-curve test's reach (BraggPredictionRot: f(l) = |p0|^2 + 2 S0.p0 bounded by f_max, at most two intervals of l). The GPU predictor now walks the same l: - RotationColumnRange.h: the CPU predictor's phi limit and column bound, moved into a host/device header shared by both, unchanged in arithmetic except that the four divisions by 2 C*.C* are a product with its reciprocal (each end is widened by a whole index, which covers the rounding). - column_range_kernel: the l range of every column, one thread a column, in double; the column's b and c are evaluated as polynomials in h and k from coefficients set up on the host, and the blocks are 32 threads, because a consumer card runs double at a small fraction of the float rate on a unit the warps of a multiprocessor share (a warp per column with the range on lane 0 was slower than the whole box). - bragg_rot_kernel_columns: a warp per column, its l spread over the lanes; per (h, k, l) the same compute_reflections_rot. The output is sorted afterwards (OrderAndSelect), so the predictions and their order are those of the whole box. Kernel time on the RTX 5080 (nsys, whole run): 4nwv 1968 -> 415 ms (bragg 374 + ranges 41), myob 45.5 -> 49.9 ms (small box: the ranges cost more than they save there, ~4 ms a run). On the Windows laptop bragg_rot_kernel_3d was 9.4 s of 4nwv. BraggPredictionRotGPU_ColumnRangeKeepsEveryReflection: on 300 random lattices, geometries and rocking widths the pruned walk predicts bit for bit what the whole box does (the GPU twin of the CPU test). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PXc1zD1yxHqaR1DGdCTHL4 |
||
|
|
0d7e176b3c |
Speculative geometry probe beside the merge decided on bytes, not on a 12 GB card size
The speculative geometry probe waited for the main line's merge on every card below 12 GB (gpu_takes_turns), so on an 8 GB laptop card it always ran after the merge, as a serial "Geometry check" at the end of the run (Windows RTX PRO 2000: myob 1.4-1.7 s, lyso 0.6 s, 4nwv 3.2-4.4 s, against ~0.15 s where it overlaps). Now it is decided from bytes, up front and never from free memory: - GPUMerge::Holds(bytes): the main line says what its merge holds of the card once the scaling engine is ingested - the engine's DeviceBytes (an upper bound), twice where the all-observation arm gets an engine of its own - before the post-refinement that may start the probe is let go. A merge that has not said yet counts as leaving no room. Before the model stage it says the whole card: model validation and MR budget 80% of the card for themselves. - GPUWorkBeside(after_merges, bytes): the probe waits for the merges only where its own bytes and theirs exceed 80% of the first card's total (the same 80% the merge's and the model's GPU budgets use; on WDDM the rest is the paging margin). The image-pass / probe-pass turn-taking below 12 GB is unchanged. - Rugnux::IndexingProbeGPUBytes: the probe's first-pass spot workers at 24 bytes a pixel (GPUWorkersPerCard's figure) plus 0.65 GB per FFT indexer (1.24 GB measured for two). The spot-worker count is now one function (FirstPassSpotWorkers) for both. - The model stage waits for GPU work beside to end before it plans its GPU engines. Estimates on an 8.55 GB card: myob probe 4.1 GB + merge 0.6 GB -> beside (was: after); 4nwv probe 3.9 GB + merge 4.2 GB -> still after. On the RTX 5080 (16.3 GB): myob 4.8 + 0.6, 4nwv 4.5 + 8.4 = 13.0 of 13.04 GB -> beside, as before. Concurrency only: what each pass computes is unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PXc1zD1yxHqaR1DGdCTHL4 |
||
|
|
2f3885259f |
Merge mr-gpu-r2 into rc176: MR and model validation spread their rigid-body engines over the cards, and MR packs the transform where its cost model expects it faster; output unchanged
Validated on the 4x T4 server (round 2): p.hkl, p_model.pdb, MR_* and the candidate table identical on 9zlo/9s02/9gjx/4nwv against round 1 on 1 and 4 cards; 4nwv on 4 cards 140.8 -> 127.9 s wall (MR 34.0 -> 21.2 s; rotation 18.4 -> 4.8 s), 9zlo/9s02/9gjx 1-3% faster. Conflicts were the crash fix both branches carry: the branch's side taken (the per-card Reserve of the device test). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PXc1zD1yxHqaR1DGdCTHL4 |
||
|
|
aca27be862 |
jfjoch_writer writes rugnux's .mtz, _maps.mtz and _model.cif from the END blocks
New gemmi-only library JFJochRugnuxFiles (writer/), linked by JFJochWriter, so the writer needs no analysis library and builds with JFJOCH_WRITER_ONLY: - WriteMergedMtz / WriteMapCoefficientsMtz / PlacedModelStructure make the files from the structured blocks; WriteRugnuxResultFiles writes whichever blocks END carries beside the master, each under a temporary name and renamed into place, an existing file replaced only when the run's overwrite is set. A file that fails costs only itself (logged), not the run. - FillRugnuxResultBlocks reads the blocks back from the files rugnux wrote at a prefix (p.mtz, p_maps.mtz, p_model.cif), for the broker to fill END. WriteMtzReflections now goes through WriteMergedMtz (MergedReflectionsForWriter builds the block); its output is byte-identical to before, checked by md5 on a synthetic set in both the Friedel-merged and the anomalous layout. StreamWriter writes the files after the master and before the END ACK, so the ACK means they are in place; END receipt and each rename are logged at INFO with the wall-clock time, for last-frame-to-files latency. The broker's direct HDF5 pusher writes them too. Test: rugnux's three files -> blocks -> CBOR -> writer reproduces all of them (and _model.pdb) byte for byte; a ~25k-reflection END is 2.7 MB. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
bc5577d32c |
Merge mr-multigpu-crash-fix into rc176: rigid-body engine calls restore the caller's card and the MR GPU functions run on their own card, fixing an illegal memory access in MR with engines on other cards; output unchanged on one card
Build Packages / build:portable:linux-x86_64:cuda (push) Successful in 27m42s
Build Packages / build:portable:macos-arm64:nocuda (push) Successful in 5m35s
Build Packages / build:rugnux:linux-aarch64:cuda (push) Successful in 17m8s
Build Packages / build:jfjoch:rocky8:nocuda (push) Successful in 30m6s
Build Packages / build:jfjoch:rocky9:nocuda (push) Successful in 20m19s
Build Packages / build:jfjoch:ubuntu2204:nocuda (push) Successful in 13m19s
Build Packages / build:jfjoch:ubuntu2404:nocuda (push) Successful in 16m43s
Build Packages / HDF5 consumer tests (DIALS, XDS) (push) Successful in 35m34s
Build Packages / Create release (push) Successful in 7s
Build Packages / Generate python client (push) Successful in 11s
Build Packages / Build documentation (push) Successful in 45s
Build Packages / build:jfjoch:ubuntu2204:cuda (push) Successful in 24m56s
Build Packages / build:jfjoch:ubuntu2404:cuda (push) Successful in 28m38s
Build Packages / build:jfjoch:rocky8:cuda (push) Successful in 29m13s
Build Packages / build:jfjoch:rocky9:cuda (push) Successful in 30m13s
Build Packages / build:jfjoch:rocky9:cuda-sls9 (push) Successful in 30m37s
Build Packages / Unit tests (push) Successful in 1h12m25s
Build Packages / Validation Battery (push) Successful in 33m41s
Build Packages / build:portable:linux-x86_64:nocuda (push) Successful in 23m23s
Build Packages / build:portable:windows-x86_64:nocuda (push) Successful in 21m56s
Build Packages / build:portable:windows-x86_64:cuda (push) Successful in 27m8s
Build Packages / build:jfjoch:rocky8:cuda-sls9 (push) Successful in 29m12s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PXc1zD1yxHqaR1DGdCTHL4 |
||
|
|
a47f030074 |
Merge singular-fix into rc176: the model-scale fit no longer stops on a singular normal matrix (a reflection whose |Fcalc| the solvent cancels exactly; an underflowed Levenberg-Marquardt step), output unchanged where it ran before
Fixes the GPU-path crash after MR on 8sqo, 8v4o and 9zmu (all three now place in the deposited group) and the CPU-only ModelValidation_CCModelUnrelatedModelConfirmsNothing failure. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PXc1zD1yxHqaR1DGdCTHL4 |
||
|
|
210664f454 |
Model scale fit: no log ratio at |Fcalc| = 0, and no LM step once the model has underflowed
Two ways the scale fit's normal matrix went singular and gemmi's jordan_solve threw "Trying to reverse singular matrix. Column 0 is zeroed.", ending the run: 1. The isotropic start (fit_isotropic_b_approximately) takes log(Fobs/|Fcalc|) over the strong reflections. At a phase-restricted reflection whose Fcalc and Fmask share a phase, some solvent pair of the k_sol/b_sol grid can cancel the model exactly in float, |Fcalc + k_sol exp(-b_sol s^2) Fmask| = 0. log(Fobs/0) = inf made that grid point's k_overall and B NaN, every sum of the Levenberg-Marquardt NaN, and the solve failed. This is what stopped three open-arm sets in the output pass after MR on the GPU (the scale fit after model validation's rigid body): one strong reflection, one grid point. The CPU path has the same exposure; which grid point hits an exact zero depends on the last bits of Fcalc, so the --no-gpu run of the same set went through. Such a reflection has no log ratio and is now left out of the start - in the GPU kernel, in FixedSolventFit::Start and, as a marked local change, in gemmi's own fit_isotropic_b_approximately, so the three stay equal and the held-solvent fits are covered too. 2. In FitModelScale's CPU Levenberg-Marquardt (ModelValidation_CCModelUnrelatedModelConfirmsNothing in a CUDA=OFF build): on 66 reflections of an unrelated model the fit walked to k_overall -424 and a B where k exp(-B s^2) |F| underflows at every reflection; the squares in J^T J were all 0 while J^T r kept a residue near 1e-210, which jordan_solve rejects. The fit now ends there, at its best so far, as it would at the lambda limit; that grid point then loses on R. The GPU fit takes the derivatives in float and their squares in double, so it cannot reach this state. Both changes only touch fits that threw before. Byte identity checked against an rc176 build on the standard and inhouse timing benchmarks and on 4nwv, 8tyy, 6oel (p.hkl, p_model.pdb, MTZ data, MR_* report keys). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PXc1zD1yxHqaR1DGdCTHL4 |
||
|
|
80f634b641 |
MR GPU: engines spread over the cards; the transform packed where it is expected faster
Build Packages / Create release (push) Successful in 8s
Build Packages / build:portable:macos-arm64:nocuda (push) Successful in 5m31s
Build Packages / HDF5 consumer tests (DIALS, XDS) (push) Successful in 37m25s
Build Packages / build:portable:linux-x86_64:cuda (push) Canceled after 0s
Build Packages / build:rugnux:linux-aarch64:cuda (push) Canceled after 0s
Build Packages / Validation Battery (push) Canceled after 0s
Build Packages / Unit tests (push) Canceled after 48m13s
Build Packages / build:jfjoch:rocky8:cuda (push) Canceled after 0s
Build Packages / build:jfjoch:rocky8:nocuda (push) Canceled after 0s
Build Packages / build:jfjoch:rocky9:cuda (push) Canceled after 0s
Build Packages / build:jfjoch:rocky9:cuda-sls9 (push) Canceled after 0s
Build Packages / build:jfjoch:rocky9:nocuda (push) Canceled after 0s
Build Packages / build:jfjoch:ubuntu2204:cuda (push) Canceled after 0s
Build Packages / build:jfjoch:ubuntu2204:nocuda (push) Canceled after 0s
Build Packages / build:jfjoch:ubuntu2404:cuda (push) Canceled after 0s
Build Packages / build:jfjoch:ubuntu2404:nocuda (push) Canceled after 0s
Build Packages / Generate python client (push) Canceled after 0s
Build Packages / Build documentation (push) Canceled after 0s
Build Packages / build:portable:windows-x86_64:nocuda (push) Successful in 12m45s
Build Packages / build:portable:linux-x86_64:nocuda (push) Canceled after 0s
Build Packages / build:jfjoch:rocky8:cuda-sls9 (push) Canceled after 0s
Build Packages / build:portable:windows-x86_64:cuda (push) Canceled after 21m47s
Engine placement: the rigid-body engines past this card's first go one card after the other in turn, from
the next card and this one last, each within half of its budget. A small cell on four cards (24 engines of
0.09 GB) had put all of them on this card, which has room for them, where rc176 spread them; now 6/6/6/6.
A large cell on four 15.6 GB cards keeps T+1/T+2/T+2/T+2.
Layout: packing was refused wherever it cost any card an engine, which kept 4nwv plain on four T4s although
the packed rotation function on ONE card (15.1 s) already beat plain over four (18.5 s). Now the two layouts'
plans are compared on a small cost model, decided once before the search from sizes and counts alone:
seconds = rotation interpolations (orientations x reflections x operators) x s/interpolation / cards with a copy
+ rigid-body fits at once x engine GB x s/(fit GB) / engines
Constants measured on 4nwv on Tesla T4 (17255 x 244183 x 4 interpolations): 75.8 s plain and 15.1 s packed on
one card; rescoring + null 28.5 s with one engine and 11.6 s with seven, 9 fits of 2.10 GB, so 19.7 s shared
among the engines. Packing must still keep the search, the scores and (where plain has it) the rigid body on
the GPU, and the budget must hold both grids while the packed one is made. Expected on four T4s: packed
T+1/T+1/T+1/T+1, 8.7 s against 21.8 s plain. One card is unchanged (the engines are the same either way, so
packed). The layout line now logs both expected times and the search's size.
Layout and engine count change where the work runs, never a number.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PXc1zD1yxHqaR1DGdCTHL4
|
||
|
|
3fa17b9385 |
Model validation: the rigid-body engines on every card in turn, even where this card has room for all
The engines past this card's first now go one card after the other, from the next card and this one last, each within half of its own budget, as MR's do. Before, this card took every extra engine it had room for and the other cards only the rest, so a small cell on four cards ran all its fits on one. Where this card has no room for a second engine (a large cell on 15.6 GB cards) the plan is unchanged: 1/3/3/3. This card's scale fits take the room its engines leave. Engines are interchangeable and deterministic, so only where fits run changes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PXc1zD1yxHqaR1DGdCTHL4 |
||
|
|
46c44e04d9 |
Rotation scaling: a host-memory budget decides what runs side by side
The run's budget (ProcessConfig::host_memory_budget_bytes, else 75% of the machine's RAM) is decided once and logged, and sizes the host worker pool. Three concurrencies of the scaling chain are decided on it from counts known before each starts (RotationScaleMerge::HostIngestBytes, HostMergeBytes, HostBytesBound), each logged where it serialises: - the quality guard's merge beside the main ingest: where they would not fit together, the guard merges first; - the canonical pass's post-refinement beside the merge chain: done before the first merge; - the all-observation P1 search merge beside the main engine's (GPU path): started where the search first reads it, after the main engine's merges and the release of their scratch. None of these reads what the other writes while it runs, so only the order changes: a [large] test runs the rotation set at a 1 TB and a 1 MB budget and compares the .hkl byte for byte. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PXc1zD1yxHqaR1DGdCTHL4 |
||
|
|
3ebf085e4c |
Host memory: the machine's total, a budget decided from it, and a pool for large per-worker buffers
get_host_total_memory (sysconf / hw.memsize / GlobalMemoryStatusEx), DefaultHostMemoryBudget at 75% of the total - decided from the total, never from what is free, as the GPU plans are - and HostWorkerPool, a process-wide pool (a third of the budget) that workers reserve their large buffers against before making them, so how many run at once is decided by bytes rather than threads. Only scheduling reads any of it. [HostMemory] tests. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PXc1zD1yxHqaR1DGdCTHL4 |
||
|
|
b004a846dd |
RigidBodyGPU_CallsLeaveTheCallerOnItsCard: one engine on each card with the per-card Reserve
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PXc1zD1yxHqaR1DGdCTHL4 |
||
|
|
fbdf036e6f |
Rigid-body engines leave the calling thread on its own card; the MR search runs on its transform's card
Every RigidBodyGPUEngine call did cudaSetDevice(engine's card) and never set the caller back. Molecular replacement's group threads refine copies on the pool's engines - on any card where every engine on this one is taken - and then run the next translation function on the same thread. MolecularReplacementGPU ran its calls on whatever card the thread was on, so that function's buffers and cuFFT plan were made on the engine's card, beside the transform and the stream on the search's card: an illegal memory access, 9s02 with four cards visible, every run (the further-copies loop: refine a trial on another card's engine, then translation_function on the group thread). - Each engine call (and the constructor) now holds a DeviceGuard: on the engine's card for the call, back on the caller's after it. - MolecularReplacementGPU remembers the card its transform was uploaded to and runs every call (and its destructor) there, whichever card the calling thread is on. - RigidBodyGPU_CallsLeaveTheCallerOnItsCard: one engine per card, all taken from one thread; the thread's card is unchanged after each call (meaningful with two or more cards). No number changes: where every call runs is the same card as before for each object. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PXc1zD1yxHqaR1DGdCTHL4 |
||
|
|
a3f30d03c1 |
Rigid-body engines leave the calling thread on its own card; the MR search runs on its transform's card
Every RigidBodyGPUEngine call did cudaSetDevice(engine's card) and never set the caller back. Molecular replacement's group threads refine copies on the pool's engines - on any card where every engine on this one is taken - and then run the next translation function on the same thread. MolecularReplacementGPU ran its calls on whatever card the thread was on, so that function's buffers and cuFFT plan were made on the engine's card, beside the transform and the stream on the search's card: an illegal memory access, 9s02 with four cards visible, every run (the further-copies loop: refine a trial on another card's engine, then translation_function on the group thread). - Each engine call (and the constructor) now holds a DeviceGuard: on the engine's card for the call, back on the caller's after it. - MolecularReplacementGPU remembers the card its transform was uploaded to and runs every call (and its destructor) there, whichever card the calling thread is on. - RigidBodyGPU_CallsLeaveTheCallerOnItsCard: one engine per card, all taken from one thread; the thread's card is unchanged after each call (meaningful with two or more cards). No number changes: where every call runs is the same card as before for each object. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PXc1zD1yxHqaR1DGdCTHL4 |
||
|
|
38e75c8e5b |
HDF5Writer_Socket: wait for the subscription before the first file is announced
The test connected its SUB socket and wrote at once; file 1 is closed and announced on the PUB socket right after the second image, and PUB drops whatever it sends before the subscription has reached it (slow joiner). On a loaded CI runner the first notification was lost and the test read file 2 where it expected file 1. Wait 2 s after subscribing, as the preview and metadata socket tests already do. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PXc1zD1yxHqaR1DGdCTHL4 |
||
|
|
0f461a65a2 |
Merge mr-transform-layout: the corner-packed molecular transform beside MR on every card
Build Packages / Create release (push) Successful in 7s
Build Packages / build:portable:macos-arm64:nocuda (push) Successful in 4m38s
Build Packages / build:rugnux:linux-aarch64:cuda (push) Successful in 8m58s
Build Packages / build:portable:linux-x86_64:cuda (push) Successful in 18m0s
Build Packages / build:jfjoch:rocky8:nocuda (push) Successful in 21m31s
Build Packages / build:jfjoch:rocky9:nocuda (push) Successful in 21m49s
Build Packages / build:jfjoch:ubuntu2204:nocuda (push) Successful in 13m41s
Build Packages / HDF5 consumer tests (DIALS, XDS) (push) Successful in 25m30s
Build Packages / build:jfjoch:ubuntu2404:nocuda (push) Successful in 15m22s
Build Packages / Generate python client (push) Successful in 31s
Build Packages / Build documentation (push) Successful in 1m13s
Build Packages / build:jfjoch:ubuntu2204:cuda (push) Successful in 18m45s
Build Packages / build:jfjoch:rocky8:cuda (push) Successful in 23m54s
Build Packages / build:jfjoch:rocky9:cuda-sls9 (push) Successful in 25m56s
Build Packages / build:jfjoch:rocky9:cuda (push) Successful in 25m47s
Build Packages / build:jfjoch:ubuntu2404:cuda (push) Successful in 20m33s
Build Packages / Unit tests (push) Failing after 1h28m5s
Build Packages / Validation Battery (push) Successful in 34m34s
Build Packages / build:portable:linux-x86_64:nocuda (push) Successful in 14m20s
Build Packages / build:portable:windows-x86_64:nocuda (push) Successful in 21m55s
Build Packages / build:portable:windows-x86_64:cuda (push) Successful in 26m7s
Build Packages / build:jfjoch:rocky8:cuda-sls9 (push) Successful in 21m54s
Combines mr-multigpu (per-card engine budgets, a transform copy on each other card, the rotation/translation functions split over the cards) with mr-transform-layout (the GPU transform optionally held corner-packed, same bits, 2.2x faster rotation function). Conflict (MolecularReplacement.cpp): the two new functions side by side (PackMolecularTransformGPU next to SplitRotationFunction/SplitTranslationFunction). On top of the textual resolution: - One layout decision for all cards, not one per card: the functions are split into equal slices, so a mix of packed and plain cards would run at the speed of the plain ones; either layout gives the same bits. - PackMolecularTransformGPU now plans with the other cards' budgets too and packs only where every card keeps what the plain plan gives it: this card's transform, engines and score engine, and on every other card its copy and its engine count. A packed copy is made after the card's engines are reserved; copy and engines within half of that card's budget leave room for the plain grid it is made from. - The copies on the other cards are made in the chosen layout, and the per-card plan (copies, engines, room) is made with the bytes actually placed. - Test: four 15.6 GB cards stay plain (packed, each other card would fall from T+2 to T+1); with 24 GB cards beside, packed. So on a 4x T4 4nwv runs split and plain, on one card packed; whether giving up 3 of 7 engines for the packed rotation function would pay there is left to a server measurement. Workstation (1x RTX 5080, --gpulock), against rc176: battery timing --benchmark standard (9zlo, 9s02, 9gjx, 4nwv) and --benchmark inhouse (myob, cytc, 4nwv) on GPU, inhouse also --no-gpu: p.hkl, p_model.pdb and the MR_ report block byte-identical on every set. 4nwv GPU: rotation 5.53 -> 2.50 s, MR step 20.1 -> 16.5 s (packed, 2.28 GB in place of 0.84 GB). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PXc1zD1yxHqaR1DGdCTHL4 |
||
|
|
3aa67a6059 |
MR GPU: corner-packed molecular transform for the rotation function
Each sample of the molecular transform interpolates over 8 grid corners that lie in four u-rows of the half-l grid, 4-5 32-byte sectors per sample. On the GPU the transform can now be held packed: every point (i, j, l) stores its four (v, w) corners, so the two neighbouring records hold all eight, read from two places. The packed grid is cut to |u| <= reach as the plain one already is in v, and has the conjugate plane l = -1 in front; below l = -1 the eight corners are read mirrored about -i0 - 1 and conjugated. Same floats, same accumulation order: rotation and translation functions give the same bits (checked in MolecularReplacement_GPUMatchesCPU). The layout is chosen up front from the budget (PackMolecularTransformGPU): packed where the answer merge's plan holds every part beside it that it holds beside the plain transform, and the budget holds both grids while the packed one is made from the plain one on the device; logged either way. The upload no longer stages a host copy of the grid. The CPU At() is unchanged: a microbenchmark gained 1.3x single-threaded and ~1.0-1.1x at 16-32 threads, not worth 2.7x the host memory. 4nwv (moved model, timing benchmark), RTX 5080: rotation 5.56 -> 2.48 s, MR step 20.9 -> 16.7 s; transform on the card 0.84 -> 2.28 GB. p.hkl, p_model.pdb and the MR_ report block byte-identical on the timing sets (GPU and --no-gpu) and on 4nwv, 8tyy, 6oel, 3inp. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PXc1zD1yxHqaR1DGdCTHL4 |
||
|
|
bfc6ca8487 |
MR and model validation: use every card's memory, split MR's functions over the cards
On a multi-GPU host the structure stage ran essentially on one card: the rotation function's launches all went to the search's card, and the rigid-body engines of model validation and MR were admitted only within half of that one card's budget, although RigidBodyGPUPool already placed engines on other cards. On a 4x T4 server 4nwv's MR rotation function took 75.8 s on one card, validation queued its 10 fits on one engine and MR's rescoring and null got one engine. - PlanModelValidationGPU / PlanMolecularReplacementGPU: this card is planned exactly as on a machine with it alone (GPU-vs-CPU placement unchanged: 80% of the total, less what is resident). The rigid-body engines it has no room for go on the other cards in turn, each against its own budget (80% of its total, less the resident bytes, counted on every card) within half of it. MR also puts a copy of the molecular transform on each other card within half of its budget. - RigidBodyGPUPool::Reserve takes per-card engine counts. - Validation forwards the most it holds on any card as gpu_bytes to a validation beside, and may run one beside only where twice that fits every card's budget. - MR splits every rotation and translation function into contiguous slices of the orientation list over the cards holding a transform copy (and room for the call's buffers), one thread per card, gathered back in order. Each orientation is scored by itself (one block / one map), nothing is summed across orientations, so N cards give the bytes of one. - ScoreEngines keeps a room per card; score engines always go on the search's own card; function buffers are held on the card they run on. Byte-identical at N=1 (workstation, one RTX 5080): timing benchmark (myob, cytc, 4nwv) and 4nwv, 8tyy, 6oel, 3inp with --model give the same p.hkl, MTZ data, p_model.pdb, maps and report against rc176. New tests: per-card plans on four 15.6 GB cards (validation 1/3/3/3 engines, MR T+1/T+2/T+2/T+2), and the split driven over 1-4 virtual cards on one device, bitwise equal to one card. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PXc1zD1yxHqaR1DGdCTHL4 |
||
|
|
19b135186d |
v1.0.0-rc.175 (#85)
Build Packages / Create release (push) Successful in 7s
Build Packages / build:portable:macos-arm64:nocuda (push) Successful in 4m56s
Build Packages / build:rugnux:linux-aarch64:cuda (push) Successful in 9m10s
Build Packages / build:portable:linux-x86_64:cuda (push) Successful in 16m56s
Build Packages / build:jfjoch:rocky8:nocuda (push) Successful in 20m59s
Build Packages / build:jfjoch:rocky9:nocuda (push) Successful in 21m17s
Build Packages / build:jfjoch:ubuntu2204:nocuda (push) Successful in 14m14s
Build Packages / HDF5 consumer tests (DIALS, XDS) (push) Successful in 25m59s
Build Packages / build:jfjoch:ubuntu2404:nocuda (push) Successful in 15m52s
Build Packages / Generate python client (push) Successful in 29s
Build Packages / Build documentation (push) Successful in 1m19s
Build Packages / build:jfjoch:ubuntu2204:cuda (push) Successful in 20m49s
Build Packages / build:jfjoch:rocky9:cuda-sls9 (push) Successful in 25m31s
Build Packages / build:jfjoch:rocky8:cuda (push) Successful in 25m24s
Build Packages / build:jfjoch:rocky9:cuda (push) Successful in 26m5s
Build Packages / build:jfjoch:ubuntu2404:cuda (push) Successful in 22m19s
Build Packages / Unit tests (push) Failing after 2h28m24s
Build Packages / Validation Battery (push) Successful in 40m33s
Build Packages / build:portable:linux-x86_64:nocuda (push) Successful in 13m51s
Build Packages / build:portable:windows-x86_64:nocuda (push) Successful in 21m25s
Build Packages / build:portable:windows-x86_64:cuda (push) Successful in 25m48s
Build Packages / build:jfjoch:rocky8:cuda-sls9 (push) Successful in 19m33s
* Rugnux: Processes a collection live while jfjoch_broker writes it (`rugnux <master.h5> <broker URL>`). * Rugnux: Processing starts on the first images and confirms its choices once all are in, so analysis can begin during collection. * Rugnux: Faster processing, especially on servers with several GPUs and CPU sockets and on computers without a GPU (`--no-gpu`, macOS). * Rugnux: Uses much less GPU memory, so large data sets stay on the GPU of smaller cards, and a data set too large for the card is processed on the CPU instead. * Rugnux: On macOS, Bragg integration runs on the Apple GPU. * Rugnux: Better handling of twinning and pseudo-symmetry, with the twin hypothesis written as `<prefix>_twin_<SG>.mtz`, and a wrong `--model` no longer confirms the data or decides the hand. * Rugnux: `--model` accepts predicted (AlphaFold) models and falls back to molecular replacement when the model is not placed as a rigid body (experimental `--mr` forces it), settling space group, hand and twinning and writing a different answer as `<prefix>_mr.mtz`. * Rugnux: Molecular replacement is faster and settles the space group in more cases with several copies in the asymmetric unit. * Rugnux: Deposition-ready mmCIF, a richer report, and numbered steps on the terminal with the full log in `<prefix>_log.txt`; `_P1.mtz`, `--estimate-beam-center` and `--beam-center-search` are removed. * Rugnux: The beam-stop shadow is found correctly on tilted detectors. * Rugnux: Stills files that record a stationary goniometer axis get the default stills geometry refinement. * jfjoch_viewer: "Analyze dataset" uses the same defaults as a bare `rugnux <file>`, and shows the results of processed CBF, marCCD and SMV sweeps. * jfjoch_viewer: The Files panel refreshes on F5 and every few seconds, and the plot type and other selections stay put during live collection. * jfjoch_writer: Memory stays bounded and old data files are closed efficiently on long runs, any failure ends the run in an error state the broker is told about, and the master file appears only after its data files; the ZeroMQ pusher logs when a stalled writer makes it drop images. * Fixes: The TCP image pusher no longer blocks the broker's receiver, GPU out-of-memory failures stop with a clear message, and the XDS plugin masks module and chip edges. --------- Co-authored-by: Filip Leonarski <jungfrau@filips-mac-mini.home> Reviewed-on: #85 Co-authored-by: Filip Leonarski <filip.leonarski@psi.ch> |
||
|
|
a395f358ef |
1.0.0-rc.174 (#84)
Build Packages / Create release (push) Successful in 17s
Build Packages / build:viewer:macos-arm64:nocuda (push) Successful in 3m22s
Build Packages / build:rugnux:macos-arm64:nocuda (push) Successful in 2m37s
Build Packages / build:rugnux:linux-aarch64:cuda (push) Successful in 9m33s
Build Packages / build:rugnux:linux-x86_64:cuda (push) Successful in 10m39s
Build Packages / build:viewer:linux-x86_64:nocuda (push) Successful in 11m4s
Build Packages / build:jfjoch:rocky8:nocuda (push) Successful in 17m37s
Build Packages / build:jfjoch:rocky9:nocuda (push) Successful in 18m49s
Build Packages / build:viewer:windows-x86_64:nocuda (push) Successful in 19m10s
Build Packages / build:viewer:windows-x86_64:cuda (push) Successful in 24m26s
Build Packages / HDF5 consumer tests (DIALS, XDS) (push) Successful in 25m31s
Build Packages / build:jfjoch:ubuntu2404:nocuda (push) Successful in 18m54s
Build Packages / build:jfjoch:ubuntu2204:nocuda (push) Successful in 20m45s
Build Packages / Generate python client (push) Successful in 37s
Build Packages / Build documentation (push) Successful in 1m32s
Build Packages / build:rugnux:windows-x86_64:cuda (push) Successful in 14m37s
Build Packages / build:jfjoch:rocky9:cuda-sls9 (push) Successful in 21m6s
Build Packages / build:jfjoch:rocky8:cuda (push) Successful in 19m49s
Build Packages / build:jfjoch:rocky9:cuda (push) Successful in 20m29s
Build Packages / build:jfjoch:ubuntu2204:cuda (push) Successful in 17m2s
Build Packages / build:jfjoch:ubuntu2404:cuda (push) Successful in 14m27s
Build Packages / Unit tests (push) Successful in 1h18m12s
Build Packages / build:viewer:linux-x86_64:cuda (push) Successful in 13m19s
Build Packages / build:jfjoch:rocky8:cuda-sls9 (push) Successful in 20m20s
* Rugnux: Performance improvements on GPU and CPU (more of the pre-scan and of scaling on the GPU, faster CPU spot finding and crystal refinement), with unchanged results. * Rugnux: More robust processing - patches of persistently hot pixels are masked, an inconsistent merge triggers a retry at the measured beam centre, and builds targeting different CPU levels give the same results. * Rugnux: Improved scaling and merging - reflections with an overloaded pixel are dropped, as in XDS, sparse rotation sweeps are scaled more reliably, and French-Wilson amplitudes use an anisotropic Wilson prior. * Rugnux: Improved space-group determination - glide planes in groups without a centre of symmetry, screw axes from short or weak axial rows kept when a higher group is adopted, and more reliable decisions on twinned and pseudo-symmetric crystals. * Rugnux: Improved small-molecule processing - spots that grow wider than the integration disk and split spots are integrated over their measured footprint, sparse lattices are integrated on every frame, and the `.hkl` file holds unmerged scaled reflections (SHELX HKLF 4). * Rugnux: Reads Rigaku d*TREK SMV images (Saturn CCD), including detector 2theta and encoded pixel overflows; home-source (rotating-anode) datasets were added to the validation battery. * jfjoch_viewer: Fixed processing failing at the end with "Wrong JPEG library version" on Linux; the merge window shows the space group with proper subscripts and a checklist of crystal pathologies. Reviewed-on: #84 Co-authored-by: Filip Leonarski <filip.leonarski@psi.ch> |
||
|
|
84228bf8be |
v1.0.0-rc.173 (#83)
Build Packages / Create release (push) Successful in 24s
Build Packages / build:viewer:macos-arm64:nocuda (push) Successful in 3m29s
Build Packages / build:rugnux:macos-arm64:nocuda (push) Successful in 2m43s
Build Packages / build:rugnux:linux-aarch64:cuda (push) Successful in 8m27s
Build Packages / build:rugnux:linux-x86_64:cuda (push) Successful in 9m53s
Build Packages / build:viewer:linux-x86_64:nocuda (push) Successful in 9m58s
Build Packages / build:jfjoch:rocky8:nocuda (push) Successful in 13m39s
Build Packages / build:viewer:windows-x86_64:nocuda (push) Successful in 18m37s
Build Packages / build:jfjoch:rocky9:nocuda (push) Successful in 16m32s
Build Packages / build:viewer:windows-x86_64:cuda (push) Successful in 24m11s
Build Packages / HDF5 consumer tests (DIALS, XDS) (push) Successful in 25m30s
Build Packages / build:jfjoch:ubuntu2404:nocuda (push) Successful in 19m3s
Build Packages / build:jfjoch:ubuntu2204:nocuda (push) Successful in 20m23s
Build Packages / Generate python client (push) Successful in 50s
Build Packages / Build documentation (push) Successful in 1m16s
Build Packages / build:jfjoch:rocky9:cuda-sls9 (push) Successful in 21m0s
Build Packages / build:jfjoch:rocky8:cuda (push) Successful in 18m38s
Build Packages / build:rugnux:windows-x86_64:cuda (push) Successful in 14m33s
Build Packages / build:jfjoch:rocky9:cuda (push) Successful in 17m55s
Build Packages / build:jfjoch:ubuntu2204:cuda (push) Successful in 20m50s
Build Packages / build:jfjoch:ubuntu2404:cuda (push) Successful in 18m38s
Build Packages / Unit tests (push) Successful in 1h46m14s
Build Packages / build:viewer:linux-x86_64:cuda (push) Successful in 11m22s
Build Packages / build:jfjoch:rocky8:cuda-sls9 (push) Successful in 19m41s
* jfjoch_broker: Optional per-dataset authentication - statistics, images and plots can require a bearer token, which jfjoch_viewer supports. * jfjoch_viewer: Dark mode and a theme-matched colour scheme, a magnifier panel, and simpler contrast and background controls. * Rugnux: Multiple performance improvements on GPU and CPU (CPU-only processing up to 40% faster, faster image decoding on ARM), with unchanged results. * Rugnux: `--model` rigid-body refinement runs on the GPU, and the model-validation check is faster and more reliable. * Rugnux: Improved scaling and merging - error model, outlier rejection, absorption correction and French-Wilson amplitudes now agree more closely with XDS and ctruncate. * Rugnux: Improved integration - radial background on powder and ice rings, crowded rotation data keep their reflections, and CPU-only builds integrate large unit cells as GPU builds do. * Rugnux: More robust detector geometry - measured beam centre, X-ray bandwidth and goniometer rate, and geometry refinement accepted only on significant evidence. * Rugnux: Merged files are written in the standard setting, or in the setting of a reference MTZ, structure-factor mmCIF or model, with its free-R flags. * Rugnux: Richer report - ice and powder rings, further lattices, superstructure candidates and mosaicity, with warnings worded as prompts to check. * Rugnux: Clear error messages when a data set needs more GPU or host memory than is available. Reviewed-on: #83 Co-authored-by: Filip Leonarski <filip.leonarski@psi.ch> |
||
|
|
6dfe065365 |
v1.0.0-rc.172 (#82)
Build Packages / Create release (push) Successful in 16s
Build Packages / build:rugnux-tgz (x86_64) (push) Successful in 9m15s
Build Packages / build:viewer-tgz:cpu (push) Successful in 10m11s
Build Packages / build:viewer-tgz:cuda (push) Successful in 12m6s
Build Packages / build:rpm (rocky8_nocuda) (push) Successful in 15m44s
Build Packages / build:rpm (rocky9_nocuda) (push) Successful in 16m1s
Build Packages / build:windows:nocuda (push) Successful in 17m29s
Build Packages / build:windows:cuda (push) Successful in 19m58s
Build Packages / HDF5 consumer tests (DIALS, XDS) (push) Successful in 24m7s
Build Packages / build:rpm (ubuntu2404_nocuda) (push) Successful in 19m8s
Build Packages / build:rugnux:windows (push) Successful in 10m58s
Build Packages / build:rpm (ubuntu2204_nocuda) (push) Successful in 20m46s
Build Packages / Generate python client (push) Successful in 53s
Build Packages / build:rpm (rocky8_sls9) (push) Successful in 20m13s
Build Packages / Build documentation (push) Successful in 1m36s
Build Packages / build:rpm (rocky9_sls9) (push) Successful in 19m57s
Build Packages / build:rpm (rocky8) (push) Successful in 18m7s
Build Packages / build:rpm (rocky9) (push) Successful in 18m54s
Build Packages / build:rpm (ubuntu2204) (push) Successful in 19m32s
Build Packages / build:rpm (ubuntu2404) (push) Successful in 17m30s
Build Packages / Unit tests (push) Successful in 1h39m2s
Build Packages / build:rugnux:aarch64 (cross) (push) Successful in 8m27s
* Fixed `jfjoch_broker` cancelling every data collection with a CUDA "out of memory" error after long operation: GPU memory no longer leaks with each collection. * Rugnux scales a rotation sweep until the per-frame scales settle instead of for a fixed three rounds, and says so when they did not - merged intensities, and the space group, resolution cut and frame rejection read off them, change accordingly; `--scaling-iterations` is now the cap on that loop (default 100). * Rugnux places every frame of a marCCD, SMV or miniCBF series at the spindle angle its own header states, so a series with missing frames, or with angles written modulo 360, is no longer read at the wrong geometry or refused. * Every rotation run writes two diagnostic files beside its reflections: `<prefix>_detector.jpg`, the detector projection with the pixel mask and the detected beam-stop shadow drawn on it, and `<prefix>_plot.txt`, one row per image. Reviewed-on: #82 Co-authored-by: Filip Leonarski <filip.leonarski@psi.ch> |
||
|
|
30b6800289 |
v1.0.0-rc.171 (#81)
Build Packages / build:windows:nocuda (push) Successful in 17m20s
Build Packages / build:windows:cuda (push) Successful in 19m52s
Build Packages / build:viewer-tgz:cpu (push) Successful in 9m38s
Build Packages / build:viewer-tgz:cuda (push) Successful in 11m18s
Build Packages / build:rugnux-tgz (x86_64) (push) Successful in 9m34s
Build Packages / HDF5 consumer tests (DIALS, XDS) (push) Successful in 20m33s
Build Packages / Create release (push) Successful in 33s
Build Packages / build:rugnux:windows (push) Successful in 12m0s
Build Packages / build:rpm (rocky8_nocuda) (push) Successful in 15m42s
Build Packages / build:rpm (ubuntu2204_nocuda) (push) Successful in 14m59s
Build Packages / build:rpm (rocky9_nocuda) (push) Successful in 16m8s
Build Packages / build:rpm (ubuntu2404_nocuda) (push) Successful in 14m35s
Build Packages / build:rpm (rocky8_sls9) (push) Successful in 16m55s
Build Packages / build:rpm (rocky9_sls9) (push) Successful in 16m58s
Build Packages / Generate python client (push) Successful in 16s
Build Packages / build:rpm (rocky8) (push) Successful in 15m21s
Build Packages / Build documentation (push) Successful in 54s
Build Packages / build:rpm (rocky9) (push) Successful in 16m23s
Build Packages / build:rpm (ubuntu2204) (push) Successful in 12m2s
Build Packages / build:rpm (ubuntu2404) (push) Successful in 10m6s
Build Packages / Unit tests (push) Successful in 1h10m26s
Build Packages / build:rugnux:aarch64 (cross) (push) Successful in 5m42s
* Rugnux: basic support for CCD images (marCCD, SMV) and for gzipped miniCBF. * `jfjoch_viewer`: opens the CCD formats, and fixes to the dataset plots. * Documentation updates. Reviewed-on: #81 Co-authored-by: Filip Leonarski <filip.leonarski@psi.ch> |
||
|
|
cb5a2f032a |
v1.0.0-rc.170 (#80)
Build Packages / Create release (push) Successful in 23s
Build Packages / build:rugnux-tgz (x86_64) (push) Successful in 10m6s
Build Packages / build:viewer-tgz:cpu (push) Successful in 11m15s
Build Packages / build:viewer-tgz:cuda (push) Successful in 12m21s
Build Packages / build:windows:nocuda (push) Successful in 17m9s
Build Packages / build:windows:cuda (push) Successful in 19m49s
Build Packages / HDF5 consumer tests (DIALS, XDS) (push) Successful in 25m42s
Build Packages / build:rpm (ubuntu2204_nocuda) (push) Successful in 16m0s
Build Packages / build:rpm (ubuntu2404_nocuda) (push) Successful in 14m54s
Build Packages / build:rpm (rocky8_nocuda) (push) Successful in 17m7s
Build Packages / build:rugnux:windows (push) Successful in 10m47s
Build Packages / build:rpm (rocky9_nocuda) (push) Successful in 17m4s
Build Packages / build:rpm (rocky8_sls9) (push) Successful in 17m8s
Build Packages / Generate python client (push) Successful in 45s
Build Packages / Build documentation (push) Successful in 1m45s
Build Packages / build:rpm (rocky9_sls9) (push) Successful in 19m23s
Build Packages / build:rpm (ubuntu2204) (push) Successful in 19m20s
Build Packages / build:rpm (ubuntu2404) (push) Successful in 18m43s
Build Packages / build:rpm (rocky8) (push) Successful in 19m31s
Build Packages / build:rpm (rocky9) (push) Successful in 20m16s
Build Packages / Unit tests (push) Successful in 1h41m19s
Build Packages / build:rugnux:aarch64 (cross) (push) Successful in 9m6s
* Fixed a `jfjoch_broker` crash during indexing: sorting no longer misbehaves on non-finite values, and GPU FFT indexer kernel launches are now error-checked. * rugnux needs about a third less peak memory to scale, merge and post-refine rotation data, with identical results. * `rugnux --model`: the placed coordinate file carries the space group its own coordinates obey, and says so when that is not the group the reflection files beside it carry. * `jfjoch_viewer`: fixes in the dataset plots, inspector and layout; spot markers lose their black outline by default (a checkbox under "Image features" restores it) and the highest-pixel markers are white boxes around the pixel. Reviewed-on: #80 Co-authored-by: Filip Leonarski <filip.leonarski@psi.ch> |
||
|
|
9aae0c2ba7 |
v1.0.0-rc.169 (#79)
Build Packages / Create release (push) Successful in 21s
Build Packages / build:rugnux-tgz (x86_64) (push) Successful in 9m40s
Build Packages / build:viewer-tgz:cpu (push) Successful in 11m37s
Build Packages / build:viewer-tgz:cuda (push) Successful in 12m40s
Build Packages / build:windows:nocuda (push) Successful in 17m44s
Build Packages / build:windows:cuda (push) Successful in 20m13s
Build Packages / build:rpm (rocky8_nocuda) (push) Successful in 14m41s
Build Packages / HDF5 consumer tests (DIALS, XDS) (push) Successful in 25m59s
Build Packages / build:rpm (ubuntu2204_nocuda) (push) Successful in 15m5s
Build Packages / build:rpm (ubuntu2404_nocuda) (push) Successful in 14m35s
Build Packages / build:rpm (rocky9_nocuda) (push) Successful in 15m53s
Build Packages / build:rugnux:windows (push) Successful in 11m29s
Build Packages / build:rpm (rocky8_sls9) (push) Successful in 18m51s
Build Packages / build:rpm (rocky9_sls9) (push) Successful in 18m43s
Build Packages / Generate python client (push) Successful in 51s
Build Packages / build:rpm (rocky8) (push) Successful in 18m51s
Build Packages / Build documentation (push) Successful in 1m21s
Build Packages / build:rpm (ubuntu2204) (push) Successful in 18m38s
Build Packages / build:rpm (ubuntu2404) (push) Successful in 18m24s
Build Packages / build:rpm (rocky9) (push) Successful in 19m19s
Build Packages / Unit tests (push) Successful in 1h37m15s
Build Packages / build:rugnux:aarch64 (cross) (push) Successful in 9m49s
* Building Jungfraujoch no longer needs zlib or Eigen installed on the machine, and the dependencies the build fetches are pinned and updated to current releases. * rugnux: improvements in indexing, lattice selection and geometry post-refinement, which index crystals that previously returned no lattice and keep the better of the two geometries a run measures. * rugnux: improvements in beam-centre measurement, beam-stop detection and space-group determination. * rugnux: the unit cell reported with a determined space group now obeys that group - a cell whose symmetry was confirmed from the intensities is re-refined under it, and a cell the group cannot describe is reported with a warning rather than as it stands. * rugnux drops the stretches of a rotation sweep whose removal measurably improves the merged intensities and reports what became of every frame, and decides the resolution cut on the crystal's own diffraction rather than on its ice rings. * The rugnux results report is machine-readable - every line that is not `KEY= value` data starts with `#` - and states the build it was written by, its authorship and its terms of use (`REPORT_VERSION= 8`). * `jfjoch_viewer`: improvements in the file manager (CBF frames beside HDF5 datasets, a remembered root), the dataset plots, the inspector and the image statistics, plus a settable font size, a view of the rugnux results report, usable performance over a remote display (`ssh -X`) and a reset of all settings to defaults; the reciprocal-space window is removed. * Broker fixes around DECTRIS collections and dark-mask calibration: re-initialising after a run that never started no longer freezes the broker, a cancelled calibration is abandoned instead of reported as done, and a collection whose start message never arrives ends by itself. Reviewed-on: #79 Co-authored-by: Filip Leonarski <filip.leonarski@psi.ch> |