Skip to content

Conversation

@mhong
Copy link

@mhong mhong commented Jan 24, 2019

These tensors become additional input tensors to feed into the generated trace
graph function. For example, if the tracee is:

func foo(x: TensorPair<Float, Float>) -> Tensor<Float> {
  let y = Tensor<Float>(1.0)
  return x.first + x.second + y
}

Then the generated trace graph function has 3 input tensors: x.first,
x.second, and y, where y is the additional input.

…n tracee.

These tensors become additional input tensors to feed into the generated trace
graph function. For example, if the tracee is:
```swift
func foo(x: TensorPair) -> Tensor {
  let y = Tensor<1.0>
  return x.first + x.second + y
}
```

Then the generated trace graph function has 3 input tensors: `x.first`,
`x.second`, and `y`, where `y` is the additional input.
@mhong
Copy link
Author

mhong commented Jan 24, 2019

@swift-ci please test tensorflow

@mhong mhong requested review from bgogul, pschuh and rxwei January 24, 2019 23:54
@mhong
Copy link
Author

mhong commented Jan 24, 2019

Also cc @jekbradbury as FYI

@rxwei
Copy link
Contributor

rxwei commented Jan 24, 2019

let y = Tensor<1.0>

Did you mean Tensor<Float>(1.0)? :)

@mhong
Copy link
Author

mhong commented Jan 25, 2019

Good catch. :) Fixed.

/// The number of additional input tensors to the trace graph function,
/// created from concrete intermediate tensors in the tracee, such as `y` in
/// the code snippet above.
var additionalInputTensorCount: Int32 = -1
Copy link
Contributor

Choose a reason for hiding this comment

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

Is there a reason why the initial value is -1?

Copy link
Author

Choose a reason for hiding this comment

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

This increases the chance of catching bugs (since -1 is never valid), if we forget to set it to some legal value.

Copy link
Contributor

Choose a reason for hiding this comment

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

I see where you are coming from, however, there's a safer way to do that in Swift -- since you expect additionalInputTensorCount to always be set during class initialization, removing the default value makes you able to catch initialization bugs at compile-time. When you forget to set it in init, Swift gives you a compile-time error saying "member is not initialized", which is significantly better than catching this at runtime.

// x) is symbolic. The second one for y is concrete, and is computed at
// trace creation time, not trace execution time.
// Also see the comment block above finalizeAndExecuteTraceFn().
for (i, output) in outputs.enumerated() {
Copy link
Contributor

@rxwei rxwei Jan 25, 2019

Choose a reason for hiding this comment

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

Suggested change
for (i, output) in outputs.enumerated() {
for (i, output) in outputs.enumerated() where TFE_TensorHandleIsConcrete(output) == 0 {

Copy link
Author

Choose a reason for hiding this comment

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

Nice! Done.

// trace creation time, not trace execution time.
// Also see the comment block above finalizeAndExecuteTraceFn().
for (i, output) in outputs.enumerated() {
if TFE_TensorHandleIsConcrete(output) != 0 {
Copy link
Contributor

Choose a reason for hiding this comment

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

The TF_GraphToFunction call below sets the number of outputs to symbolicOutputs.count. As far as I understand symbolicOutputs.count <= outputs.count after this PR. Should TF_GraphToFunction have outputs.count for the number of outputs?

Copy link
Contributor

Choose a reason for hiding this comment

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

I think I understand it now. Basically, the concrete outputs are captured and returned by the _graph function and don't have to be part of the TFFunction outputs.

// For example, let the tracee be:
// func foo(x: Tensor) -> (Tensor, Tensor) {
// let y = Tensor<Float>(1.0)
// return (x + x, y)
Copy link
Contributor

Choose a reason for hiding this comment

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

The test added here does not exercise this scenario?

Copy link
Author

Choose a reason for hiding this comment

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

Discussed in person, and TracerTests.testAllBackends("Basic_IntermediateTensors") should cover this case.

@mhong
Copy link
Author

mhong commented Jan 25, 2019

@swift-ci please test tensorflow

/// The number of additional input tensors to the trace graph function,
/// created from concrete intermediate tensors in the tracee, such as `y` in
/// the code snippet above.
var additionalInputTensorCount: Int32 = -1
Copy link
Contributor

Choose a reason for hiding this comment

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

I see where you are coming from, however, there's a safer way to do that in Swift -- since you expect additionalInputTensorCount to always be set during class initialization, removing the default value makes you able to catch initialization bugs at compile-time. When you forget to set it in init, Swift gives you a compile-time error saying "member is not initialized", which is significantly better than catching this at runtime.

cTraceContext)
for i in 0..<additionalInputTensorCount {
symbolicInputs.append(TFE_GetInputGraphNodeFromTraceContext(
cTraceContext, UInt32(i)))
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
cTraceContext, UInt32(i)))
cTraceContext, UInt32(i)))

Copy link
Author

Choose a reason for hiding this comment

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

cTraceContext is indented two spaces after the pervious line on TFE_GetInputGraphNodeFromTraceContext( -- I believe that's the correct indentation?

Copy link
Contributor

Choose a reason for hiding this comment

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

Oh, I misread.

debugLog("Running tracee in tracing mode.")
// The tracee output can contain a mixture of symbolic and concrete tensors
// (see the comment block within TraceContext.finalize()).
debugLog("Running tracee in tracing mode.")
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
debugLog("Running tracee in tracing mode.")
debugLog("Running tracee in tracing mode.")

Copy link
Author

Choose a reason for hiding this comment

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

Good catch, thanks!

@rxwei
Copy link
Contributor

rxwei commented Jan 27, 2019

func foo(x: TensorPair) -> Tensor {
 let y = Tensor<Float>(1.0)
 return x.first + x.second + y
}

Nit: TensorPair is a generic type. It'd be clearer to show a program that actually compiles in the PR description.

func foo(x: TensorPair<Float, Float>) -> Tensor<Float> {
  let y = Tensor<Float>(1.0)
  return x.first + x.second + y
}

@mhong
Copy link
Author

mhong commented Jan 28, 2019

@rxwei: On additionalInputTensorCount, it's not initialized at init(), but at finalize(). So unfortunately we cannot rely on the "definitive initialization" feature in Swift.

@rxwei
Copy link
Contributor

rxwei commented Jan 28, 2019

Ah, I misread the diff. I thought it was in init(). This SGTM!

@mhong
Copy link
Author

mhong commented Jan 28, 2019

Thanks all for the review! Submitting this patch. Happy to address any follow-up comments.

@mhong mhong merged commit e4d1eba into swiftlang:tensorflow Jan 28, 2019
@mhong mhong deleted the trace3_intermediate_tensors branch January 28, 2019 22:39
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