Files
Jungfraujoch/image_analysis/structure_refinement/ModelGrid.h
T
leonarski_fandClaude Opus 5.5 43e836573d MR and model validation on the CPU: workers bounded by their bytes, not the thread count
- The CPU translation function runs as many rotations at once as the host worker pool holds (8 B per
  grid point each, 550 MiB on a 400 A cell; 33 at once at 32 threads was 18 GiB), at most nthreads.
  Counted, not reserved: the rotations run on ParallelFor's pool, whose workers must not wait on memory.
- Null replicates (model validation's and MR's) whose structure factors are made on the CPU reserve
  32 B per point of their grid (ModelGridPoints) against the pool before they start, so the nine
  replicates, and nulls run side by side, hold at most the pool between them.
Every replicate and rotation computes what it did and is stored by index: no result depends on how
many run at once.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PXc1zD1yxHqaR1DGdCTHL4
2026-10-17 09:31:05 +02:00

39 lines
2.2 KiB
C++

// SPDX-FileCopyrightText: 2026 Filip Leonarski, Paul Scherrer Institute <filip.leonarski@psi.ch>
// SPDX-License-Identifier: GPL-3.0-only
#pragma once
#include <cstddef>
#include <vector>
#include "gemmi/dencalc.hpp" // DensityCalculator
#include "gemmi/grid.hpp"
#include "gemmi/it92.hpp" // IT92 x-ray form factors
#include "gemmi/model.hpp"
// gemmi's gridding of a model - the density of DensityCalculator::put_model_density_on_grid() and the
// bulk-solvent mask of SolventMasker(AtomicRadiiSet::Refmac).put_mask_on_grid() - spread over
// `nthreads` threads of ParallelFor's pool. Every grid point receives the same operations in the same
// order as in gemmi's serial loops, so the grids are gemmi's, bit for bit, on any number of threads.
// The points gemmi's Grid::symmetrize() reduces the orbits of this grid's size and space group into
// (empty in P1). Both functions below take them, for a grid of the same size.
std::vector<size_t> OrbitLeaders(const gemmi::Grid<float> &grid, size_t nthreads);
// `dc` set up as for put_model_density_on_grid(): d_min, rate, blur, the grid's cell and group.
void PutModelDensityOnGrid(gemmi::DensityCalculator<gemmi::IT92<float>, float> &dc, const gemmi::Model &model,
const std::vector<size_t> &orbit_leaders, size_t nthreads);
// `grid` sized, with its cell and group set.
void PutMaskOnGrid(gemmi::Grid<float> &grid, const gemmi::Model &model, const std::vector<size_t> &orbit_leaders,
size_t nthreads);
// The number of points of the grid a model's structure factors to d_min are computed on at DensityCalculator's
// `rate` (a spacing of d_min / (2 rate)) in this cell and space group: the grid's size, without making it.
size_t ModelGridPoints(const gemmi::UnitCell &cell, const gemmi::SpaceGroup *sg, double d_min, double rate = 1.5);
// What computing a model's structure factors on the CPU holds at its peak, per point of that grid: the density
// and the bulk-solvent mask grids, and for each of them its transform's input copy, spectrum and coefficients,
// with the two made at once (ModelValidation's compute_model_factors).
constexpr size_t MODEL_FACTORS_BYTES_PER_GRID_POINT = 32;