127 auto inputType = cast<ShapedType>(convOp.getInputs()[0].getType());
128 auto filterType = cast<ShapedType>(convOp.getInputs()[1].getType());
129 auto outputType = cast<ShapedType>(convOp.getOutputs()[0].getType());
131 if (!convOp.hasPureTensorSemantics())
133 convOp,
"expected op to have pure tensor semantics");
135 if (!filterType.hasStaticShape())
137 convOp,
"expected a static shape for the filter");
139 if (!inputType.hasStaticShape())
141 "expected a static shape for the input");
144 Value input = convOp.getInputs()[0];
145 Value filter = convOp.getInputs()[1];
146 Value output = convOp.getOutputs()[0];
161 assert(isa<RankedTensorType>(filterType) &&
162 "expected filter type to be a ranked tensor");
163 auto tensorFilterType = cast<RankedTensorType>(filterType);
167 auto reshapedFilterType =
168 RankedTensorType::get({fh * fw * ic, oc}, filterType.getElementType(),
169 tensorFilterType.getEncoding());
170 Value reshapedFilter = tensor::CollapseShapeOp::create(
171 rewriter, loc, reshapedFilterType, filter, filterReassocIndices);
174 RankedTensorType reshapedOutputType =
175 RankedTensorType::get({n, oh * ow, oc}, outputType.getElementType());
176 Value reshapedOutput = tensor::CollapseShapeOp::create(
177 rewriter, loc, reshapedOutputType, output, outputReassocIndices);
180 Value colTensor = tensor::EmptyOp::create(rewriter, loc, colTensorShape,
181 inputType.getElementType());
184 auto nloops = colTensorShape.size();
186 auto parallel = utils::IteratorType::parallel;
187 auto reduction = utils::IteratorType::reduction;
197 i2cToOperExprs.
fhIndex = kIndicesExprs[0];
198 i2cToOperExprs.
fwIndex = kIndicesExprs[1];
199 i2cToOperExprs.
icIndex = kIndicesExprs[2];
200 i2cToOperExprs.
ohIndex = mIndicesExprs[0];
201 i2cToOperExprs.
owIndex = mIndicesExprs[1];
205 i2cToOperExprs, llvm::to_vector(convOp.getStrides().getValues<
int64_t>()),
206 llvm::to_vector(convOp.getDilations().getValues<
int64_t>()), rewriter);
215 auto img2ColTensor = linalg::GenericOp::create(
216 rewriter, loc, colTensor.
getType(),
217 input, colTensor, img2colIndexingMaps,
220 linalg::YieldOp::create(nestedBuilder, nestedLoc, args[0]);
228 bindDims(context, bDim, mDim, nDim, kDim);
231 auto resultMap =
AffineMap::get(4, 0, {bDim, mDim, nDim}, context);
233 parallel, reduction};
235 auto genericOp = linalg::GenericOp::create(
236 rewriter, loc, reshapedOutputType,
237 ValueRange{img2ColTensor.getResult(0), reshapedFilter},
244 linalg::YieldOp::create(nestedBuilder, nestedLoc,
add);
248 auto reshapedResult = tensor::ExpandShapeOp::create(
249 rewriter, loc, outputType,
result, outputReassocIndices);
253 return std::make_pair(img2ColTensor.getOperation(),
254 reshapedResult.getOperation());
259 linalg::DepthwiseConv2DNhwcHwcOp convOp) {
260 auto inputType = cast<RankedTensorType>(convOp.getInputs()[0].getType());
261 auto filterType = cast<RankedTensorType>(convOp.getInputs()[1].getType());
262 auto outputType = cast<RankedTensorType>(convOp.getOutputs()[0].getType());
264 if (!convOp.hasPureTensorSemantics())
266 convOp,
"expected op to have pure tensor semantics");
268 if (!filterType.hasStaticShape())
270 convOp,
"expected a static shape for the filter");
272 if (!inputType.hasStaticShape())
274 "expected a static shape for the input");
279 "expected all ones for dilations");
284 auto operandTensorType = cast<RankedTensorType>(operand.
getType());
296 Value outputTensor = tensor::EmptyOp::create(
297 rewriter, loc, targetShape, operandTensorType.getElementType());
300 nloops, utils::IteratorType::parallel);
307 auto transposedOp = linalg::GenericOp::create(
308 rewriter, loc, outputTensor.getType(),
309 operand, outputTensor, indexingMaps,
312 linalg::YieldOp::create(nestedBuilder, nestedLoc, args[0]);
315 return transposedOp.getResult(0);
318 Value input = convOp.getInputs()[0];
319 Value filter = convOp.getInputs()[1];
320 Value output = convOp.getOutputs()[0];
323 Value inputT = transposeOperand(input, {0, 3, 1, 2});
324 Value filterT = transposeOperand(filter, {2, 0, 1});
326 cast<RankedTensorType>(filterT.getType()).getShape();
329 int n = outputShape[0];
330 int oh = outputShape[1];
331 int ow = outputShape[2];
332 int c = outputShape[3];
333 int fh = filterTShape[1];
334 int fw = filterTShape[2];
337 Value transposedOutputTensor = transposeOperand(output, {0, 3, 1, 2});
339 AffineExpr nDim, cDim, ohDim, owDim, khDim, kwDim;
343 convOp.getStrides().getValues<
int64_t>()[0]);
345 convOp.getStrides().getValues<
int64_t>()[1]);
348 owDim * swSym + kwDim};
350 auto nloops = colTensorShape.size();
353 nloops, utils::IteratorType::parallel);
359 Value colTensor = tensor::EmptyOp::create(rewriter, loc, colTensorShape,
360 inputType.getElementType());
362 auto img2ColTensor = linalg::GenericOp::create(
363 rewriter, loc, colTensor.
getType(),
364 inputT, colTensor, indexingMaps,
367 linalg::YieldOp::create(nestedBuilder, nestedLoc, args[0]);
371 {0, 1}, {2, 3}, {4, 5}};
376 auto reshapedImg2ColTensorType = RankedTensorType::get(
377 {n * c, oh * ow, fh * fw}, inputType.getElementType());
378 auto reshapedFilterTensorType =
379 RankedTensorType::get({c, fh * fw}, filterType.getElementType());
380 auto reshapedOutputTensorType =
381 RankedTensorType::get({n * c, oh * ow}, outputType.getElementType());
383 Value reshapedImg2ColTensor = tensor::CollapseShapeOp::create(
384 rewriter, loc, reshapedImg2ColTensorType, img2ColTensor.getResult(0),
385 img2ColTensorReassocIndices);
386 Value reshapedFilterTensor =
387 tensor::CollapseShapeOp::create(rewriter, loc, reshapedFilterTensorType,
388 filterT, filterReassociationIndice);
389 Value reshapedoutputTensor = tensor::CollapseShapeOp::create(
390 rewriter, loc, reshapedOutputTensorType, transposedOutputTensor,
391 outputReassociationIndice);
393 auto batchMatVecResult = linalg::BatchMatvecOp::create(
395 ValueRange{reshapedImg2ColTensor, reshapedFilterTensor},
401 auto batchMatVecResultReshaped = tensor::ExpandShapeOp::create(
402 rewriter, loc, transposedOutputTensor.
getType(),
403 batchMatVecResult.getResult(0), batchMatVecReassociationIndice);
405 Value transposedResult =
406 transposeOperand(batchMatVecResultReshaped, {0, 2, 3, 1});
409 return std::make_pair(img2ColTensor.getOperation(),
415 auto inputType = cast<ShapedType>(convOp.getInputs()[0].getType());
416 auto filterType = cast<ShapedType>(convOp.getInputs()[1].getType());
417 auto outputType = cast<ShapedType>(convOp.getOutputs()[0].getType());
419 if (!convOp.hasPureTensorSemantics())
421 convOp,
"expected op to have pure tensor semantics");
423 if (!filterType.hasStaticShape())
425 convOp,
"expected a static shape for the filter");
427 if (!inputType.hasStaticShape())
429 "expected a static shape for the input");
431 Value input = convOp.getInputs()[0];
432 Value filter = convOp.getInputs()[1];
433 Value output = convOp.getOutputs()[0];
435 auto filterShape = filterType.getShape();
436 auto outputShape = outputType.getShape();
446 auto loc = convOp.getLoc();
449 assert(isa<RankedTensorType>(filterType) &&
450 "expected filter type to be a ranked tensor");
451 auto tensorFilterType = cast<RankedTensorType>(filterType);
454 auto reshapedFilterType =
455 RankedTensorType::get({oc, ic * fh * fw}, inputType.getElementType(),
456 tensorFilterType.getEncoding());
457 Value reshapedFilter = tensor::CollapseShapeOp::create(
458 rewriter, loc, reshapedFilterType, filter, filterReassocIndices);
461 auto reshapedOutputType =
462 RankedTensorType::get({n, oc, oh * ow}, outputType.getElementType());
463 Value reshapedOutput = tensor::CollapseShapeOp::create(
464 rewriter, loc, reshapedOutputType, output, outputReassocIndices);
468 Value colTensor = tensor::EmptyOp::create(rewriter, loc, colTensorShape,
469 inputType.getElementType());
471 auto nloops = colTensorShape.size();
473 auto parallel = utils::IteratorType::parallel;
474 auto reduction = utils::IteratorType::reduction;
485 i2cToOperExprs.
icIndex = kIndicesExprs[0];
486 i2cToOperExprs.
fhIndex = kIndicesExprs[1];
487 i2cToOperExprs.
fwIndex = kIndicesExprs[2];
488 i2cToOperExprs.
ohIndex = mIndicesExprs[0];
489 i2cToOperExprs.
owIndex = mIndicesExprs[1];
491 i2cToOperExprs, llvm::to_vector(convOp.getStrides().getValues<
int64_t>()),
492 llvm::to_vector(convOp.getDilations().getValues<
int64_t>()), rewriter);
501 auto img2ColTensor = linalg::GenericOp::create(
502 rewriter, loc, colTensor.
getType(),
503 input, colTensor, img2colIndexingMaps,
506 linalg::YieldOp::create(nestedBuilder, nestedLoc, args[0]);
514 bindDims(context, bDim, mDim, nDim, kDim);
517 auto resultMap =
AffineMap::get(4, 0, {bDim, mDim, nDim}, context);
519 parallel, reduction};
520 auto genericOp = linalg::GenericOp::create(
521 rewriter, loc, reshapedOutputType,
522 ValueRange{reshapedFilter, img2ColTensor.getResult(0)},
529 linalg::YieldOp::create(nestedBuilder, nestedLoc,
add);
533 auto reshapedResult = tensor::ExpandShapeOp::create(
534 rewriter, loc, outputType,
result, outputReassocIndices);
538 return std::make_pair(img2ColTensor.getOperation(),
539 reshapedResult.getOperation());
544 auto inputType = cast<ShapedType>(convOp.getInputs()[0].getType());
545 auto filterType = cast<ShapedType>(convOp.getInputs()[1].getType());
546 auto outputType = cast<ShapedType>(convOp.getOutputs()[0].getType());
548 if (!convOp.hasPureTensorSemantics())
550 convOp,
"expected op to have pure tensor semantics");
552 if (!filterType.hasStaticShape())
554 convOp,
"expected a static shape for the filter");
556 if (!inputType.hasStaticShape())
558 "expected a static shape for the input");
561 Value input = convOp.getInputs()[0];
562 Value filter = convOp.getInputs()[1];
563 Value output = convOp.getOutputs()[0];
578 assert(isa<RankedTensorType>(filterType) &&
579 "expected filter type to be a ranked tensor");
580 auto tensorFilterType = cast<RankedTensorType>(filterType);
585 auto reshapedFilterType =
586 RankedTensorType::get({oc, fh * fw * ic}, filterType.getElementType(),
587 tensorFilterType.getEncoding());
588 Value reshapedFilter = tensor::CollapseShapeOp::create(
589 rewriter, loc, reshapedFilterType, filter, filterReassocIndices);
592 RankedTensorType reshapedOutputType =
593 RankedTensorType::get({n, oh * ow, oc}, outputType.getElementType());
594 Value reshapedOutput = tensor::CollapseShapeOp::create(
595 rewriter, loc, reshapedOutputType, output, outputReassocIndices);
599 Value colTensor = tensor::EmptyOp::create(rewriter, loc, colTensorShape,
600 inputType.getElementType());
603 auto nloops = colTensorShape.size();
605 auto parallel = utils::IteratorType::parallel;
606 auto reduction = utils::IteratorType::reduction;
616 i2cToOperExprs.
fhIndex = kIndicesExprs[0];
617 i2cToOperExprs.
fwIndex = kIndicesExprs[1];
618 i2cToOperExprs.
icIndex = kIndicesExprs[2];
619 i2cToOperExprs.
ohIndex = mIndicesExprs[0];
620 i2cToOperExprs.
owIndex = mIndicesExprs[1];
624 i2cToOperExprs, llvm::to_vector(convOp.getStrides().getValues<
int64_t>()),
625 llvm::to_vector(convOp.getDilations().getValues<
int64_t>()), rewriter);
633 auto img2ColTensor = linalg::GenericOp::create(
634 rewriter, loc, colTensor.
getType(),
635 input, colTensor, img2colIndexingMaps,
638 linalg::YieldOp::create(nestedBuilder, nestedLoc, args[0]);
645 bindDims(context, bDim, mDim, nDim, kDim);
648 auto resultMap =
AffineMap::get(4, 0, {bDim, mDim, nDim}, context);
650 parallel, reduction};
652 auto genericOp = linalg::GenericOp::create(
653 rewriter, loc, reshapedOutputType,
654 ValueRange{img2ColTensor.getResult(0), reshapedFilter},
661 linalg::YieldOp::create(nestedBuilder, nestedLoc,
add);
665 auto reshapedResult = tensor::ExpandShapeOp::create(
666 rewriter, loc, outputType,
result, outputReassocIndices);
670 return std::make_pair(img2ColTensor.getOperation(),
671 reshapedResult.getOperation());
MLIRContext is the top-level object for a collection of MLIR operations.