Hi Nitish, Yes, this is a bug with gem5, but I haven't been able to track down the problem myself. It could be due to some inaccuracy in setting up the program's memory (in src/arch/riscv/process.cc), which is based on my interpretation of the proxy kernel's code.
-Alec Roelke On Mon, Sep 25, 2017 at 4:58 PM, Nitish Srivastava <[email protected]> wrote: > 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 >
_______________________________________________ gem5-users mailing list [email protected] http://m5sim.org/cgi-bin/mailman/listinfo/gem5-users
