Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix richards segfault #55

Merged
merged 4 commits into from
Aug 11, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions benchmarks/single-core/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
SRC=$(wildcard *.c)
ELFS=$(patsubst %.c,%.elf,$(SRC))

ESDK=${EPIPHANY_HOME}
LDF=${ESDK}/bsps/parallella_E16G3_1GB/fast.ldf

CC=e-gcc
CFLAGS=-Wall -Wno-unused -Werror -falign-functions=8
EXTRA_CFLAGS=

LDFLAGS=-T${LDF}
LDLIBS=-le-lib

LIBDIR=${ESDK}/tools/host/lib
INCDIR=${ESDK}/tools/host/include

.PHONY: all clean

all: ${ELFS}

%.elf: %.c
${CC} $< -o $@ ${CFLAGS} ${EXTRA_CFLAGS} -static -L${LIBDIR} -I${INCDIR} ${LDLIBS} ${LDFLAGS}

clean:
-rm -f ${ELFS}
2 changes: 1 addition & 1 deletion benchmarks/single-core/fib_large.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#include <stdio.h>
int main() {
unsigned long a = 1, b = 1, i = 0, temp = 0;
for(i = 0; i < 10000; i++) {
for(i = 0; i < 10000000; i++) {
temp = a;
a = b;
b += temp;
Expand Down
Binary file modified benchmarks/single-core/fib_large.elf
100644 → 100755
Binary file not shown.
2 changes: 1 addition & 1 deletion benchmarks/single-core/richards.c
Original file line number Diff line number Diff line change
Expand Up @@ -375,7 +375,7 @@ void append(struct packet *pkt, struct packet *ptr)

int main(void)
{
int reps = 1; /* FIXME: 500 */
int reps = 100; /* FIXME: 500 */
struct packet *wkq = 0;
struct task *tasks[NUM_TASKS];
struct packet *pkts[NUM_PKTS];
Expand Down
Binary file modified benchmarks/single-core/richards.elf
100644 → 100755
Binary file not shown.
1 change: 1 addition & 0 deletions revelation/machine.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ def __init__(self, memory, debug, coreid=0x808, logger=None):
self.num_insts = 0
self.running = True
self.is_first_core = False # Is this the top-left (NW) core?
self.is_in_hardware_loop = False
self.logger = logger
# Epiphany III exceptions.
self.exceptions = { 'UNIMPLEMENTED' : 0b0100,
Expand Down
325 changes: 161 additions & 164 deletions revelation/sim.py

Large diffs are not rendered by default.

12 changes: 0 additions & 12 deletions revelation/storage.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from pydgin.debug import Debug, pad, pad_hex
from pydgin.jit import elidable, unroll_safe, hint

from revelation.registers import reg_memory_map

Expand All @@ -23,15 +22,13 @@ def __init__(self, size=2**10, logger=None):
self.data = ['\0'] * size
self.size = len(self.data)

@unroll_safe
def read(self, start_addr, num_bytes):
value = 0
for i in range(num_bytes - 1, -1, -1):
value = value << 8
value = value | ord(self.data[start_addr + i])
return value

@elidable
def iread(self, start_addr, num_bytes):
"""This is instruction read, which is otherwise identical to read. The
only difference is the elidable annotation, which we assume the
Expand All @@ -44,7 +41,6 @@ def iread(self, start_addr, num_bytes):
value = value | ord(self.data[start_addr + i])
return value

@unroll_safe
def write(self, start_addr, num_bytes, value, from_core=0x808):
for i in range(num_bytes):
self.data[start_addr + i] = chr(value & 0xff)
Expand All @@ -54,7 +50,6 @@ def write(self, start_addr, num_bytes, value, from_core=0x808):
class Memory(object):
"""Sparse memory model adapted from Pydgin.
"""
_immutable_fields_ = ['block_size', 'addr_mask', 'block_mask', 'logger']

def __init__(self, block_size=2**20, logger=None):
self.block_size = block_size
Expand All @@ -68,19 +63,15 @@ def __init__(self, block_size=2**20, logger=None):
def add_block(self, block_addr):
self.block_dict[block_addr] = _BlockMemory(size=self.block_size)

@elidable
def get_block_mem(self, block_addr):
if block_addr not in self.block_dict:
self.add_block(block_addr)
block_mem = self.block_dict[block_addr]
return block_mem

@elidable
def iread(self, start_addr, num_bytes, from_core=0x808):
if is_local_address(start_addr):
start_addr |= (from_core << 20)
start_addr = hint(start_addr, promote=True)
num_bytes = hint(num_bytes, promote=True)
end_addr = start_addr + num_bytes - 1
block_addr = self.block_mask & start_addr
block_mem = self.get_block_mem(block_addr)
Expand All @@ -106,7 +97,6 @@ def read(self, start_addr, num_bytes, from_core=0x808):
if is_local_address(start_addr):
start_addr |= (from_core << 20)
block_addr = self.block_mask & start_addr
block_addr = hint(block_addr, promote=True)
block_mem = self.get_block_mem(block_addr)
masked_addr = 0xfffff & start_addr
value = block_mem.read(start_addr & self.addr_mask, num_bytes)
Expand Down Expand Up @@ -149,7 +139,6 @@ def write(self, start_addr, num_bytes, value, from_core=0x808, quiet=False):
ilat |= 0x10
self.write(coreid_mask | 0xf0428, 4, ilat)
block_addr = self.block_mask & start_addr
block_addr = hint(block_addr, promote=True)
block_mem = self.get_block_mem(block_addr)
block_mem.write(start_addr & self.addr_mask, num_bytes, value)
masked_addr = 0xfffff & start_addr
Expand All @@ -166,7 +155,6 @@ class MemoryMappedRegisterFile(object):
"""Simulate the memory-mapped registers of a single Epiphany core.
Note that memory objects can only read and write aligned words.
"""
_immutable_fields_ = ['debug_nchars', 'num_regs', 'coreid', 'logger']

def __init__(self, memory, coreid, logger):
self.debug = Debug()
Expand Down
3 changes: 2 additions & 1 deletion revelation/test/sim.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ def init_state(self, instructions, **args):
self.memory.write(RESET_ADDR + written_so_far, num_bytes, data)
written_so_far += num_bytes
self.states.append(new_state(mem=self.memory, debug=self.debug, **args))
self.hardware_loops.append(False)
self.states[0].set_first_core(True)
self.num_cores = len(self.states)
self.max_insts = len(instructions)

init_sim(MockRevelation())
1 change: 0 additions & 1 deletion revelation/test/test_argument_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ def test_argv_defaults(capfd):
assert revelation.switch_interval == 1
assert not revelation.collect_times
assert revelation.logger == None
assert revelation.core == 0


@pytest.mark.parametrize('argv,expected',
Expand Down
12 changes: 5 additions & 7 deletions revelation/test/test_compiled_c.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from revelation.sim import Revelation
from revelation.sim import EXIT_SUCCESS, Revelation
from revelation.test.machine import StateChecker

import os.path
Expand Down Expand Up @@ -105,7 +105,7 @@ def test_compiled_c_with_return(elf_file, expected):
@pytest.mark.parametrize('elf_file,expected', [('nothing.elf', 250),
('fib.elf', 544),
])
def test_compiled_c(elf_file, expected, capsys):
def test_compiled_c(elf_file, expected):
"""Test an ELF file that has been compiled from a C function.
This test checks that the correct number of instructions have been executed.
"""
Expand All @@ -114,9 +114,7 @@ def test_compiled_c(elf_file, expected, capsys):
with open(elf_filename, 'rb') as elf:
revelation.init_state(elf, elf_filename, False, is_test=True)
revelation.max_insts = 10000
revelation.run()
out, err = capsys.readouterr()
expected_text = 'Total ticks simulated = ' + str(expected)
assert expected_text in out
assert err == ''
exit_code, ticks = revelation.run()
assert expected == ticks
assert EXIT_SUCCESS == exit_code
assert not revelation.states[0].running
37 changes: 28 additions & 9 deletions revelation/test/test_sim.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from revelation.machine import RESET_ADDR
from revelation.sim import EXIT_SUCCESS
from revelation.test.sim import MockRevelation
from revelation.test.machine import StateChecker

Expand All @@ -10,9 +11,11 @@ def test_sim_trap16_3():
revelation = MockRevelation()
revelation.init_state(instructions)
assert revelation.states[0].running
revelation.run()
exit_code, ticks = revelation.run()
expected_state = StateChecker(pc=(2 + RESET_ADDR))
expected_state.check(revelation.states[0])
assert EXIT_SUCCESS == exit_code
assert len(instructions) == ticks
assert not revelation.states[0].running


Expand All @@ -23,9 +26,11 @@ def test_sim_nop16():
revelation = MockRevelation()
revelation.init_state(instructions)
assert revelation.states[0].running
revelation.run()
exit_code, ticks = revelation.run()
expected_state = StateChecker(pc=(4 + RESET_ADDR))
expected_state.check(revelation.states[0])
assert EXIT_SUCCESS == exit_code
assert len(instructions) == ticks
assert not revelation.states[0].running


Expand All @@ -35,9 +40,11 @@ def test_single_inst_add32():
revelation = MockRevelation()
revelation.init_state(instructions, rf0=0b01010101010)
assert revelation.states[0].running
revelation.run()
exit_code, ticks = revelation.run()
expected_state = StateChecker(AZ=0, pc=(6 + RESET_ADDR), rf1=(0b01010101010 * 2))
expected_state.check(revelation.states[0])
assert EXIT_SUCCESS == exit_code
assert len(instructions) == ticks
assert not revelation.states[0].running


Expand All @@ -48,10 +55,12 @@ def test_single_inst_sub32():
revelation = MockRevelation()
revelation.init_state(instructions, rf0=5)
assert revelation.states[0].running
revelation.run()
exit_code, ticks = revelation.run()
expected_state = StateChecker(AZ=0, AN=1, AC=0,
pc=(6 + RESET_ADDR), rf1=trim_32(5 - 0b01010101010))
expected_state.check(revelation.states[0])
assert EXIT_SUCCESS == exit_code
assert len(instructions) == ticks
assert not revelation.states[0].running


Expand All @@ -66,10 +75,12 @@ def test_add32_sub32():
revelation = MockRevelation()
revelation.init_state(instructions, rf0=0)
assert revelation.states[0].running
revelation.run()
exit_code, ticks = revelation.run()
expected_state = StateChecker(AZ=0, AN=1, AC=0, pc=(10 + RESET_ADDR),
rf1=trim_32(0 - 0b01010101010))
expected_state.check(revelation.states[0])
assert EXIT_SUCCESS == exit_code
assert len(instructions) == ticks
assert not revelation.states[0].running


Expand All @@ -82,15 +93,19 @@ def test_bcond32():
revelation = MockRevelation()
revelation.init_state(instructions, rf0=5)
assert revelation.states[0].running
revelation.run()
exit_code, ticks = revelation.run()
expected_state = StateChecker(pc=(14 + RESET_ADDR), rf1=0)
expected_state.check(revelation.states[0])
assert EXIT_SUCCESS == exit_code
assert len(instructions) - 1 == ticks
assert not revelation.states[0].running
revelation = MockRevelation()
revelation.init_state(instructions, rf0=8)
revelation.run()
exit_code, ticks = revelation.run()
expected_state = StateChecker(pc=(14 + RESET_ADDR), rf1=(8 + 0b01010101010))
expected_state.check(revelation.states[0])
assert EXIT_SUCCESS == exit_code
assert len(instructions) == ticks
assert not revelation.states[0].running


Expand All @@ -104,10 +119,12 @@ def test_add32_nop16_sub32():
revelation = MockRevelation()
revelation.init_state(instructions, rf0=0)
assert revelation.states[0].running
revelation.run()
exit_code, ticks = revelation.run()
expected_state = StateChecker(pc=(12 + RESET_ADDR), AC=0, AN=1, AZ=0,
rf1=trim_32(0 - 0b01010101010))
expected_state.check(revelation.states[0])
assert EXIT_SUCCESS == exit_code
assert len(instructions) == ticks
assert not revelation.states[0].running


Expand All @@ -119,7 +136,9 @@ def test_sim_all_16bit():
revelation = MockRevelation()
revelation.init_state(instructions)
assert revelation.states[0].running
revelation.run()
exit_code, ticks = revelation.run()
expected_state = StateChecker(pc=(6 + RESET_ADDR))
expected_state.check(revelation.states[0])
assert EXIT_SUCCESS == exit_code
assert len(instructions) == ticks
assert not revelation.states[0].running
17 changes: 15 additions & 2 deletions revelation/test/test_utils.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,22 @@
from revelation.utils import (get_exponent, get_mantissa, bits2float,
float2bits, is_nan, is_inf, is_zero, sext_3, sext_11, sext_24, zfill)
from revelation.utils import get_exponent, get_mantissa, bits2float
from revelation.utils import float2bits, format_thousands, is_nan, is_inf
from revelation.utils import is_zero, sext_3, sext_11, sext_24, zfill

import math


def test_format_number():
assert '1' == format_thousands(1)
assert '11' == format_thousands(11)
assert '111' == format_thousands(111)
assert '1,111' == format_thousands(1111)
assert '11,111' == format_thousands(11111)
assert '1,111,111' == format_thousands(1111111)
assert '11,111,111' == format_thousands(11111111)
assert '111,111,111' == format_thousands(111111111)
assert '1,111,111,111' == format_thousands(1111111111)


def test_zfill():
assert '000001' == zfill('1', 6)
assert '+00001' == zfill('+1', 6)
Expand Down
14 changes: 13 additions & 1 deletion revelation/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,19 @@
import math


def format_thousands(number):
"""Format a number with a comma after every third digit.
"""
chars = []
number_s = str(number)
size = len(number_s)
for index in xrange(size - 1, -1, -1):
if (size - index) > 1 and (size - index - 1) % 3 == 0:
chars.insert(0, ',')
chars.insert(0, number_s[index])
return ''.join(chars)


def zfill(string, width):
"""zfill(x, width) -> string
Pad a numeric string x with zeros on the left, to fill a field
Expand Down Expand Up @@ -84,7 +97,6 @@ def sext_24(value):
return value


@pydgin.utils.specialize.argtype(0)
def trim_32(value):
return value & 0xffffffff

Expand Down