src.tests.dl_sparse_concat_sequencer_test

Classes

DLSparseConcatSequencerTest()

class src.tests.dl_sparse_concat_sequencer_test.DLSparseConcatSequencerTest
Author:

Alberto M. Esmoris Pena

Regression test for DLSparseConcatSequencer, covering both the per-RF concatenation contract and the static-shape padding that eliminates tf.function retracing.

Verifies the sequencer’s correctness properties on synthetic data:

  1. Concatenation shapes: every emitted tensor has the expected padded (1 + pad_R_per_t[t], ...) row count for every depth \(t \in [0, t^*)\). The same constant shape is observed for every batch.

  2. Ground row invariant: row 0 of \(\pmb{F}\) and of every \(\pmb{S}_t\), \(\pmb{D}_t\), \(\pmb{U}_t\) is entirely zero (no per-RF ground rows leak into the global tensor, and the padded tail is zeroed too).

  3. Per-RF offset correctness: the j-th receptive field in a batch has its active cells at rows \([1 + \mathrm{off}_{jt}, R_{jt} + \mathrm{off}_{jt}]\) of the depth-t output, where \(\mathrm{off}_{jt} = \sum_{l < j} R_{lt}\). The neighbor table values referencing those cells are correctly offset.

  4. Label flat concatenation with sample-weight mask: \(y\) has the padded length pad_R_per_t[0] and the sample_weight mask is 1.0 over the real cells and 0.0 over the padded tail. The first actual_R_0 entries of \(y\) match the unpadded concatenation of per-RF labels.

  5. Random shuffle preserves the invariants: after random_shuffle_indices=True shuffles the RF order, the sequencer still produces a consistent global tensor.

  6. post_process_output round-trip: feeding an (n_batches * pad_R_per_t[0], num_classes) tensor through post_process_output strips the padded tail and returns a list of per-RF arrays whose lengths match each RF’s level-0 active-cell count.

  7. Input-shape validation: feeding the legacy 6-element pyout (without the dense neighbor tables) raises DeepLearningException rather than silently mis-indexing.

  8. Pad budget: pad_R_per_t[t] equals the sum of the top batch_size values of R_per_rf_t[:, t] and is therefore sufficient to hold any batch the sequencer can emit.

  9. Ignore-labels masking: when ignore_labels is supplied, real cells whose label is in the list get sample_weight=0 in the emitted training tuple while all other padded-tail and ground-row invariants still hold.

__init__()

Basic configuration for any VL3D test.

Parameters:

name (str) – Test name

run()

Run every subtest; return True only if all pass.

subtest_concatenation_shapes()

Every emitted tensor has the padded (1 + pad_R_per_t[t], ...) row count and that count is the same across batches.

subtest_ground_row_invariant()

Row 0 of F and every S/D/U is entirely zero. Padded-tail rows are zero too, so a downstream tf.gather fetches the ground row. The per-depth masks (last max_depth entries of batch_X) are 1-D bool tensors with no ground row; they are checked separately.

subtest_offset_correctness()

Verify that the j-th RF’s active cells land at the expected rows of the depth-t output, and the column values referencing those cells are correctly offset.

subtest_labels_flat_concat()

Padded labels match flat concatenation up to actual_R_0; sample_weight is 1 over real cells and 0 over padding.

subtest_random_shuffle_preserves_invariants()

With random_shuffle_indices=True the sequencer still produces valid global tensors (just in a different RF order).

subtest_post_process_output_roundtrip()

post_process_output strips the padded tail of every batch in a stacked (n_batches * pad_R_0, num_classes) tensor and splits the result by the per-RF cumulative offsets.

subtest_pad_budget()

pad_R_per_t[t] is the sum of the top batch_size values of R_per_rf_t[:, t], which strictly bounds any batch sum.

subtest_input_shape_validation()

Feeding the legacy 6-element pyout (no neighbor tables) raises rather than silently mis-indexing.

subtest_ignore_labels()

ignore_labels zeroes sample_weight over real cells with a matching label without changing the padded layout.

subtest_batch_size_property_refreshes_pad()

Mutating sq.batch_size post-init must re-run prepare_data() so pad_R_per_t matches the new top-batch_size sum of R_per_rf_t. Without the property setter the stale pad budget would underrun at predict time when a larger batch is used.

subtest_ignore_labels_dtype_validation()

ignore_labels values that cannot be exactly represented in y.dtype must raise a DeepLearningException instead of silently wrapping on cast (e.g., 255 in an int8 array wraps to -1, masking the wrong cells).

subtest_batch_size_setter_resets_shuffle()

Mutating batch_size post-init must clear Irandom and shuffled. Documented use case: switching from a training batch size to a (larger) predict batch size. If the setter left stale shuffle state, a subsequent toggle back to training mode would apply the old indices against the new pad budget.

subtest_ignore_labels_dtype_validation_heterogeneous()

A y list with heterogeneous per-RF dtypes must be validated against the NARROWEST dtype. Mixing int32 with int8 and passing ignore_labels=[255] must raise, since the int8 RFs cannot represent 255.