Repository: spinnakermanchester/spinnfrontendcommon
Issue: Pair compressor test failing

https://github.com/SpiNNakerManchester/sPyNNaker8/blob/master/p8_integration_tests/quick_test/test_onchip_compressor/test_pair/test_pair_compressor.py is reliably failing, e.g.

Running routing table compression on chip
|0%                          50%                         100%|
 ===========================================================2020-06-23 11:52:40 INFO: Router compressor has failed
Extracting IOBUF from the machine
|0%                          50%                         100%|
 ============================================================
2020-06-23 11:52:41 ERROR: Error when calling spinn_front_end_common.mapping_algorithms.on_chip_router_table_compression.compression.pair_compression with inputs dict_keys(['routing_tables', 'transceiver', 'executable_finder', 'machine', 'app_id', 'provenance_file_path'])
======================================================================
ERROR: test_do_run (p8_integration_tests.quick_test.test_onchip_compressor.test_pair.test_pair_compressor.TestPairCompressor)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/andrewgait/work/spinnaker/git/sPyNNaker8/p8_integration_tests/quick_test/test_onchip_compressor/test_pair/test_pair_compressor.py", line 24, in test_do_run
    self.runsafe(do_run)
  File "/Users/andrewgait/work/spinnaker/git/sPyNNaker8/p8_integration_tests/base_test_case.py", line 184, in runsafe
    method()
  File "/Users/andrewgait/work/spinnaker/git/sPyNNaker8/p8_integration_tests/quick_test/test_onchip_compressor/many_routes.py", line 77, in do_run
    sim.run(1)
  File "/Users/andrewgait/work/spinnaker/git/sPyNNaker8/spynnaker8/__init__.py", line 737, in run
    return __pynn["run"](simtime, callbacks=callbacks)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/pyNN/common/control.py", line 111, in run
    return run_until(simulator.state.t + simtime, callbacks)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/pyNN/common/control.py", line 93, in run_until
    simulator.state.run_until(time_point)
  File "/Users/andrewgait/work/spinnaker/git/sPyNNaker8/spynnaker8/spinnaker.py", line 123, in run_until
    self._run_wait(tstop - self.t)
  File "/Users/andrewgait/work/spinnaker/git/sPyNNaker8/spynnaker8/spinnaker.py", line 153, in _run_wait
    super(SpiNNaker, self).run(duration_ms)
  File "/Users/andrewgait/work/spinnaker/git/sPyNNaker/spynnaker/pyNN/abstract_spinnaker_common.py", line 394, in run
    super(AbstractSpiNNakerCommon, self).run(run_time)
  File "/Users/andrewgait/work/spinnaker/git/SpiNNFrontEndCommon/spinn_front_end_common/interface/abstract_spinnaker_base.py", line 769, in run
    self._run(run_time)
  File "/Users/andrewgait/work/spinnaker/git/SpiNNFrontEndCommon/spinn_front_end_common/interface/abstract_spinnaker_base.py", line 976, in _run
    self._do_load(graph_changed, data_changed)
  File "/Users/andrewgait/work/spinnaker/git/SpiNNFrontEndCommon/spinn_front_end_common/interface/abstract_spinnaker_base.py", line 1861, in _do_load
    optional_algorithms)
  File "/Users/andrewgait/work/spinnaker/git/SpiNNFrontEndCommon/spinn_front_end_common/interface/abstract_spinnaker_base.py", line 1169, in _run_algorithms
    reraise(*exc_info)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/six.py", line 693, in reraise
    raise value
  File "/Users/andrewgait/work/spinnaker/git/SpiNNFrontEndCommon/spinn_front_end_common/interface/abstract_spinnaker_base.py", line 1157, in _run_algorithms
    executor.execute_mapping()
  File "/Users/andrewgait/work/spinnaker/git/PACMAN/pacman/executor/pacman_algorithm_executor.py", line 659, in execute_mapping
    self.__execute_mapping()
  File "/Users/andrewgait/work/spinnaker/git/PACMAN/pacman/executor/pacman_algorithm_executor.py", line 675, in __execute_mapping
    results = algorithm.call(self._internal_type_mapping)
  File "/Users/andrewgait/work/spinnaker/git/PACMAN/pacman/executor/algorithm_classes/abstract_python_algorithm.py", line 77, in call
    results = self.call_python(method_inputs)
  File "/Users/andrewgait/work/spinnaker/git/PACMAN/pacman/executor/algorithm_classes/python_function_algorithm.py", line 75, in call_python
    return function(**inputs)
  File "/Users/andrewgait/work/spinnaker/git/SpiNNFrontEndCommon/spinn_front_end_common/mapping_algorithms/on_chip_router_table_compression/compression.py", line 101, in pair_compression
    compression.compress()
  File "/Users/andrewgait/work/spinnaker/git/SpiNNFrontEndCommon/spinn_front_end_common/mapping_algorithms/on_chip_router_table_compression/compression.py", line 180, in compress
    self._check_for_success(executable_targets)
  File "/Users/andrewgait/work/spinnaker/git/SpiNNFrontEndCommon/spinn_front_end_common/mapping_algorithms/on_chip_router_table_compression/compression.py", line 227, in _check_for_success
    .format(x, y))
