Skip to content

Break TensorGroup into InputTensorGroup and OutputTensorGroup. #20188

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

Merged
merged 1 commit into from
Nov 1, 2018

Conversation

pschuh
Copy link
Contributor

@pschuh pschuh commented Oct 31, 2018

This allows array to conform to InputTensorGroup and participate as an input to a #tfop.

@pschuh pschuh requested review from mhong and marcrasi and removed request for mhong October 31, 2018 18:29
@pschuh
Copy link
Contributor Author

pschuh commented Oct 31, 2018

@swift-ci please test tensorflow

Copy link

@marcrasi marcrasi left a comment

Choose a reason for hiding this comment

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

Yay!

Could you also add a test that exercises this?

auto conformance = tfModule->lookupConformance(canType,
tensorGroupProto);
auto conformance =
tfModule->lookupConformance(canType, outputTensorGroupProto);
assert(conformance && "out type does not conform to TensorGroup");

Choose a reason for hiding this comment

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

s/TensorGroup/OutputTensorGroup/

@pschuh
Copy link
Contributor Author

pschuh commented Oct 31, 2018

@swift-ci please test tensorflow

@pschuh
Copy link
Contributor Author

pschuh commented Nov 1, 2018

Updated with fixes.

@pschuh
Copy link
Contributor Author

pschuh commented Nov 1, 2018

@swift-ci please test tensorflow

@@ -2060,7 +2063,7 @@ void IRGenSILFunction::visitGraphOperationInst(GraphOperationInst *i) {
// TODO: We should also handle the following cases:
Copy link

Choose a reason for hiding this comment

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

Ooo, you can remove this whole TODO now!


// Test packing dynamic arrays.
TensorGroupTest.testAllBackends("input, array") {
some_tf_op(n: 32);
Copy link

Choose a reason for hiding this comment

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

No semicolon needed

let ret: TensorHandle<Float> = #tfop("Pack",
[arr], T$dtype: Float.tensorFlowDataType, axis: 0)
let t: Tensor<Float> = Tensor<Float>(shape: [Int32(n), 3], scalars: arr_exp)
expectEqual(Tensor<Float>(handle: ret).array, t.array)
Copy link

Choose a reason for hiding this comment

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

Our convention is to have the expected value first.

Also you can simplify this by making the expected ShapedArray directly with ShapedArray(shape: scalars:) instead of making a tensor and converting it to array.

arr_exp.insert(contentsOf: [Float(i), 2, 3], at: arr_exp.count)
}

let ret: TensorHandle<Float> = #tfop("Pack",
Copy link

Choose a reason for hiding this comment

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

You should be able to do let ret: Tensor<Float> to avoid having to construct the Tensor yourself. This may require my very latest change that I submitted just about an hour ago.


/// This protocol is divided from OutputTensorGroup in order for the number of
/// tensors to be determined at runtime. For example, Array<Tensor<Float>> may
/// have an unknown number of elements at runtime.
Copy link

Choose a reason for hiding this comment

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

s/runtime/compile time/

@marcrasi
Copy link

marcrasi commented Nov 1, 2018

Thanks for the updates! I re-reviewed it.

Is swift-ci still not listening to you? Let me know if you want me to trigger it.

@marcrasi
Copy link

marcrasi commented Nov 1, 2018

Also, my conflicting PR is submitted now so expect a few conflicts. Let me know if you want help resolving them. Sorry :)

@pschuh pschuh force-pushed the 3 branch 2 times, most recently from 610c44c to 4252736 Compare November 1, 2018 00:56
@pschuh
Copy link
Contributor Author

pschuh commented Nov 1, 2018

All good now.

@pschuh pschuh force-pushed the 3 branch 2 times, most recently from 5871232 to ee3dd73 Compare November 1, 2018 01:13
@marcrasi
Copy link

marcrasi commented Nov 1, 2018

@swift-ci please test tensorflow

1 similar comment
@marcrasi
Copy link

marcrasi commented Nov 1, 2018

