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

[XLA] Add simple HLO if conversion pass #22974

Merged
merged 2 commits into from Mar 18, 2019

Conversation

Keno
Copy link
Contributor

@Keno Keno commented Oct 14, 2018

kConditional operations are currently generally disallowed in parallel contexts
(e.g. in mapped computations). The julia XLA frontend was running into this limitation
quite a bit, because existing julia code tends to use the terniary operator for select,
e.g. to describe the derivative of a max call (and thus a relu) - see the
definitions of the derivatives of max at
https://github.com/JuliaDiff/DiffRules.jl/blob/master/src/rules.jl#L94

To support these sorts of patterns, add a simple if conversion pass that converts
conditionals in parallel context by equivalent select operations (which are well supported),
i.e. a computation like:

if {
 %pif = () parameter(0)
 ROOT %cif = f32[] constant(0)
}

else {
 %pelse = () parameter(0)
 ROOT %celse = f32[] constant(1)
}

mapped {
 %a = f32[] parameter(0)
 %b = f32[] parameter(1)
 %lt = pred[] less-than(%a, %b)
 %t = () tuple()
 ROOT %conditional = f32[] conditional(%lt, %t, %t), true_computation=if, false_computation=else
}

ENTRY comp {
 %p1 = f32[1000]{0} parameter(0)
 %p2 = f32[1000]{0} parameter(1)
 ROOT %mapped = f32[1000]{0} map(%p1, %p2), dimensions={0}, to_apply=mapped
}

gets rewritten to

mapped {
 %a = f32[] parameter(0)
 %b = f32[] parameter(1)
 %cif = f32[] constant(0)
 %celse = f32[] constant(1)
 %lt = pred[] less-than(%a, %b)
 ROOT %select = f32[] select(%lt, %cif, %celse)
}

ENTRY comp {
 %p1 = f32[1000]{0} parameter(0)
 %p2 = f32[1000]{0} parameter(1)
 ROOT %mapped = f32[1000]{0} map(%p1, %p2) dimensions={0} to_apply=mapped
}

To keep things simple, this is accomplished by first rewriting the conditional
to two calls and a select and then inlining the individual calls. Naturally,
the transformation is only applied if the called computation do not
have side effects (which they generally don't if they're in parallel
context). In the future, it would be good to let MapInliner further
simplify this to an implicitly mapped select.

@drpngx drpngx requested a review from sanjoy October 15, 2018 17:32
@drpngx drpngx added the awaiting review Pull request awaiting review label Oct 15, 2018