spinn_front_end_common.utilities.exceptions.SpinnFrontEndException: The router compressor on 4, 11 failed to complete

----------------------------------------------------------------------
Ran 1 test in 141.712s

FAILED (errors=1)

Changed files:
spinn_front_end_common/mapping_algorithms/on_chip_router_table_compression/compression.py

diff --git a/spinn_front_end_common/mapping_algorithms/on_chip_router_table_compression/compression.py b/spinn_front_end_common/mapping_algorithms/on_chip_router_table_compression/compression.py
index 848bb018c..430838164 100644
--- a/spinn_front_end_common/mapping_algorithms/on_chip_router_table_compression/compression.py
+++ b/spinn_front_end_common/mapping_algorithms/on_chip_router_table_compression/compression.py
@@ -60,7 +60,7 @@ def mundy_on_chip_router_compression(
         app_id, binary_path, compress_as_much_as_possible,
         compress_only_when_needed, machine, system_provenance_folder,
         routing_tables, transceiver)
-    compression.compress()
+    compression.compress(register=0)
 
 
 def pair_compression(
@@ -98,7 +98,7 @@ def pair_compression(
         app_id, binary_path, compress_as_much_as_possible,
         compress_only_when_needed, machine, provenance_file_path,
         routing_tables, transceiver)
-    compression.compress()
+    compression.compress(register=1)
 
 
 class Compression(object):
@@ -140,8 +140,9 @@ class Compression(object):
         self._transceiver = transceiver
         self._routing_tables = routing_tables
 
-    def compress(self):
+    def compress(self, register):
         """ Apply the on-machine compression algorithm.
+        :param int register: number of user register to check
         """
         # pylint: disable=too-many-arguments
 
@@ -177,7 +178,7 @@ class Compression(object):
                     executable_targets)
 
         # Check if any cores have not completed successfully
-        self._check_for_success(executable_targets)
+        self._check_for_success(executable_targets, register)
 
         # update progress bar
         progress.update()
@@ -204,20 +205,27 @@ class Compression(object):
         # write SDRAM requirements per chip
         self._transceiver.write_memory(table.x, table.y, base_address, data)
 
-    def _check_for_success(self, executable_targets):
+    def _check_for_success(self, executable_targets, register):
         """ Goes through the cores checking for cores that have failed to\\
             compress the routing tables to the level where they fit into the\\
             router
 
         :param ExecutableTargets executable_targets:
+        :param int register: number of user register to check
         """
         for core_subset in executable_targets.all_core_subsets:
             x = core_subset.x
             y = core_subset.y
             for p in core_subset.processor_ids:
-                # Read the result from USER0 register
-                result = self._transceiver.read_user_0(x, y, p)
-
+                # Read the result from specified register
+                if register == 0:
+                    result = self._transceiver.read_user_0(x, y, p)
+                elif register == 1:
+                    result = self._transceiver.read_user_1(x, y, p)
+                elif register == 2:
+                    result = self._transceiver.read_user_2(x, y, p)
+                else:
+                    raise Exception("Incorrect register")
                 # The result is 0 if success, otherwise failure
                 if result != 0:
                     self._handle_failure(executable_targets)