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

[SR-7668] testEagerLoop() in crashers.swift crashers in TFLowerGraph.cpp, after supporting TF tensor receives #50208

Closed
rxwei opened this issue May 12, 2018 · 8 comments
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself crash Bug: A crash, i.e., an abnormal termination of software GPE swift for tensorflow

Comments

@rxwei
Copy link
Member

rxwei commented May 12, 2018

Previous ID SR-7668
Radar None
Original Reporter @rxwei
Type Bug
Additional Detail from JIRA
Votes 0
Component/s Swift for TensorFlow
Labels Bug, CompilerCrash, GPE
Assignee jmolloy (JIRA)
Priority Medium

md5: a5410e07461899b5d49b2e6efa8a5836

Issue Description:

Original: https://github.com/google/swift/issues/28

Test case:

public func testEagerLoop() -> Int32 {
  var a = Tensor<Int32>(6)

  // expected-error @+2 {{GraphGen cannot lower a 'receive' from the host yet}}
  var count = Tensor<Int32>(0) // expected-warning {{value implicitly copied to the host}}
  while a.elementsEqual(1).scalar! { // expected-warning 2 {{implicitly copied}} expected-note {{value used here}}
  if (a % 2).elementsEqual(0).scalar! { // expected-warning 2 {{implicitly copied}} expected-note {{value used here}}
    a = a / 2
  } else {
    a = 3 * a + 1
  }
    count += 1
  }
  return count.scalar! // expected-note {{value used here}}
}
F0503 11:47:05.977181   43806 logging.cc:78] assert.h assertion failed at third_party/unsupported_toolchains/swift/src/swift/lib/SILOptimizer/Mandatory/TFLowerGraph.cpp:455 in TF_Output (anonymous namespace)::TFGraphLowering::getOperandValue((anonymous namespace)::SILOpResult): valueInfo.first.oper != nullptr && "didn't find live-in value?"
@swift-ci
Copy link
Collaborator

Comment by James Molloy (JIRA)

This still reproduces at HEAD today. Mingsheng, are you looking at this or are you OK for me to steal it? 🙂

@swift-ci
Copy link
Collaborator

Comment by Mingsheng Hong (JIRA)

James, please feel free to take it. Thanks for the help!

Looks like at the end of TFGraphLowering::visitBuiltinRecvFromHostInst(), we need to call addValueMapping() to map the output of the "__tfop_tfc.RecvFromHost" builtin to a graph node that it constructed, just like in addTFRecvOp().

Happy to support as needed.

@swift-ci
Copy link
Collaborator

Comment by Mingsheng Hong (JIRA)

Correction: We do call addValueMapping() at

addValueMapping({inst, 0}, {dequeueOp, 0});

When debugging another issue with Chris, we found that the hack of early return here based on shouldLowerEffectfulOps is incorrect

https://github.com/apple/swift/blob/553ac93bb98f08adc2f88b2ce76b245a92a7b5ab/lib/SILOptimizer/Mandatory/TFLowerGraph.cpp#L963. When TF needs to recv a value from Swift host within a loop, that recv is currently present in both the loop header and body. In that case we cannot simply do early return when lowering the recv node in the loop header (where

shouldLowerEffectfulOps is set for loop header at https://github.com/apple/swift/blob/553ac93bb98f08adc2f88b2ce76b245a92a7b5ab/lib/SILOptimizer/Mandatory/TFLowerGraph.cpp#L2076),). Instead we'll need to issue an internal error, and wait for proper loop rotation to fix this kind of issues.

That should be the same root cause for the above test case, where the output scalar of
(a % 2).elementsEqual(0).scalar!
, computed on the host, is sent back to TF.

@swift-ci
Copy link
Collaborator

Comment by Mingsheng Hong (JIRA)

#17502 fixed a bug in the current hacky solution – will need to wait for loop rotation to land as a proper fix!

CC jmolloy (JIRA User) bgogul (JIRA User)

@swift-ci
Copy link
Collaborator

Comment by James Molloy (JIRA)

To be clear, I don't think what we need here is classic loop rotation, I think it's a little simpler than that.

Canonical loop form is head-tested:

Preheader
    |
Header <+
    |   |
Latch --+
    |
 Exit

Loop rotated form is tail-tested:

Preheader
 |    |
 |  Header <+
 |    |     |
 |  Latch --+
 |    |
 +> Exit

We want a head-tested loop (While form, not Do-While); we just want the header to contain only the loop test and no other code. We can do this by pushing (and duplicating) all instructions except the condbr from the header into both preheader and latch.

This is a very simple transform that should only be a few lines of code as part of TFCanonicalizeCFG, rather than full-on loop rotation which is a bigger problem.

James

@swift-ci
Copy link
Collaborator

Comment by Gogul Balakrishnan (JIRA)

James, you are right. It does not require full loop rotation. My fix for SR-7765 does exactly as you had suggested—canonicalizes the loop so that only side-effect free operations are in the header.

@swift-ci
Copy link
Collaborator

Comment by Mingsheng Hong (JIRA)

pushing (and duplicating) all instructions except the condbr from the header into both preheader and latch

When the loop condition has a side-effecting op, it seems the above is not sufficient?

e.g. if the code has:

 var a = <some tensor>
 while (A < SomeTensorFromHost()) {
   a += ...
 }
 

Compiler will need to transform the code into:

 var a = <some tensor>
 var cond = A < SomeTensorFromHost()
 while (cond) {
   a += ...
   cond = A < SomeTensorFromHost()
 }

Is this transformation usually referred to as loop rotation?

@swift-ci
Copy link
Collaborator

Comment by James Molloy (JIRA)

Kind of; loop rotation normally involves changing a loop from being head-tested to tail-tested so the loop test can use state calculated in the loop body and only one phi is needed, for the induction variable.

In this case we still want the loop to be head-tested, so it's not loop rotation per se. But that's just semantics (I posted it to explain why we couldn't just use the SIL loop rotation pass that already exists).

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
@AnthonyLatsis AnthonyLatsis added crash Bug: A crash, i.e., an abnormal termination of software compiler The Swift compiler in itself labels Dec 12, 2022
@BradLarson BradLarson closed this as not planned Won't fix, can't repro, duplicate, stale May 23, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself crash Bug: A crash, i.e., an abnormal termination of software GPE swift for tensorflow
Projects
None yet
Development

No branches or pull requests

4 participants