Replies: 2 comments 1 reply
-
Beta Was this translation helpful? Give feedback.
-
|
The quick version (at least from the MutualExclusionPass's perspective), since we've accidentally let this sit a while (sorry about that!): if you have an operation on channel X, then an operation on channel Y, and then an operation on channel X again, with a token dependency forcing this order... then you can't merge the two operations on channel X without violating the order guarantee, even if their predicates happen to be mutually exclusive. This analysis/legalization pass enforces that, saying that these operations are not in the same "mergeable class". P.S. ... okay, technically, it could be possible to merge the channel-X operations if we added a restriction that the result must happen simultaneously with the intervening channel-Y operation, which would respect the ordering requirements. We don't currently handle that. Also, the definition of simultaneity could end up making things complicated pretty fast! P.P.S. I'm not sure about the |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Hi!
Out of curiosity I have been digging into a few different parts of the code base and have a super implementation-specific questions about the restriction on "one channel interaction per channel per proc activation".
Baseline
My current understanding is as follows:
XLS can only support one channel interaction per channel per proc activation. From the docs:
Seems logical to me: A send inside a proc pipeline could "trigger" up to once per clock cycle, so if you have multiple sends to the same channel that becomes physically impossible.
This means that once code reaches scheduling, there must be at most be one send per channel.
There are many things done to "hide" this from the user. For example the
mutual_exclusion_passconverts multiple, mutually-exclusive, sends to one channel into a single send with a select.Another example of one such "workaround" is @grebe 's
channel_legalization_passwhich replaces multiple sends to one channel with multiple channels and an arbiter proc.The test
TwoSequentialSendsinmutual_exclusion_pass_testsmatches my expectations from the above. Given this input:The pass is able to reduce the two sends to one:
Question: Why are the mutual exclusion checks not per-channel?
However, I came across the test
TwoSequentialSendsWithInterveningIOinmutual_exclusion_pass_tests, which has the following input:From my understanding above, I would expect the pass to fold the two sends to
test_channeltogether since they are again mutually exclusive. However, the pass does not, and the test verifies that it does not:I played around with this, and
AreStreamingOutputsMutuallyExclusivefrombdd_io_analysisbehaves the same. It reports the first snippet to be mutually exclusive, but not the second snippet.Looking into
bdd_io_analysis, it seems that this is because the mutual exclusion analysis is done on all sends in the proc, instead of all the sends to one channel in one proc. Since there is both a send without predicate and a send with predicate,AreStreamingOutputsMutuallyExclusivedirectly aborts:To my actual question: Why is mutual exclusivity analysis being done once per proc for all sends, instead of for each output channel's set of sends? Why does it matter that there is a send to
other_channel?Is this just a limitation of the mutual exclusivity detection, or are there downstreams problems if cases like the second snippet were allowed?
Cheers!
Beta Was this translation helpful? Give feedback.
All reactions