Debugging¶
The quadric SDK offers functions to print the contents of tensors in OCM, qVar, and static variables, as well as EPU registers, all formatted automatically.
The debugPrint
and debugOCMPrint
functions are very helpful when debugging kernels in ArchSim.
Note
Calls to debugPrint
and debugOCMPrint
are disregarded in the FPGA or on EPU hardware, and are only valid when using ArchSim.
debugPrint
¶
The debugPrint
function can print constants, qVar(s), and registers on the EPU system.
Examples¶
std::int32_t i32 = argc;
FixedPoint32<8> fx8 = 52.25;
qVar_t<std::int32_t> qI32 = qNorth<>;
qVar_t<FixedPoint32<8>> qFx8 = qWest<FixedPoint32<8>>;
// Scalars, no message
debugPrint(i32);
debugPrint(i32, DebugPrintFmt::HEX);
debugPrint(fx8);
// Scalars, with message
debugPrint(i32, "i32");
debugPrint(i32, DebugPrintFmt::HEX, "i32h");
debugPrint(fx8, "fx8");
// Special regs, no message
debugPrint(qWest<>);
debugPrint(qEast<>, DebugPrintFmt::HEX);
debugPrint(qSouth<FixedPoint32<8>>);
// Special regs, with message
debugPrint(qWest<>, "qWest<>");
debugPrint(qEast<>, DebugPrintFmt::HEX, "qEast<>h");
debugPrint(qSouth<FixedPoint32<8>>, "qSouth<FX8>");
// qVar, no message
debugPrint(qI32);
debugPrint(qI32, DebugPrintFmt::HEX);
debugPrint(qFx8);
// qVar, with message
debugPrint(qI32, "qI32");
debugPrint(qI32, DebugPrintFmt::HEX, "qI32h");
debugPrint(qFx8, "qFx8");
We can also use debugPrint
to examine the configuration of our EPU. For example:
debugPrint(qCol<>); //Output is shown below
[-4] [-3] [-2] [-1] | [0] [1] [2] [3] [4] [5] [6] [7] | [8] [9] [10] [11]
[-4] [-3] [-2] [-1] | [0] [1] [2] [3] [4] [5] [6] [7] | [8] [9] [10] [11]
[-4] [-3] [-2] [-1] | [0] [1] [2] [3] [4] [5] [6] [7] | [8] [9] [10] [11]
[-4] [-3] [-2] [-1] | [0] [1] [2] [3] [4] [5] [6] [7] | [8] [9] [10] [11]
------------------------------------------------------------------------------------------------
[-4] [-3] [-2] [-1] | [0] [1] [2] [3] [4] [5] [6] [7] | [8] [9] [10] [11]
[-4] [-3] [-2] [-1] | [0] [1] [2] [3] [4] [5] [6] [7] | [8] [9] [10] [11]
[-4] [-3] [-2] [-1] | [0] [1] [2] [3] [4] [5] [6] [7] | [8] [9] [10] [11]
[-4] [-3] [-2] [-1] | [0] [1] [2] [3] [4] [5] [6] [7] | [8] [9] [10] [11]
[-4] [-3] [-2] [-1] | [0] [1] [2] [3] [4] [5] [6] [7] | [8] [9] [10] [11]
[-4] [-3] [-2] [-1] | [0] [1] [2] [3] [4] [5] [6] [7] | [8] [9] [10] [11]
[-4] [-3] [-2] [-1] | [0] [1] [2] [3] [4] [5] [6] [7] | [8] [9] [10] [11]
[-4] [-3] [-2] [-1] | [0] [1] [2] [3] [4] [5] [6] [7] | [8] [9] [10] [11]
------------------------------------------------------------------------------------------------
[-4] [-3] [-2] [-1] | [0] [1] [2] [3] [4] [5] [6] [7] | [8] [9] [10] [11]
[-4] [-3] [-2] [-1] | [0] [1] [2] [3] [4] [5] [6] [7] | [8] [9] [10] [11]
[-4] [-3] [-2] [-1] | [0] [1] [2] [3] [4] [5] [6] [7] | [8] [9] [10] [11]
[-4] [-3] [-2] [-1] | [0] [1] [2] [3] [4] [5] [6] [7] | [8] [9] [10] [11]
debugPrint(qRow<>); //Output is shown below
[-4] [-4] [-4] [-4] | [-4] [-4] [-4] [-4] [-4] [-4] [-4] [-4] | [-4] [-4] [-4] [-4]
[-3] [-3] [-3] [-3] | [-3] [-3] [-3] [-3] [-3] [-3] [-3] [-3] | [-3] [-3] [-3] [-3]
[-2] [-2] [-2] [-2] | [-2] [-2] [-2] [-2] [-2] [-2] [-2] [-2] | [-2] [-2] [-2] [-2]
[-1] [-1] [-1] [-1] | [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] | [-1] [-1] [-1] [-1]
------------------------------------------------------------------------------------------------
[ 0] [ 0] [ 0] [ 0] | [ 0] [ 0] [ 0] [ 0] [ 0] [ 0] [ 0] [ 0] | [ 0] [ 0] [ 0] [ 0]
[ 1] [ 1] [ 1] [ 1] | [ 1] [ 1] [ 1] [ 1] [ 1] [ 1] [ 1] [ 1] | [ 1] [ 1] [ 1] [ 1]
[ 2] [ 2] [ 2] [ 2] | [ 2] [ 2] [ 2] [ 2] [ 2] [ 2] [ 2] [ 2] | [ 2] [ 2] [ 2] [ 2]
[ 3] [ 3] [ 3] [ 3] | [ 3] [ 3] [ 3] [ 3] [ 3] [ 3] [ 3] [ 3] | [ 3] [ 3] [ 3] [ 3]
[ 4] [ 4] [ 4] [ 4] | [ 4] [ 4] [ 4] [ 4] [ 4] [ 4] [ 4] [ 4] | [ 4] [ 4] [ 4] [ 4]
[ 5] [ 5] [ 5] [ 5] | [ 5] [ 5] [ 5] [ 5] [ 5] [ 5] [ 5] [ 5] | [ 5] [ 5] [ 5] [ 5]
[ 6] [ 6] [ 6] [ 6] | [ 6] [ 6] [ 6] [ 6] [ 6] [ 6] [ 6] [ 6] | [ 6] [ 6] [ 6] [ 6]
[ 7] [ 7] [ 7] [ 7] | [ 7] [ 7] [ 7] [ 7] [ 7] [ 7] [ 7] [ 7] | [ 7] [ 7] [ 7] [ 7]
------------------------------------------------------------------------------------------------
[ 8] [ 8] [ 8] [ 8] | [ 8] [ 8] [ 8] [ 8] [ 8] [ 8] [ 8] [ 8] | [ 8] [ 8] [ 8] [ 8]
[ 9] [ 9] [ 9] [ 9] | [ 9] [ 9] [ 9] [ 9] [ 9] [ 9] [ 9] [ 9] | [ 9] [ 9] [ 9] [ 9]
[10] [10] [10] [10] | [10] [10] [10] [10] [10] [10] [10] [10] | [10] [10] [10] [10]
[11] [11] [11] [11] | [11] [11] [11] [11] [11] [11] [11] [11] | [11] [11] [11] [11]
Above, the debugPrint
statements display the column and row of each core in the EPU. Notably, the border cores have values below 0 or greater than 7, which makes sense as the examples above were generated by a q8, which has 8 cores per side.
debugOCMPrint
¶
The debugOCMPrint
function gives the user the ability to print out the data stored in the On Chip Memory (OCM). Usage of debugOCMPrint
function mirrors the usage of the debugPrint
function, although it’s used only for OcmTensor
type objects.
OcmInOutShape ocmInp; // Already allocated and populated previously...
debugOCMPrint(ocmInp)
Output of a call to debugOCMPrint
will look look like this:
ocm[0x00000000]= 0x00000000 0x00000001 0x00000002 0x00000003 0x00000004 0x00000005 0x00000006 0x00000007
ocm[0x00000001]= 0x00000008 0x00000009 0x0000000a 0x0000000b 0x0000000c 0x0000000d 0x0000000e 0x0000000f
ocm[0x00000002]= 0x00000010 0x00000011 0x00000012 0x00000013 0x00000014 0x00000015 0x00000016 0x00000017
ocm[0x00000003]= 0x00000018 0x00000019 0x0000001a 0x0000001b 0x0000001c 0x0000001d 0x0000001e 0x0000001f
ocm[0x00000004]= 0x00000020 0x00000021 0x00000022 0x00000023 0x00000024 0x00000025 0x00000026 0x00000027
ocm[0x00000005]= 0x00000028 0x00000029 0x0000002a 0x0000002b 0x0000002c 0x0000002d 0x0000002e 0x0000002f
ocm[0x00000006]= 0x00000030 0x00000031 0x00000032 0x00000033 0x00000034 0x00000035 0x00000036 0x00000037
ocm[0x00000007]= 0x00000038 0x00000039 0x0000003a 0x0000003b 0x0000003c 0x0000003d 0x0000003e 0x0000003f
ocm[0x00000008]= 0x00000800 0x00000801 0x00000802 0x00000803 0x00000804 0x00000805 0x00000806 0x00000807
Each of the above lines represents a line of OCM memory (on a q8, which the example above represents, 1 OCM line is 32 bytes). The data is represented with the least significant byte at the lowest address (little endian).