Refinement GPU: the bulk-solvent mask on its own fine grid on the card
The score draws the mask on a grid of its own (min(d_min/3, 0.4 A), BulkSolventMask) on the host; on a GPU engine that was a CPU mask and transform every cycle, per trial slot on one thread. Now the engine masks on that grid itself: - RefinementGPUSetup::mask_grid (BulkSolventMask::MaskGrid, the grid the host mask uses); where it is not the structure factors' grid the engine reserves a grid, a spectrum and an R2C plan for it (counted in DeviceBytes and the FFT work area), and Fmask masks (ModelMaskGPU), transforms and reads the rows there. Refit takes the engine's Fmask on a GPU, BulkSolventMask on the CPU. - ModelMaskGPU's shrink: each edge point marks its stencil as solvent instead of every macromolecule point searching its stencil for an edge - the same idempotent stores to the same points, so the same mask to the bit (ModelMaskGPU_* tests unchanged), and a thin shell of points visited instead of half the grid. - BulkSolventMask finds its symmetry orbits at its first mask: a GPU refinement never draws one on the host (1.1 s of trial-slot setup on the 3.6 A set). The card's mask is gemmi's but at points exactly on an atom's radius (ModelMaskGPU.h): R-work/R-free of the 14 parity sets on the GPU are the CPU engine's to 4 digits. Refinement deterministic run to run on the GPU (7 timing sets, refined model and report identical over 5 runs of successive builds that did not change results). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015CeEGgpKdfkCTJb3YNMJcu (cherry picked from commit 89b5d00907c9ad99e8b389f6272a3724f981cd10)
This commit is contained in:
1 parent
46ad2c10ed
commit
8718065a7c
7 files changed
+83
-35
No files matched your search
@@ -61,6 +61,12 @@ public:
|
||||
setup_.grid.frac[3 * i + j] = cell.frac.mat[i][j];
|
||||
}
|
||||
setup_.volume = cell.volume;
|
||||
// the mask on a grid of its own, as BulkSolventMask has it
|
||||
const gemmi::Grid<float> mask_grid = BulkSolventMask::MaskGrid(cell, sg, d_min);
|
||||
setup_.mask_grid = setup_.grid;
|
||||
setup_.mask_grid.nu = mask_grid.nu;
|
||||
setup_.mask_grid.nv = mask_grid.nv;
|
||||
setup_.mask_grid.nw = mask_grid.nw;
|
||||
const gemmi::GroupOps gops = sg.operations();
|
||||
setup_.den = gemmi::Op::DEN;
|
||||
setup_.centring = static_cast<double>(gops.cen_ops.size());
|
||||
@@ -135,7 +141,7 @@ public:
|
||||
supported_ = !setup_.rows.empty() && ModelDensityGPU::Supports(setup_.grid, widest) &&
|
||||
setup_.mask_ops.size() <= ModelMaskGPU::MAX_OPS;
|
||||
if (supported_) {
|
||||
fft_work_ = RefinementGPUEngine::FFTWorkBytes(device, setup_.grid);
|
||||
fft_work_ = RefinementGPUEngine::FFTWorkBytes(device, setup_);
|
||||
// the restraints: about thirty records and slots per atom
|
||||
bytes_ = RefinementGPUEngine::DeviceBytes(setup_, fft_work_, 30 * widest.size(), 60 * widest.size());
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user