namespace xla {

StatusOr<bool> DoConditionalToSelect(HloInstruction* conditional) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Please either make this static or put in an anonymous namespace.

StatusOr<bool> DoConditionalToSelect(HloInstruction* conditional) {
// Only allow conditional to select if the called computations
// do not have side effects.
for (HloComputation* computation : conditional->called_computations()) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Up to you, but I think conditional->true_computation()->HasSideEffects() || conditional->false_computation()->HasSideEffects() looks a bit cleaner.

conditional->false_computation()));
HloInstruction* select_op =
computation->AddInstruction(HloInstruction::CreateTernary(
conditional->shape(), HloOpcode::kSelect,
Copy link
Contributor

Choose a reason for hiding this comment

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

I suspect this may need to be a kTupleSelect if conditional->shape() is a tuple.

Copy link
Contributor

Choose a reason for hiding this comment

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

Also, I think we need to broadcast the condition when creating the select if conditional->shape() is not a scalar.

TF_RETURN_IF_ERROR(
call_graph->VisitNodes([&](const CallGraphNode& node) -> Status {
std::vector<HloInstruction*> ToInline;
if (node.context() != CallContext::kParallel) return Status::OK();
Copy link
Contributor

Choose a reason for hiding this comment

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

We prefer using braces even for single statement if and for.

@Keno
Copy link
Contributor Author

Keno commented Oct 16, 2018

Feedback addressed.

sanjoy
sanjoy previously approved these changes Oct 16, 2018
namespace xla {

// A pass which transforms conditionals to selects in places where conditionals
// are not allowed to appear (e.g. mapped computation)
Copy link
Contributor

Choose a reason for hiding this comment

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

Just to be clear, this is a backend constraint right (that we can't codegen this) not a general constraint (i.e. the un-transformed IR still passes the verifier)? If yes, would be nice to note explicitly.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It passes the verifier, but fails in buffer assignment. The backend folks would have to say what the long term plan here is.

Copy link
Contributor

Choose a reason for hiding this comment

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

Ok, can you instead s/not allowed/legal but not supported/ or something like that? I don't want folks to get misled by this comment about what HLO is allowed.

@tensorflowbutler tensorflowbutler removed the awaiting review Pull request awaiting review label Oct 17, 2018
@ymodak ymodak self-assigned this Oct 18, 2018
@ymodak ymodak added the kokoro:force-run Tests on submitted change label Oct 23, 2018
@kokoro-team kokoro-team removed the kokoro:force-run Tests on submitted change label Oct 23, 2018
@kokoro-team kokoro-team removed the kokoro:force-run Tests on submitted change label Oct 23, 2018
@Keno
Copy link
Contributor Author

Keno commented Oct 24, 2018

Looks like there's some whitespace issues with my BUILD changes? Should I update the PR to fix that or do you want to do that as part of the merge?

@sanjoy
Copy link
Contributor

sanjoy commented Oct 24, 2018

Hi Keno,

It'd be great if you could fix it on the PR itself; I believe the error message has a diff? If you run into any unforeseen issues let me know and I'll send you a buildified BUILD file.

@Keno
Copy link
Contributor Author

Keno commented Oct 25, 2018

Alright. Let's try that. I assume you'll have to re-trigger CI since that doesn't seem to run automatically.

@sanjoy sanjoy added the kokoro:force-run Tests on submitted change label Oct 25, 2018
@kokoro-team kokoro-team removed the kokoro:force-run Tests on submitted change label Oct 25, 2018
@Keno
Copy link
Contributor Author

Keno commented Nov 5, 2018

bump

Keno added a commit to Keno/DiffRules.jl that referenced this pull request Nov 5, 2018
@sanjoy sanjoy added the kokoro:force-run Tests on submitted change label Nov 5, 2018
@kokoro-team kokoro-team removed the kokoro:force-run Tests on submitted change label Nov 5, 2018
Copy link
Contributor

@sanjoy sanjoy left a comment

Choose a reason for hiding this comment

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

lgtm with comments addressed but not actually lgtm'ing since I'm not sure if the code will be auto merged automatically without giving you time to address the comments.

namespace xla {

// A pass which transforms conditionals to selects in places where conditionals
// are not allowed to appear (e.g. mapped computation)
Copy link
Contributor

Choose a reason for hiding this comment

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

Ok, can you instead s/not allowed/legal but not supported/ or something like that? I don't want folks to get misled by this comment about what HLO is allowed.

// which expects the condition to be a scalar.
if (!ShapeUtil::IsScalar(conditional->shape()) &&
!ShapeUtil::IsTuple(conditional->shape())) {
condition = computation->AddInstruction(HloInstruction::CreateBroadcast(
Copy link
Contributor

Choose a reason for hiding this comment

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

This can be a new utility in tensorflow/compiler/xla/service/hlo_creation_utils.h

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I see that it already has MakeSelectHlo. In principle that could be expanded do do this whole rigamarole. Should I do that? Or should I create a separate function?

Copy link
Contributor

Choose a reason for hiding this comment

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

Making the existing switch between select and triple-select sgtm.

@Keno
Copy link
Contributor Author

Keno commented Nov 5, 2018

I've addressed those two comments. @davidel had some thoughts on the split of work here between HLO and the backend, but I think the conclusion ended up being that while we should fix this in the backend also, the HLO-level pass in nevertheless useful.

sanjoy
sanjoy previously approved these changes Nov 20, 2018
@ymodak ymodak added the kokoro:force-run Tests on submitted change label Nov 20, 2018
@ymodak ymodak added the kokoro:force-run Tests on submitted change label Feb 13, 2019
@sanjoy
Copy link
Contributor

sanjoy commented Feb 13, 2019

@ymodak I'm happy to manually pull in the CL to Google and check it in (and resolve the merge conflicts internally). However it is missing the [ready to pull] label -- can I just add that label directly?

@ymodak ymodak added ready to pull PR ready for merge process and removed ready to pull PR ready for merge process labels Feb 13, 2019
@tensorflowbutler tensorflowbutler removed the stat:awaiting response Status - Awaiting response from author label Feb 15, 2019
@ymodak ymodak added ready to pull PR ready for merge process and removed ready to pull PR ready for merge process kokoro:force-run Tests on submitted change labels Feb 19, 2019
@yifeif
Copy link
Contributor

yifeif commented Feb 27, 2019

@Keno do you mind resolving the conflicts? Thank you!

@Keno
Copy link
Contributor Author

Keno commented Feb 27, 2019

I was under the impression @sanjoy would do that on import

@sanjoy
Copy link
Contributor

sanjoy commented Feb 27, 2019

I was under the impression @sanjoy would do that on import

I tried to do that but it seems like we don't have a way to pull in a change with conflicts into piper (so that I can later resolve the conflicts). @yifeif - is that accurate?

@rthadur
Copy link
Contributor

rthadur commented Mar 13, 2019

@Keno @sanjoy @yifeif any updates on resolving conflicts ?

@Keno
Copy link
Contributor Author

Keno commented Mar 13, 2019

Let me just do it. Sounds like that's easiest.

@rthadur
Copy link
Contributor

rthadur commented Mar 13, 2019

Let me just do it. Sounds like that's easiest.

thank you

PR Queue automation moved this from Approved by Reviewer to Reviewer Requested Changes Mar 16, 2019
PR Queue automation moved this from Reviewer Requested Changes to Approved by Reviewer Mar 16, 2019
@rthadur rthadur assigned rthadur and unassigned ymodak Mar 18, 2019
@rthadur rthadur added kokoro:force-run Tests on submitted change ready to pull PR ready for merge process and removed ready to pull PR ready for merge process labels Mar 18, 2019
@kokoro-team kokoro-team removed the kokoro:force-run Tests on submitted change label Mar 18, 2019
@tensorflow-copybara tensorflow-copybara merged commit 7026001 into tensorflow:master Mar 18, 2019
PR Queue automation moved this from Approved by Reviewer to Merged Mar 18, 2019
tensorflow-copybara pushed a commit that referenced this pull request Mar 18, 2019
@Keno
Copy link
Contributor Author

Keno commented Mar 20, 2019

Thanks, @sanjoy.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cla: yes ready to pull PR ready for merge process size:L CL Change Size: Large
Projects
PR Queue
  
Merged
Development

Successfully merging this pull request may close these issues.

None yet

10 participants