@swift-ci please test tensorflow

This allows array to conform to InputTensorGroup and participate
as an input to a #tfop.
@marcrasi
Copy link

marcrasi commented Nov 1, 2018

@swift-ci please test tensorflow

1 similar comment
@marcrasi
Copy link

marcrasi commented Nov 1, 2018

@swift-ci please test tensorflow

@marcrasi
Copy link

marcrasi commented Nov 1, 2018

@swift-ci please test tensorflow

@pschuh pschuh merged commit c605516 into swiftlang:tensorflow Nov 1, 2018
Copy link
Contributor

@rxwei rxwei left a comment

Choose a reason for hiding this comment

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

Left some comments.

First, I'd like to see some justification on the naming choice. This is user-visible API, meaning that the user has to understand what "input" and "output" are. As far as I can tell, much of this change has been implementation-driven, leaking compiler-specific information to the user space. I believe there are better names, and potentially better solutions to this problem. Why such a hurry in landing this patch?

Second, public API changes are expected to go through a discussion with the owner of API design and Swift readability at a minimum.

ptr = ptr!.advanced(by: Int(elem._inputTensorHandleCount))
}
}
public var _inputTensorHandleCount : Int32 { get {
Copy link
Contributor

Choose a reason for hiding this comment

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

Please reformat this as the following:

public var _inputTensorHandleCount : Int32 {
  get {
    ...
  }
}

Copy link

Choose a reason for hiding this comment

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

Would it be even better to do it without the get, like this?

public var _inputTensorHandleCount: Int32 {
  return ...
}

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes it definitely would. I didn't notice there's no set or there's no special attributes on get.

ptr = ptr!.advanced(by: Int(elem._inputTensorHandleCount))
}
}
public var _inputTensorHandleCount : Int32 { get {
Copy link
Contributor

Choose a reason for hiding this comment

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

Please remove space before :.

return [Scalar.tensorFlowDataType]
}

public var _inputTensorHandleCount : Int32 {
Copy link
Contributor

Choose a reason for hiding this comment

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

Please remove the space before :.

return [Scalar.tensorFlowDataType]
}

public var _inputTensorHandleCount : Int32 {
Copy link
Contributor

Choose a reason for hiding this comment

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

Please remove the space before :.

return [TensorDataType(TF_VARIANT)]
}

public var _inputTensorHandleCount : Int32 {
Copy link
Contributor

Choose a reason for hiding this comment

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

Please remove the space before :.

return [TensorDataType(TF_RESOURCE)]
}

public var _inputTensorHandleCount : Int32 {
Copy link
Contributor

Choose a reason for hiding this comment

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

Please remove the space before :.

return [Scalar.tensorFlowDataType]
}

public var _inputTensorHandleCount : Int32 {
Copy link
Contributor

Choose a reason for hiding this comment

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

Please remove the space before :.

///
/// TODO: Add a derived conformance to TensorGroup so that users don't have
/// to write the conformance themselves.
public protocol TensorGroup : InputTensorGroup & OutputTensorGroup {}
Copy link
Contributor

Choose a reason for hiding this comment

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

This is not idiomatic. Please change this to a typealias instead.

public typealias TensorGroup = InoutTensorGroup & OutputTensorGroup

/// The types of the tensor stored properties in this type.
static var _typeList: [TensorDataType] { get }

/// This protocol is divided from OutputTensorGroup in order for the number of
Copy link
Contributor

Choose a reason for hiding this comment

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

This is not valid Swift API doc comment because it's implementation-specific, not something the user is expected to understand. If you wanted it to be seen the library implementer, please use double slashes.

/// tensor operation as an input list whose elements are the tensor fields of
/// the type. When a TensorGroup is used as an output, it gets initialized
/// with its tensor fields set to the tensor operation's tensor outputs.
/// A protocol for types that can be used as tensor operation inputs. When a
Copy link
Contributor

Choose a reason for hiding this comment

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

"tensor operation inputs" in an implementation-specific comment. It does not have a meaning to the user.

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