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

Add support of vecmat/matvec in SetEncoding and MaterializeEncoding #15257

Closed
wants to merge 1 commit into from

Conversation

NatashaKnk
Copy link
Contributor

This PR is currently broken as it relies on 68945.

This implementation is by no means elegant. The vectors being passed into MaterializeEncoding without being expanded first require several plugs in multiple operations, since most of them try to pack the tensors directly (or at least infer the shape after packing). Thus, the shapes post-expansion need to be inferred outside the vecmat/matvec op lowering itself. This also requires a surprising amount of utility ops to calculate.
In addition, this approach creates the issue that since we are first padding, then expanding, and then packing -- the pad+pack ops don't get folded into pack.

Expanding the tensors in SetEncoding would elliminate most of the lack of elegance (but add some of it back in there, so this is not a perfect soultion by any means), but it does introduce unneccesary expansions earlier in the stack as discussed in 15053. There might be a different approach to this that I haven't considered, so feedback is appreciated.

Copy link
Contributor

@hanhanW hanhanW left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PR is quite large. Can we break it down? E.g., I think at least we could have one PR adding materialization patterns, and the other for set_encoding.

Comment on lines +107 to +111
case EncodingUser::VECMAT:
return chooseEncodingInfoForMatmul(user, role, /*tileParams=*/{1, 4, 8});
case EncodingUser::MATVEC:
case EncodingUser::BATCH_MATVEC:
return chooseEncodingInfoForMatmul(user, role, /*tileParams=*/{8, 4, 1});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This part is mostly for testing. To enable it on CPU backend, you need to add configurations to CPUMaterializeEncodingPass

https://github.com/openxla/iree/blob/3323519bad0f2b91532a8272234034920101709b/compiler/src/iree/compiler/Codegen/Common/CPU/CPUMaterializeEncodingPass.cpp#L47-L148

(I'm sorry about the structure and I will centralize the code)

Comment on lines +220 to +257
switch (user) {
case IREE::LinalgExt::EncodingUser::MATMUL:
opTiled = rewriter
.create<linalg::MatmulOp>(
loc, encodedOut.getType(),
ValueRange{encodedLhs, encodedRhs}, encodedOut)
.getResult(0);
break;

case IREE::LinalgExt::EncodingUser::BATCH_MATMUL:
opTiled = rewriter
.create<linalg::BatchMatmulOp>(
loc, encodedOut.getType(),
ValueRange{encodedLhs, encodedRhs}, encodedOut)
.getResult(0);
break;
case IREE::LinalgExt::EncodingUser::VECMAT:
opTiled = rewriter
.create<linalg::VecmatOp>(
loc, encodedOut.getType(),
ValueRange{encodedLhs, encodedRhs}, encodedOut)
.getResult(0);
break;
case IREE::LinalgExt::EncodingUser::MATVEC:
opTiled = rewriter
.create<linalg::MatvecOp>(
loc, encodedOut.getType(),
ValueRange{encodedLhs, encodedRhs}, encodedOut)
.getResult(0);
break;
case IREE::LinalgExt::EncodingUser::BATCH_MATVEC:
opTiled = rewriter
.create<linalg::BatchMatvecOp>(
loc, encodedOut.getType(),
ValueRange{encodedLhs, encodedRhs}, encodedOut)
.getResult(0);
break;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment on lines +295 to +317
EncodingUser resultUser = resultEncoding.getUser().getValue();
if (!isVecmatEncodingUser(resultUser) && !isMatvecEncodingUser(resultUser) &&
!isMatmulEncodingUser(resultUser) &&
!isBatchMatvecEncodingUser(resultUser) &&
!isBatchMatmulEncodingUser(resultUser)) {
return rewriter.notifyMatchFailure(op, "unsupported encoding type");
}

auto outType = operands[2].getType().cast<RankedTensorType>();

auto loc = op.getLoc();
Operation *resultOp;
if (isBatchMatvecEncodingUser(resultUser) ||
isBatchMatmulEncodingUser(resultUser)) {
resultOp = rewriter.create<linalg::BatchMmt4DOp>(
op.getLoc(), outType, ValueRange{operands[0], operands[1]},
ValueRange{operands[2]});
} else {
resultOp = rewriter.create<linalg::Mmt4DOp>(
op.getLoc(), outType, ValueRange{operands[0], operands[1]},
ValueRange{operands[2]});
}
return resultOp;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we use switch-case here? It's cleaner and easier for maintenance.

return false;
}

int64_t getExpandedDimIndex(EncodingAttr encoding) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please add a doc. What happen if it returns -1?

@bjacob
Copy link
Contributor

bjacob commented Oct 23, 2023

Sorry that I failed to mention this possibility earlier, but:

One simple approach would be to rewrite linalg.matvec by expanding the shape (tensor.expand_shape) of the vector operand, into a linalg.matmul. And likewise for linalg.vecmat. I think the mental barrier that prevented me from suggesting that earlier was I wondered if the inserted tensor.expand_shape ops (or the resulting unit dims) would be unwanted for some reason, but now seeing that the current approach is resulting in a substantial amount of code, I wonder if it's time to give a closer look to the expand_shape approach instead? Sorry again for not bringing this up earlier. OK to carry on with the current approach if there's a significant problem with the expand_shape approach.

@NatashaKnk
Copy link
Contributor Author

@bjacob I think this is on me for not advocating for it a bit harder once I saw the amount of work it took, since I considered it. Where do you think this would fit best, while setting the encoding or elsewhere?

@bjacob
Copy link
Contributor

bjacob commented Oct 23, 2023

@bjacob I think this is on me for not advocating for it a bit harder once I saw the amount of work it took, since I considered it. Where do you think this would fit best, while setting the encoding or elsewhere?

I think it definitely is nice to have it be its own separate pattern+pass -- this is quite generally useful to have, and reviewers tend to like reusable composable patterns that do one thing each. You could initially create it as its own new pattern/pass in GlobalOptimization/ side by side with SetEncoding. Then if a reviewer thinks it belongs elsewhere, that should be easy to move.

@NatashaKnk NatashaKnk closed this Oct 24, 2023
NatashaKnk added a commit that referenced this pull request Oct 25, 2023
…ces to enable tiling (#15273)

As discussed in
[issue#15053](#15053) and
[PR#15257](#15257), expanding the
vectors in vecmat/matvec operations and avoiding them in the encoding
step entirely seems like the best approach.
ramiro050 pushed a commit to ramiro050/iree that referenced this pull request Dec 19, 2023
…ces to enable tiling (iree-org#15273)

As discussed in
[issue#15053](iree-org#15053) and
[PR#15257](iree-org#15257), expanding the
vectors in vecmat/matvec operations and avoiding them in the encoding
step entirely seems like the best approach.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants