-
Notifications
You must be signed in to change notification settings - Fork 51
/
EyerissF.py
190 lines (146 loc) · 6.61 KB
/
EyerissF.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
import numpy as np
import conf
from PE import PE
from Activiation import Relu
class EyerissF:
GlobalBuffer = conf.SRAMSize
EyerissWidth = conf.EyerissWidth
EyerissHeight = conf.EyerissHeight
def __init__(self):
self.__InitPEs__()
def Conv2d(self, Picture, FilterWeight, ImageNum, FilterNum):
PictureColumnLength, FilterWeightColumnLength = self.__DataDeliver__(Picture, FilterWeight, ImageNum, FilterNum)
self.__run__()
ConvedArray = self.__PsumTransport__(PictureColumnLength, FilterWeightColumnLength)
ReluedConvedArray = Relu(ConvedArray)
self.__SetALLPEsState__(conf.ClockGate)
return ReluedConvedArray
def __InitPEs__(self, PEsWidth=conf.EyerissWidth, PEsHeight=conf.EyerissHeight):
self.PEArray = list()
for x in range(0, PEsHeight):
self.PEArray.append(list())
for y in range(0, PEsWidth):
self.PEArray[x].append(PE())
def __SetALLPEsState__(self, State):
assert State == conf.ClockGate or State == conf.Running
for ColumnELement in range(0, EyerissF.EyerissHeight):
for RowElement in range(0, EyerissF.EyerissWidth):
self.PEArray[ColumnELement][RowElement].SetPEState(State)
def __SetPEsRunningState__(self, PictureColumnLength, FilterWeightColumnLength):
# 卷积核行数必须小于图片行数
assert FilterWeightColumnLength <= PictureColumnLength
# 卷积核行数必须小于Eyeriss高度
assert FilterWeightColumnLength <= EyerissF.EyerissHeight
# 图片行数必须小于 Eyeriss长宽只和-1
assert PictureColumnLength <= EyerissF.EyerissHeight + EyerissF.EyerissWidth - 1
for ColumnELement in range(0, FilterWeightColumnLength):
for RowElement in range(0, PictureColumnLength + 1 - FilterWeightColumnLength):
try:
self.PEArray[ColumnELement][RowElement].SetPEState(conf.Running)
except:
pass
def __SetALLPEImgNumAndFltNum__(self, ImageNum, FilterNum):
for ColumnELement in range(0, EyerissF.EyerissHeight):
for RowElement in range(0, EyerissF.EyerissWidth):
self.PEArray[ColumnELement][RowElement].SetPEImgAndFlt(ImageNum, FilterNum)
def __DataDeliver__(self, Picture, FilterWeight, ImageNum, FilterNum):
# put the pic and filter row data into PEArray
# Eyeriss越界检查
# 卷积核行数不能超过 Eyeriss的高度(12)
assert len(FilterWeight) <= self.EyerissHeight
# 图片的行数不能超过 卷积核行数 + Eyeriss宽度(14) -1
assert len(Picture) <= len(FilterWeight) + self.EyerissWidth - 1
PictureColumnLength = len(Picture)
FilterWeightColumnLength = len(FilterWeight)
self.__SetALLPEImgNumAndFltNum__(ImageNum, FilterNum)
self.__SetPEsRunningState__(PictureColumnLength, FilterWeightColumnLength)
# filterWeight 从左到右
for ColumnELement in range(0, len(FilterWeight)):
for RowElement in range(0, self.EyerissWidth):
self.PEArray[ColumnELement][RowElement].SetFilterWeight(FilterWeight[ColumnELement])
# ImageRow 从左下到右上
for ColumnELement in range(0, len(Picture)):
DeliverinitR = 0
DeliverinitH = ColumnELement
for c in range(0, ColumnELement + 1):
try:
# 当len(pic)大于12的时候会发生一场,找不到PEArray[13][0],但是与后续不影响
self.PEArray[DeliverinitH][DeliverinitR].SetImageRow(Picture[ColumnELement])
except:
pass
DeliverinitR = DeliverinitR + 1
DeliverinitH = DeliverinitH - 1
return PictureColumnLength, FilterWeightColumnLength
def __run__(self):
# 整个系统开始计算
for x in range(0, conf.EyerissHeight):
for y in range(0, conf.EyerissWidth):
if self.PEArray[x][y].PEState == conf.Running:
self.PEArray[x][y].CountPsum()
def __PsumTransport__(self, PictureColumnLength, FilterWeightColumnLength):
line = list()
result = list()
for RowElement in range(0, PictureColumnLength + 1 - FilterWeightColumnLength):
# 清空list
line.clear()
for ColumnElement in range(0, FilterWeightColumnLength).__reversed__():
# 从上到下把psum加入list
line.append(self.PEArray[ColumnElement][RowElement].Psum)
# 将list中的Psum做和,得到一行卷积值,保存到r中
result.append(np.sum(line, axis=0, dtype=int))
# 将r中全部的卷积值组合成一个矩阵,并返回
if result == []:
return
return np.vstack(result)
def __ShowPEState__(self, x, y):
print("PE is : ", x, ",", y)
if self.PEArray[x][y].PEState == conf.Running:
print("PEState : Running")
else:
print("PEState : ClockGate")
print("FilterWeight :", self.PEArray[x][y].FilterWeight)
print("ImageRow :", self.PEArray[x][y].ImageRow)
def __ShowAllPEState__(self):
xx = list()
yy = list()
for x in range(conf.EyerissHeight):
for y in range(conf.EyerissWidth):
self.__ShowPEState__(x, y)
if self.PEArray[x][y].PEState == conf.Running:
yy.append(1)
else:
yy.append(0)
xx.append(yy)
yy = []
print(np.array(xx))
def __ShowRunningPEState__(self):
c = 0
xx = list()
yy = list()
for x in range(conf.EyerissHeight):
for y in range(conf.EyerissWidth):
if self.PEArray[x][y].PEState == conf.Running:
self.__ShowPEState__(x, y)
c = c + 1
yy.append(1)
else:
yy.append(0)
xx.append(yy)
yy = []
print("一共有", c, "个PE正在运行")
print(np.array(xx))
def __ShowStates__(self):
c = 0
xx = list()
yy = list()
for x in range(conf.EyerissHeight):
for y in range(conf.EyerissWidth):
if self.PEArray[x][y].PEState == conf.Running:
c = c + 1
yy.append(1)
else:
yy.append(0)
xx.append(yy)
yy = []
print("一共有", c, "个PE正在运行")
print(np.array(xx))