Build: #3 was successful Changes by Josh Marvil

Stages & jobs

  1. Default Stage

  2. Test

Build result summary

Details

Completed
Queue duration
< 1 second
Duration
44 minutes
Labels
None
Revision
6cf1ede958f01d0f3ed691911c29f0f5c2778eb7
Total tests
697
First to pass since
#2 (Changes by Josh Marvil – )

Tests

Code commits

Author Commit Message Commit date
Josh Marvil Josh Marvil 6cf1ede958f01d0f3ed691911c29f0f5c2778eb7 CAS-14874: derive briggsbwtaper fracBW from output cube
Josh Marvil Josh Marvil d27fff1705e9d9b7af956665dcd0a23eb5d5e692 CAS-14874: Make the Briggs cube weight density partition-invariant
The per-channel imaging-weight density that briggsbwtaper/perchanweightdensity
relies on is local to a channel: f2/d2[chan] are derived from that channel's
gridded-weight plane only.  The quality of that plane nevertheless depended on
*how many* channels this process happens to own, which made the weights - and
therefore the PSF and flux scale - vary with the number of MPI processes:

- estimateSwingChanPad() scaled its extra margin by the sub-cube channel count
  (extrapad = max(min(4, imNChan/10), 1)), so different sub-cubes got different
  guard margins.
- estimateSwingChanPad() returned 0 for a homogeneous frame, i.e. no guard
  margin at all, even though the FT machine still interpolates visibility
  frequencies across neighbouring channel planes (edge truncation).
- init() padded its density template by a fixed +4/+2 channels while
  fillImgWeightCol() used the data-derived swingpad, so the two passes could
  disagree on the geometry.
- the default pad for the multi-field/multi-MS path was a bare 4.
- the scratch weight table key was (nrows, freqbeg, freqend, rmode, robust,
  interp).  All ranks chdir to the same working directory, so ranks that
  produced the same key shared one IMAGING_WEIGHT_* table and raced on it
  (reuse-if-nonzero-row-count, else delete-and-recreate) while it was being
  filled and consumed through readWeightColumn().  The reuse checks in
  initImgWeightCol()/init() keyed on (nx, ny, first-channel frequency) only and
  could hand back a density built for a different sub-cube.
- initializeFTMachine() rebuilt grids_p[index] from the new template on every
  call but sized f2_p/d2_p only on the first one, so a template that grew
  between calls left f2_p/d2_p shorter than the grid and made
  f2_p[index][pos(3)] read past the end of the vector.

Fix, in this file only:

- introduce minWgtDensityEdgePad = 4 (channels per edge) and use it everywhere
  the guard margin was previously derived from the local channel count;
- return that floor instead of 0 when no frame swing is present;
- align init()'s template padding and the multi-field default with it;
- fold a spectral geometry token (nchan, channel reference pixel, first
  channel frequency) into the scratch table name, and require it in the
  initImgWeightCol() early return;
- pin the init() reuse on the cached density extent (f2_p) matching the
  requested template channel count;
- grow f2_p/d2_p (and zero them) in initializeFTMachine() when the template
  channel count exceeds the cached allocation, and bounds-check the channel
  index in both weightUniform() and getWeightUniform() so a stale allocation
  yields a zero weight instead of an out-of-bounds read.

Because the density itself is per-channel-local, making the geometry
rule partition-independent is enough to make parallel results agree with serial
for a single input MS, and it removes the shared-table race entirely.  No
interface, XML or Python change.

Known remaining partition dependence (follow-up, needs the full-cube channel
count to be plumbed into this file):

- the inOneGo threshold in initImgWeightCol() still compares the swing pad
  against templateimage.shape()[3]/10, so multi-MS inputs can still choose a
  different processing path on a small sub-cube than serial does;
- estimateSwingChanPad() still derives freqbeg/freqend (and so the swing
  estimate itself) from the local template rather than the full selection, so
  the swing term remains weakly dependent on the sub-cube range;
- the scratch table stays in the shared working directory (a per-rank workdir
  is not knowable here), so cross-run reuse of a same-tag, same-row-count table
  remains possible, as before.

Validation: two standalone harnesses compile the changed logic against stubbed
casacore types - the first asserts geometry-key/cache-key behaviour (reuse only
for identical token/extent/nx/ny/freq) and the pad floor values, the second a
faithful Block<Vector<Float>> model asserts the grow-then-zero path and that a
stale shorter f2_p is rejected rather than read out of bounds.  Brace/paren
balance preserved (110->112 braces, 794->849 parens, both sides equal).  A full
casatools build plus serial-vs-parallel tests are still required before merge.

Jira issues

IssueDescriptionStatus
Unknown Issue TypeCAS-14874Could not obtain issue details from Jira

Shared artifacts

Artifact File size
ManyLinux228 Casatestutils 157 KB
ManyLinux228 Python 3.12 Tool wheel 75 MB