Sigmasq and autocorrelation arrays are incorrectly loaded when non-sequential IFOs are chosen.
Throughout the spiir pipeline, we either loop over the IFOs by the number of IFOs that the pipeline is currently ingesting (i.e the IFOs input as arguments, nifo), or by the maximum number of IFOs that the pipeline is able to injest, (MAX_NIFO).
During the start of a run, the arrays for sigmasq and autocorr are loaded in from the bank files.
The loop that determines which input IFO to associate with each bank file only loops over nifo when trying to string match to the input IFOs. This will break when the n'th IFO ingested by the pipeline does not match the n'th IFO of MAX_NIFO.
This bug had not previously occurred because all runs during tests and production ran the IFO combinations of HL, HLV, and HLVK, where the n'th of nifo does match the n'th of MAX_NIFO. If any non-sequential combination such as HV, LVK, or HVK is run, these indexes do not match and the array loading is mismanaged.
For instance, in the case of HV, the matched ifo index for H is correctly identified as 0 and so the array for H is correctly loaded into the sigmasq array, but when matching for V, nifo is looped over (0 then 1) but V is not found because only 2 will match. This leaves the match_ifo variable as the last set value of 0 and the V data then overwrites the H data, leaving sigmasq[1] pointing to random memory.
Pseudocode for helper function get_ifo_string:
get_ifo_string(int: IFO_ID):
if IFO_ID == 0:
return 'H1'
if IFO_ID == 1:
return 'L1'
if IFO_ID == 2:
return 'V1'
if IFO_ID == 3:
return 'K1'
Input variables for a HV run:
/* MAX_NIFO is 4 at the moment for Hanford, Livingston, Virgo, and Kagra */
MAX_NIFO = 4
/* Bank files are supplied as an input argument to the pipeline and formatted similarly to this further upstream */
bank_files = {
'H1': 'bank_H1.xml',
'V1': 'bank_V1.xml'
}
/* nifo = 2 */
nifo = len(bank_files)
/* allocate the sigmasq array as a pointer for each enabled ifo */
sigmasq = malloc(sizeof(double *) * nifo)
Pseudocode for the bug:
int match_ifo = 0
/* parsing for all_ifos */
for (IFO_STR, filename of bank_files) {
/* Try (and sometimes fail) to find IFO that matches array */
for (int i = 0; i < nifo; i++) {
print("Outer, IFO_STR: ", IFO_STR, ", Inner, i: ", i, ", match_ifo: ", match_ifo);
if (match(get_ifo_string(i), IFO_STR) {
match_ifo = i;
print("Matched ", IFO_STR, " as IFO ", i);
break;
}
}
print("Loading ", filename, " into sigmasq[", match_ifo, "]");
sigmasq[match_ifo] = parseFile(filename);
}
will output:
Outer, IFO_STR: H1, Inner, i: 0, match_ifo: 0
Matched H1 as IFO 0
Loading H1_bank.xml into sigmasq[0]
Outer, IFO_STR: V1, Inner, i: 0, match_ifo: 0
Outer, IFO_STR: V1, Inner, i: 1, match_ifo: 0
Loading V1_bank.xml into sigmasq[0]
Pseudocode for fix:
int num_parsed_ifos = 0;
for (int i = 0; i < MAX_NIFO; i++) {
// Find array that matches IFO i, if any
matched_filename = NULL;
for (IFO_STR, filename of bank_files) {
print("Outer, i: ", i, ", Inner, IFO_STR: ", IFO_STR, ", num_parsed_ifos: ", num_parsed_ifos);
if (match(get_ifo_string(i), IFO_STR) {
matched_filename = filename;
print("Matched ", IFO_STR, " as IFO ", i);
break;
}
}
if (!matched_filename) continue;
int match_ifo = num_parsed_ifos++;
print("Loading ", matched_filename, " into sigmasq[", match_ifo, "]");
sigmasq[match_ifo] = parseFile(matched_filename);
}
will output:
Outer, i: 0, Inner, IFO_STR: H1, num_parsed_ifos: 0
Matched H1 as IFO 0
Loading H1_bank.xml into sigmasq[0]
Outer, i: 1, Inner, IFO_STR: H1, num_parsed_ifos: 1
Outer, i: 1, Inner, IFO_STR: V1, num_parsed_ifos: 1
Matched V1 as IFO 1
Loading V1_bank.xml into sigmasq[1]
Outer, i: 2, Inner, IFO_STR: H1, num_parsed_ifos: 2
Outer, i: 2, Inner, IFO_STR: V1, num_parsed_ifos: 2
Outer, i: 3, Inner, IFO_STR: H1, num_parsed_ifos: 2
Outer, i: 3, Inner, IFO_STR: V1, num_parsed_ifos: 2
This faulty logic is present in both cuda_postcoh_autocorr_from_xml and cuda_postcoh_sigmasq_from_xml.
The merge request for this issue is !60 (merged)