Skip to content

Commit

Permalink
Basic nonzero-activation serialization done
Browse files Browse the repository at this point in the history
  • Loading branch information
vysarge committed Nov 26, 2017
1 parent c54519b commit 8715b0b
Show file tree
Hide file tree
Showing 4 changed files with 160 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
nnsim.egg-info/*
nnsim/__pycache__/*
pruning/__pycache__/*
73 changes: 73 additions & 0 deletions pruning/converter.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
from nnsim.module import Module
from nnsim.reg import Reg
from nnsim.channel import Channel

class Converter(Module):
def instantiate(self, in_chn, out_chn, input_size, block_size):
self.name = 'converter'

# input_size is the width of the input channel
# block_size is the size of blocks in memory for which we make guarantees
self.input_size = input_size
self.block_size = block_size

# Number of times to transfer the input into the buffer
self.in_sets = block_size // input_size
assert(block_size % input_size == 0) # For now, ensure that input is evenly divisible
self.curr_set = 0 # Counter for where we are currently in the buffer

# Vars for serial output
self.transfer_marker = 0
self.prev_vals = []

# Buffer. Use for accumulating input values
self.buffer = [[0 for j in range(input_size)] for i in range(self.in_sets)]

# channels
self.in_chn = in_chn
self.out_chn = out_chn

def tick(self):
# Once data is accumulated (placed first to prevent this from happening on the same cycle)
if (self.curr_set == self.in_sets):
# Do this on the last cycle
if (self.transfer_marker == self.block_size):
if (len(self.prev_vals) == 0): # guarantee we will always send /something/ per block
self.out_chn.push([0,0,1])
else:
self.prev_vals.append(1)
self.out_chn.push(self.prev_vals)

# Go to next block
self.prev_vals = []
self.curr_set = 0
self.transfer_marker = 0
else:
# pull out and check current value
# if nonzero and there's room to push to the buffer, do so
# hold onto values before sending so that we can send the last bit correctly
# (1 if last nonzero activation in this block, 0 otherwise)
j = self.transfer_marker % self.input_size
i = self.transfer_marker // self.input_size
curr_val = self.buffer[i][j]
if (not curr_val == 0 and self.out_chn.vacancy()):
if (len(self.prev_vals) > 0):
self.prev_vals.append(0)
self.out_chn.push(self.prev_vals)
self.prev_vals = [self.transfer_marker, curr_val]
self.transfer_marker += 1
elif (curr_val == 0):
self.transfer_marker += 1




# Accumulate data for pruning etc
if (self.in_chn.valid() and not self.curr_set == self.in_sets):
data = self.in_chn.pop()
#imin = self.curr_set * self.input_size
#imax = imin + self.input_size
self.buffer[self.curr_set] = data
self.curr_set += 1


58 changes: 58 additions & 0 deletions pruning/tb.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
from random import randint

from nnsim.module import Module
from nnsim.reg import Reg
from nnsim.channel import Channel
from nnsim.simulator import Finish

from converter import Converter

class ConverterTB(Module):
def instantiate(self):
self.name = 'tb'

self.input_size = 4
self.block_size = 12
self.in_sets = self.block_size // self.input_size

self.in_chn = Channel()
self.out_chn = Channel()

self.dut = Converter(self.in_chn, self.out_chn, self.input_size, self.block_size)

self.iterations = 10
self.iteration = 0
self.curr_set = 0
self.out_counter = 0
self.test_data = [[randint(1,5) if randint(0,3)>2 else 0\
for j in range(self.block_size)]\
for i in range(self.iterations)]
print("Stimulus:")
print("[")
for i in range(len(self.test_data)):
print(self.test_data[i])
print("]")

def tick(self):
if (self.in_chn.vacancy() and not self.iteration == self.iterations):
imin = self.curr_set*self.input_size
imax = imin+self.input_size
data = [self.test_data[self.iteration][i] for i in range(imin, imax)]
self.in_chn.push(data)

self.curr_set += 1
if (self.curr_set == self.in_sets):
self.curr_set = 0
self.iteration += 1
if (self.out_chn.valid()):
data = self.out_chn.pop()
print(data)
if (data[2] == 1):
self.out_counter += 1
if (self.out_counter == self.iterations):
raise Finish("Check manually")

if __name__ == "__main__":
from nnsim.simulator import run_tb
converter_tb = ConverterTB()
run_tb(converter_tb, verbose=False)
26 changes: 26 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
from setuptools import setup

def readme():
return ''
#with open('README.rst') as f:
# return f.read()

setup(name='nnsim',
version='0.1',
description='Neural network dataflow simulator',
long_description=readme(),
classifiers=[
'Development Status :: 3 - Alpha',
'License :: OSI Approved :: MIT License',
'Programming Language :: Python :: 2.7',
'Topic :: Scientific/Engineering :: Electronic Design Automation (EDA)',
],
keywords='neural-networks hardware',
url='https://github.mit.edu/chiraag/nn-simulator',
author='Chiraag Juvekar',
author_email='[email protected]',
license='MIT',
packages=['nnsim'],
install_requires=[],
include_package_data=True,
zip_safe=False)

0 comments on commit 8715b0b

Please sign in to comment.