Hi everyone,
I was recently trying to compiler few benchmarks from the
https://github.com/cornell-brg/xloops-bmarks using RISCV gcc compiler and
was trying to run them on gem5. There were few benchmarks in which gem5 was
showing unusual behaviour, reporting a page fault when there should be
none. I ran the riscv binary on spike and it worked fine. Then I tried
compiling the benchmark natively on x86 machine and ran it using valgrind
and didn’t find any issue. I was wondering is this a bug in the RISCV port
in gem5? I am compiling the following benchmark.
//========================================================================//
viterbi//========================================================================//
This application performs viterbi decoding on a frame of encoded data.
#include <cstring>#include <iostream>#include <iomanip>#include <vector>
//========================================================================//
viterbi
dataset//========================================================================//
constraint length (number of memory registers)const int K = 7;//
number of symbol bits per input bitconst int rate = 2;// Dataset
parameters// size of data packetconst int framebits = 2048;//
generator polynomialsint polys[rate] = {121, 91};// size of bitpacked
data arraysconst int data_sz = framebits/8;unsigned char
data[((framebits + (K-1)) / 8) + 1];unsigned char
syms[rate*(framebits+(K-1))];unsigned char ref[(framebits+(K-1))/8+1];
namespace viterbi {namespace details {// constraint length (number of
memory registers)// implementation requires K <= 8const int K = 7;//
number of symbol bits per input bitconst int rate = 2;// number of
possible decoder statesconst int STATES (1 << (K-1));
}}
namespace viterbi {
using namespace details;
// Quickly generate a parity bit
// see http://graphics.stanford.edu/~seander/bithacks.html#ParityParallel
//__attribute__ ((always_inline))
int generate_symbol_bit_scalar(int x) {
x ^= (x >> 16);
x ^= (x >> 8);
x ^= (x >> 4);
x &= 0xf;
return (0x6996 >> x) & 1;
}
// Viterbi Decoder: take encoded symbols and return the decoded msg
void viterbi_scalar(unsigned char symbols[], unsigned char msg[],
int poly[], int framebits) {
// Branch Table stores the state transitions, we only need to build
// half thanks to trellace symmetry
unsigned int branch_table[STATES/2 * rate];
unsigned int* branch_table_ptr = &branch_table[0];
//--------------------------------------------------------------------
// Build Branch Lookup Table
//--------------------------------------------------------------------
for (int state = 0; state < STATES/2; state++) {
for (int i = 0; i < rate; i ++) {
int bit = generate_symbol_bit_scalar(2*state & poly[i]);
branch_table[i*STATES/2 + state] = bit ? 255 : 0;
}
}
// Two buffers to store the accumulated error for each state/path
unsigned int error1[STATES];
unsigned int error2[STATES];
// Pointers to track which accumulated error buffer is most current,
// pointer targets are swapped after each frame bit
unsigned int * old_error = error1;
unsigned int * new_error = error2;
// Record the minimum error path entering each state for all framebits
int traces[framebits+(K-1)][STATES];
// Bias the accumulated error buffer towards the known start state
error1[0] = 0;
for(int i=1;i<STATES;i++)
error1[i] = 63;
//--------------------------------------------------------------------
// Calculate Forward Paths
//--------------------------------------------------------------------
// For each frame bit, accumulate errors and determine path entering
// states i & i+(STATES/2) (evaluate simultaneously using symmetry)
for (int s = 0; s < framebits + (K-1); s++) {
for (int i = 0; i < STATES/2; i++) {
int decision0, decision1;
unsigned int metric, m0, m1, m2, m3;
metric = 0;
// Compute the error metric for this state
for (int j = 0; j < rate; j++)
metric += branch_table_ptr[i+j*STATES/2] ^ symbols[s*rate+j];
const unsigned int max = rate*(256 - 1);
m0 = old_error[i] + metric;
m1 = old_error[i+STATES/2] + (max - metric);
m2 = old_error[i] + (max - metric);
m3 = old_error[i+STATES/2] + metric;
// Determine which transition is minimum
decision0 = m0 > m1;
decision1 = m2 > m3;
// Save error for minimum transition
new_error[2*i] = decision0 ? m1 : m0;
new_error[2*i+1] = decision1 ? m3 : m2;
// Save transmission bit for minimum transition
traces[s][2*i] = decision0;
traces[s][2*i+1] = decision1;
}
// Swap targets of old and new error buffers
unsigned int * temp = old_error;
old_error = new_error;
new_error = temp;
}
//--------------------------------------------------------------------
// Path Traceback
//--------------------------------------------------------------------
// Traceback through the path with the lowest error and generate
// the decoded message based on the observed state transitions
// Assume final state is 0
unsigned int endstate = 0;
unsigned int nbits = framebits;
// Offset to only access the last framebits bits (ignore flush bits)
int (* trace_ptr)[STATES] = traces+(K-1);
// Traceback loop, densely pack the message bits
while (nbits-- !=0) {
int k = trace_ptr[nbits][endstate];
endstate = (endstate >> 1) | (k << (K-2));
msg[nbits>>3] >>= 1;
msg[nbits>>3] |= (k << 7);
}
}
}
int main( int argc, char* argv[] )
{
for ( int i = 0; i < ((framebits + (K-1)) / 8) + 1; i++ )
data[i] = i;
for ( int i = 0; i < rate*(framebits+(K-1)); i++ )
syms[i] = i;
for ( int i = 0; i < (framebits+(K-1))/8+1; i++ )
ref[i] = i;
unsigned char msg[(framebits + (K-1))/8 + 1] = {0};
viterbi::viterbi_scalar(syms, msg, polys, framebits);
return 0;
}
And running it using
% riscv64-unknown-elf-g++ viterbi.cc -o viterbi
% ./build/RISCV/gem5.debug --verbose ./configs/example/se.py -c ./viterbi
This gives me the following error and stack trace
0: system.remote_gdb.listener: listening for remote gdb #0 on port 7000
info: Entering event queue @ 0. Starting simulation...
**** REAL SIMULATION ****
panic: Page table fault when accessing virtual address 0x7ffffffffff7f400
Memory Usage: 793264 KBytes
Program aborted at tick 28870000
--- BEGIN LIBC BACKTRACE ---
./build/RISCV/gem5.debug(_Z15print_backtracev+0x1f)[0x14e4046]
./build/RISCV/gem5.debug(_Z12abortHandleri+0x5c)[0x14ef70b]
/lib64/libpthread.so.0(+0xf370)[0x7f69aacc7370]
/lib64/libc.so.6(gsignal+0x37)[0x7f69a98e61d7]
/lib64/libc.so.6(abort+0x148)[0x7f69a98e78c8]
./build/RISCV/gem5.debug(_ZN21GenericPageTableFault6invokeEP13ThreadContextRK14RefCountingPtrI10StaticInstE+0xa0)[0x15099c6]
./build/RISCV/gem5.debug(_ZN13BaseSimpleCPU9advancePCERKSt10shared_ptrI9FaultBaseE+0x139)[0x1306fab]
./build/RISCV/gem5.debug(_ZN15AtomicSimpleCPU4tickEv+0x925)[0x12f6b07]
./build/RISCV/gem5.debug[0x12f3d8d]
./build/RISCV/gem5.debug[0x12f6eb9]
./build/RISCV/gem5.debug(_ZNKSt8functionIFvvEEclEv+0x32)[0x12e80a0]
./build/RISCV/gem5.debug(_ZN20EventFunctionWrapper7processEv+0x1c)[0x12e705e]
./build/RISCV/gem5.debug(_ZN10EventQueue10serviceOneEv+0xda)[0x14ecfb2]
./build/RISCV/gem5.debug(_Z9doSimLoopP10EventQueue+0x1ef)[0x14f4e96]
./build/RISCV/gem5.debug(_Z8simulatem+0x2dc)[0x14f4b11]
./build/RISCV/gem5.debug(_ZN8pybind116detail15argument_loaderIJmEE9call_implIP22GlobalSimLoopExitEventRPFS5_mEJLm0EEEET_OT0_NS0_14index_sequenceIJXspT1_EEEE+0x3c)[0x1736d7c]
./build/RISCV/gem5.debug(_ZN8pybind116detail15argument_loaderIJmEE4callIP22GlobalSimLoopExitEventRPFS5_mEEENSt9enable_ifIXntsrSt7is_voidIT_E5valueESB_E4typeEOT0_+0x34)[0x1734c96]
./build/RISCV/gem5.debug(_ZZN8pybind1112cpp_function10initializeIRPFP22GlobalSimLoopExitEventmES3_JmEJNS_4nameENS_5scopeENS_7siblingENS_5arg_vEEEEvOT_PFT0_DpT1_EDpRKT2_ENKUlRNS_6detail13function_callEE1_clESO_+0x94)[0x1730c08]
./build/RISCV/gem5.debug(_ZZN8pybind1112cpp_function10initializeIRPFP22GlobalSimLoopExitEventmES3_JmEJNS_4nameENS_5scopeENS_7siblingENS_5arg_vEEEEvOT_PFT0_DpT1_EDpRKT2_ENUlRNS_6detail13function_callEE1_4_FUNESO_+0x1d)[0x1730c5b]
./build/RISCV/gem5.debug(_ZN8pybind1112cpp_function10dispatcherEP7_objectS2_S2_+0x9a3)[0x16d7466]
./build/RISCV/gem5.debug(PyEval_EvalFrameEx+0x7d42)[0x205dd52]
./build/RISCV/gem5.debug(PyEval_EvalCodeEx+0x89c)[0x205f5ec]
./build/RISCV/gem5.debug(PyEval_EvalFrameEx+0x7131)[0x205d141]
./build/RISCV/gem5.debug(PyEval_EvalFrameEx+0x7245)[0x205d255]
./build/RISCV/gem5.debug(PyEval_EvalFrameEx+0x7245)[0x205d255]
./build/RISCV/gem5.debug(PyEval_EvalCodeEx+0x89c)[0x205f5ec]
./build/RISCV/gem5.debug(PyEval_EvalFrameEx+0x5f2a)[0x205bf3a]
./build/RISCV/gem5.debug(PyEval_EvalCodeEx+0x89c)[0x205f5ec]
./build/RISCV/gem5.debug(PyEval_EvalFrameEx+0x7131)[0x205d141]
./build/RISCV/gem5.debug(PyEval_EvalCodeEx+0x89c)[0x205f5ec]
./build/RISCV/gem5.debug(PyEval_EvalCode+0x19)[0x205f6d9]
./build/RISCV/gem5.debug(PyRun_StringFlags+0xf5)[0x2087c25]
--- END LIBC BACKTRACE ---
Thanks,
Best Regards,
Nitish
_______________________________________________
gem5-users mailing list
[email protected]
http://m5sim.org/cgi-bin/mailman/listinfo/gem5-users