-
Notifications
You must be signed in to change notification settings - Fork 366
[SSP] Separate ResourceType
from OperatorType
#8444
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
Conversation
// Nothing else to check if no linked resource type is set for `opOp`, | ||
// because the operation doesn't carry a `LinkedResourceTypeAttr`, or that | ||
// class is not part of the `OperationPropertyTs` to load. | ||
if (!prob.getLinkedResourceType(opOp).has_value()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is logic duplication between checking OperatorType
and ResourceType
here, we can refactor it by making a helper function if the reviewers think the current draft-y implementation looks good.
P.S. we have not supported adding multiple, heterogeneous |
To provide some additional context to other reviewers, the ability to have multiple resource types per operation is absolutely essential for practical HLS. |
ec9a108
to
ff0e9cc
Compare
Thanks for the review, @andrewb1999 ! I have addressed the feedback you gave. Moreover, we can now associate multiple resource types to a single operation now! |
One more minor comment, but overall LGTM. I think it would be good if someone who has worked on the scheduling codebase more recently could give some feedback as well before merging. |
@7FM maybe? I'll have a look on Tuesday (not at my desk currently). |
Thank you for your review @andrewb1999 ! I will change it accordingly
If you could take a look, that'll be awesome @jopperm I'd really appreciate your input :) |
I just skimmed over the changes, LGTM so far. I am a huge fan of a clear separation between operator types and resources (especially being able to assign multiple resources to an operation)! This will certainly clean up my downstream resource sharing code base. The only thing I was wondering about while skimming the change was the purpose of adding wrapper structs for StringAttr as Operator/ResourceType: https://github.com/llvm/circt/pull/8444/files#diff-0db8e1c62706227aae263d37b3263f7c010ca77640a1329f3980bf83e1379f3aR98-R140 Right now, this does not seem to add functionality, but adds some boilerplate. Could you give a rationale for adding them? Is it to provide a common interface for Resource- and OperatorTypes to simplify changing the underlying classes for downstream users? (I don't think I have tried/needed this yet, but maybe you could give an example use case if that was indeed the intent) |
fabb15d
to
7abff07
Compare
Re.:
You are right, right now, my focus is to make sure the smooth transition from using Re.:
Yes, there is a rationale:
Please let me know if you have any question. Thanks for your review and feedback, it's really helpful :) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for working on this -- I agree this will be super useful and looks very neat already.
Have you considered tying the resources to the operator types instead of the operations?
@@ -124,6 +130,44 @@ def OperatorLibraryOp : SSPOp<"library", | |||
]; | |||
} | |||
|
|||
def ResourceLibraryOp : SSPOp<"resource", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have you considered using just one shared container for operator types and resources?
Sorry for the late reply, I got seriously blocked by something over the week. I did not consider until you ask, and I think this is a really good question. Here is what I think after some pondering, and I will answer the question below together since I think you are trying to probe the same thing?
My understanding is I feel like separating them both conception-wise and implementation-wise/container-wise is more neat, because operator types represents what an operation does and resource types tells us where or how the operation is being run. Since there will be the same operator using different resource types, or the same resource type is shared across operators, combing the operator type and resource type container altogether will lead to duplicate resource declaration in different containers. And correct me if I'm wrong, if we tie resource types to the operator type (by which I understand your proposal as instead of putting operation in the first hierarchy and both resource/operator type on the second hierarchy, tying resource types to operator types means that resource type will be on the third hierarchy?), then resource types cannot be shared across problems. Thanks again for your review and valuable insight @jopperm and please let me know if there's any further concern :) |
…hat we can associate different kinds of resource to an operation
7abff07
to
a8f44d7
Compare
Thanks for clarifying!
I think that's the point I didn't consider initially. Then it makes sense to set operator type and resources separately per operation. What's your canonical example for this? Something like "memory read port" as the operator type, and "memory_XYZ" as the resource? |
Yeah something like that, I was thinking to have |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
Can you please update the documentation in a follow-up PR as well, please?
|
||
auto &rsrcs = *maybeRsrcs; | ||
assert(rsrcs.size() == 1 && | ||
"Multi-resource operations are not yet supported by this scheduler"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please address this in a follow-up PR. We should have at least one complete, reference scheduler implementation for each problem defined in-tree. 🙏
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, no problem - this is actually an already ongoing patch!
Sure, will do! |
Merging the PR, thanks folks again for taking your time to review! 🙏 |
* We separate 'resource' as a standalone concept from 'operator type' so that we can associate different kinds of resource to an operation. * The test cases are modified to reflect the new changes accordingly. * Similar to operators, resources are also printed as the first class in operations.
This patch separates the concept of
ResourceType
fromOperatorType
, so that we can associate different kinds of resources and their constraints to a single operation.Being able to have zero, one, or multiple resource types to an operation is useful because it enables to do scheduling easily with operations like fused multiply add where it requires a multipler resource as well as an adder resource. It will also be useful to do scheduling analysis for
if-else
statement more effectively - instead of conservatively to combine the resource constraint of both thetrue
andfalse
branches, we can now only analyze thetrue
andfalse
branch separately.