Skip to content

Commit 4d6f129

Browse files
committed
Clean-up Conv2D geometrical constraints
1 parent 28fc670 commit 4d6f129

File tree

1 file changed

+56
-30
lines changed

1 file changed

+56
-30
lines changed

Deeploy/Targets/PULPOpen/TileConstraints/ConvTileConstraint.py

Lines changed: 56 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -247,58 +247,84 @@ def addGeometricalConstraint(tilerModel: TilerModel, parseDict: Dict, ctxt: Netw
247247
positions, but this requires more extensive framework changes.
248248
"""
249249

250-
# Get to-be-tiled tensor's buffers
250+
# ===== GET NECESSARY INFORMATION =====
251+
# Get to-be-tiled tensor buffers
251252
inputBufferName = parseDict['data_in']
253+
outputBufferName = parseDict['data_out']
254+
252255
weightBufferName = parseDict['weight']
253256
biasBufferName = parseDict['bias']
254-
outputBufferName = parseDict['data_out']
255257

258+
inputBuffer = ctxt.lookup(inputBufferName)
259+
260+
# Get other information
261+
has_bias = False if parseDict['has_bias'] == "false" else True
262+
263+
pads = parseDict["pads"]
256264
strides = parseDict["strides"]
257-
padding = parseDict["pads"]
258-
dilation = parseDict["dilations"]
265+
dilations = parseDict["dilations"]
266+
group = parseDict["group"]
259267

260-
# Add I/O dimensions to the model as variables
261-
for bufferName in [inputBufferName, weightBufferName, biasBufferName, outputBufferName]:
262-
if bufferName != "NULL":
263-
tilerModel.addTensorDimToModel(ctxt, bufferName)
268+
# ===== ADD I/O DIMS TO MODEL AS VARS =====
269+
buffersOfInterest = [inputBufferName, outputBufferName, weightBufferName]
270+
if has_bias:
271+
buffersOfInterest.append(biasBufferName)
272+
273+
for bufferName in buffersOfInterest:
274+
tilerModel.addTensorDimToModel(ctxt, bufferName)
264275

265-
# Handle input dimensions
276+
# ===== EXTRACT TENSOR DIMS AS VARS =====
277+
# Input
278+
# NHWC layout
266279
inputBatchVar = tilerModel.getTensorDimVar(tensorName = inputBufferName, dimIdx = 0)
267280
inputHeightVar = tilerModel.getTensorDimVar(tensorName = inputBufferName, dimIdx = 1)
268281
inputWidthVar = tilerModel.getTensorDimVar(tensorName = inputBufferName, dimIdx = 2)
269282
inputChannelVar = tilerModel.getTensorDimVar(tensorName = inputBufferName, dimIdx = 3)
270283

271-
# Handle weight dimensions
284+
# Output
285+
# NHWC layout
286+
outputBatchVar = tilerModel.getTensorDimVar(tensorName = outputBufferName, dimIdx = 0)
287+
outputHeightVar = tilerModel.getTensorDimVar(tensorName = outputBufferName, dimIdx = 1)
288+
outputWidthVar = tilerModel.getTensorDimVar(tensorName = outputBufferName, dimIdx = 2)
289+
outputChannelVar = tilerModel.getTensorDimVar(tensorName = outputBufferName, dimIdx = 3)
290+
291+
# Weight
292+
# C_out - H - W layout - C_in (depthwise convolution weights,
293+
# with c_in used for grouping different than number of channels)
272294
weightOutChannelVar = tilerModel.getTensorDimVar(tensorName = weightBufferName, dimIdx = 0)
273295
weightHeightVar = tilerModel.getTensorDimVar(tensorName = weightBufferName, dimIdx = 1)
274296
weightWidthVar = tilerModel.getTensorDimVar(tensorName = weightBufferName, dimIdx = 2)
275297
weightInChannelVar = tilerModel.getTensorDimVar(tensorName = weightBufferName, dimIdx = 3)
276298

277-
# Handle bias dimensions
278-
if biasBufferName != "NULL":
279-
biasChannelVar = tilerModel.getTensorDimVar(tensorName = biasBufferName, dimIdx = 0)
299+
# Bias (C_out)
300+
if has_bias:
301+
biasDimVar = tilerModel.getTensorDimVar(tensorName = biasBufferName, dimIdx = 0)
280302

281-
# Handle output dimensions
282-
outputBatchVar = tilerModel.getTensorDimVar(tensorName = outputBufferName, dimIdx = 0)
283-
outputHeightVar = tilerModel.getTensorDimVar(tensorName = outputBufferName, dimIdx = 1)
284-
outputWidthVar = tilerModel.getTensorDimVar(tensorName = outputBufferName, dimIdx = 2)
285-
outputChannelVar = tilerModel.getTensorDimVar(tensorName = outputBufferName, dimIdx = 3)
303+
# ===== ADD CONSTRAINTS =====
304+
# Add constraint for batch size match between input and output
305+
tilerModel.addConstraint(outputBatchVar == inputBatchVar)
286306

287-
# Add constraints to the optimization problem of the tiler model
288-
# Map output dims to inputs dims
289-
tilerModel.addConstraint(outputBatchVar == inputBatchVar) # Batch
290-
tilerModel.addConstraint(outputChannelVar == weightOutChannelVar) # Output Channel
291-
if biasBufferName != "NULL":
292-
tilerModel.addConstraint(outputChannelVar == biasChannelVar) # Bias
307+
# Add constraint for input width and height sizes match
308+
# (Depends on output height and width, kernel size, padding, dilations, and strides.
309+
# For more information on the connections, see ONNX and/or Torch Conv2D documentation).
310+
# Assume worst case scenario (data padding on all sides) when tiling on a ceratin dimension.
311+
effectiveHeight = inputHeightVar + ((pads[0] + pads[2]) * (inputHeightVar == inputBuffer.shape[1]))
312+
effectiveWidth = inputWidthVar + ((pads[1] + pads[3]) * (inputWidthVar == inputBuffer.shape[2]))
293313

294-
inputBuffer = ctxt.lookup(inputBufferName)
314+
tilerModel.addConstraint((outputHeightVar == (effectiveHeight - dilations[0] * (weightHeightVar - 1) - 1) // strides[0] + 1))
315+
tilerModel.addConstraint((outputWidthVar == (effectiveWidth - dilations[1] * (weightWidthVar - 1) - 1) // strides[1] + 1))
295316

296-
# Effective input size for output calculation (always includes full padding)
297-
effectiveHeight = inputHeightVar + ((padding[0] + padding[2]) * (inputHeightVar == inputBuffer.shape[1]))
298-
effectiveWidth = inputWidthVar + ((padding[1] + padding[3]) * (inputWidthVar == inputBuffer.shape[2]))
317+
# Add constraint for input channel size match
318+
# (Depends on weight output channel and conv grouping)
319+
tilerModel.addConstraint(inputChannelVar == (weightInChannelVar * group))
299320

300-
tilerModel.addConstraint((outputHeightVar == (effectiveHeight - (weightHeightVar - 1) - 1) // strides[0] + 1))
301-
tilerModel.addConstraint((outputWidthVar == (effectiveWidth - (weightWidthVar - 1) - 1) // strides[1] + 1))
321+
# Add constraint for weight output channels to match
322+
# output number of channels
323+
tilerModel.addConstraint(weightOutChannelVar == outputChannelVar)
324+
325+
# Add constraint for bias size to match number of output channels
326+
if has_bias:
327+
tilerModel.addConstraint(biasDimVar == outputChannelVar)
302328

303329
return tilerModel
304330

0 commit comments

Comments
 (0)