Skip to content
This repository was archived by the owner on Jul 1, 2023. It is now read-only.

Add two new requirements to TensorArrayProtocol #165

Merged
merged 6 commits into from
Jun 3, 2019

Conversation

bgogul
Copy link
Contributor

@bgogul bgogul commented Jun 1, 2019

This is one of the first steps in addressing https://bugs.swift.org/browse/TF-542. Specifically, this PR introduces two new requirements to TensorArrayProtocol and TensorGroup:

  • init(handles: [_AnyTensorHandle])
  • var _tensorHandles: [_AnyTensorHandle] { get }

This is also necessary for the implementation of LazyTensor.

The Derived conformances for TensorGroup does not address these requirements yet. Therefore, the tests have been changed to conform with TensorGroup explicitly.

@bgogul bgogul requested a review from rxwei June 1, 2019 16:36
@@ -51,6 +53,8 @@ public protocol TensorGroup: TensorArrayProtocol {
/// Initializes a value of this type, taking ownership of the `_tensorHandleCount` tensors
/// starting at address `tensorHandles`.
init(_owning tensorHandles: UnsafePointer<CTensorHandle>?)

init(handles: [_AnyTensorHandle])
Copy link
Contributor

Choose a reason for hiding this comment

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

This change is redundant because TensorGroup inherits from TensorArrayProtocol.

Suggested change
init(handles: [_AnyTensorHandle])

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

}

struct Nested : TensorGroup, Equatable {
// Immutable.
let simple: Simple
// Mutable.
var mixed: Mixed

init(simple: Simple, mixed: Mixed) {
Copy link
Contributor

Choose a reason for hiding this comment

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

This initializer shouldn't be necessary. There's already an implicitly synthesized memberwise initializer.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That is what I thought, but I get the following error, when I don't have these:

[1/2] Compiling TensorFlowTests TensorGroupTests.swift
/usr/local/google/home/bgogul/workspace/brain/s4tf/tensorflow-swift-apis/Tests/TensorFlowTests/TensorGroupTests.swift:173:22: error: cannot invoke initializer for type 'Simple' with an argument list of type '(w: Tensor<Float>, b: Tensor<Float>)'
        let simple = Simple(w: w, b: b)
                     ^
/usr/local/google/home/bgogul/workspace/brain/s4tf/tensorflow-swift-apis/Tests/TensorFlowTests/TensorGroupTests.swift:173:22: note: overloads for 'Simple' exist with these partially matching parameter lists: (_handles: C), (_owning: Optional<UnsafePointer<OpaquePointer>>\
)
        let simple = Simple(w: w, b: b)
                     ^
...

Is it because of the the protocol initializers?

Copy link
Contributor

Choose a reason for hiding this comment

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

Interesting. Yeah, that's probably why.

}

struct Generic<T: TensorGroup & Equatable, U: TensorGroup & Equatable> : TensorGroup, Equatable {
var t: T
var u: U

public init(t: T, u: U) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Same for this memberwise initializer.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

See above.


init(_owning tensorHandles: UnsafePointer<CTensorHandle>?, count: Int)
init(handles: [_AnyTensorHandle])
Copy link
Contributor

@rxwei rxwei Jun 1, 2019

Choose a reason for hiding this comment

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

Requiring the argument to be an Array is not ideal, because in a lot of cases we are creating a tensor group from a slice of an array. Converting a slice to an Array creates an unnecessary copy. Instead, I think this should take a generic RandomAccessCollection.

Also, for consistency with other requirements, it's better for the first argument label of this initializer to start with an underscore.

Suggested change
init(handles: [_AnyTensorHandle])
init<C: RandomAccessCollection>(_handles: C) where C.Element == _AnyTensorHandle

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good point. Done.

}
}

func copyOf<T>(handle: TensorHandle<T>) -> _AnyTensorHandle {
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
func copyOf<T>(handle: TensorHandle<T>) -> _AnyTensorHandle {
func copy<T>(of handle: TensorHandle<T>) -> _AnyTensorHandle {

Copy link
Contributor

@rxwei rxwei Jun 1, 2019

Choose a reason for hiding this comment

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

Random thoughts (since this is a test, naming doesn't matter at all!):

Swift naming conventions recommend that when a verb/noun phrase that the function represents ("copy of handle") contains a prepositional phrase formed with an argument ("of handle"), make the preposition be an argument label. Also, when an argument label merely repeats the type information of the argument, it ("handle") should be omitted.

What do you think of the following?

Suggested change
func copyOf<T>(handle: TensorHandle<T>) -> _AnyTensorHandle {
func copy<T>(of handle: TensorHandle<T>) -> _AnyTensorHandle {

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

@@ -32,8 +32,10 @@ public protocol TensorArrayProtocol {

var _tensorHandleCount: 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.

Should this be changed to Int now?

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 think so, but will do so in a subsequent CL. I have updated https://bugs.swift.org/browse/TF-542 to reflect this.

@@ -145,6 +149,11 @@ public struct ResourceHandle {
init(owning cTensorHandle: CTensorHandle) {
self.handle = TFETensorHandle(_owning: cTensorHandle)
}

@usableFromInline
Copy link
Contributor

Choose a reason for hiding this comment

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

Drop @usableFromInline?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.


public init(handles: [_AnyTensorHandle]) {
let size = handles.count / Int(Element._tensorHandleCount)
self = Array((0..<size).map {
Copy link
Contributor

Choose a reason for hiding this comment

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

The map(_:) method already produces an array. No need to call the array initializer.

Suggested change
self = Array((0..<size).map {
self = (0..<size).map {

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

public init(handles: [_AnyTensorHandle]) {
let size = handles.count / Int(Element._tensorHandleCount)
self = Array((0..<size).map {
let start = $0 * Int(Element._tensorHandleCount)
Copy link
Contributor

Choose a reason for hiding this comment

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

Fix indentation here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

Copy link
Contributor Author

@bgogul bgogul left a comment

Choose a reason for hiding this comment

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

Thanks for the review, @rxwei. I addressed your comments. PTAL.

@@ -32,8 +32,10 @@ public protocol TensorArrayProtocol {

var _tensorHandleCount: Int32 { get }
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 think so, but will do so in a subsequent CL. I have updated https://bugs.swift.org/browse/TF-542 to reflect this.


init(_owning tensorHandles: UnsafePointer<CTensorHandle>?, count: Int)
init(handles: [_AnyTensorHandle])
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good point. Done.

@@ -51,6 +53,8 @@ public protocol TensorGroup: TensorArrayProtocol {
/// Initializes a value of this type, taking ownership of the `_tensorHandleCount` tensors
/// starting at address `tensorHandles`.
init(_owning tensorHandles: UnsafePointer<CTensorHandle>?)

init(handles: [_AnyTensorHandle])
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.


public init(handles: [_AnyTensorHandle]) {
let size = handles.count / Int(Element._tensorHandleCount)
self = Array((0..<size).map {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

public init(handles: [_AnyTensorHandle]) {
let size = handles.count / Int(Element._tensorHandleCount)
self = Array((0..<size).map {
let start = $0 * Int(Element._tensorHandleCount)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

@@ -145,6 +149,11 @@ public struct ResourceHandle {
init(owning cTensorHandle: CTensorHandle) {
self.handle = TFETensorHandle(_owning: cTensorHandle)
}

@usableFromInline
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

}

struct Nested : TensorGroup, Equatable {
// Immutable.
let simple: Simple
// Mutable.
var mixed: Mixed

init(simple: Simple, mixed: Mixed) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

That is what I thought, but I get the following error, when I don't have these:

[1/2] Compiling TensorFlowTests TensorGroupTests.swift
/usr/local/google/home/bgogul/workspace/brain/s4tf/tensorflow-swift-apis/Tests/TensorFlowTests/TensorGroupTests.swift:173:22: error: cannot invoke initializer for type 'Simple' with an argument list of type '(w: Tensor<Float>, b: Tensor<Float>)'
        let simple = Simple(w: w, b: b)
                     ^
/usr/local/google/home/bgogul/workspace/brain/s4tf/tensorflow-swift-apis/Tests/TensorFlowTests/TensorGroupTests.swift:173:22: note: overloads for 'Simple' exist with these partially matching parameter lists: (_handles: C), (_owning: Optional<UnsafePointer<OpaquePointer>>\
)
        let simple = Simple(w: w, b: b)
                     ^
...

Is it because of the the protocol initializers?

}

struct Generic<T: TensorGroup & Equatable, U: TensorGroup & Equatable> : TensorGroup, Equatable {
var t: T
var u: U

public init(t: T, u: U) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

See above.

}
}

func copyOf<T>(handle: TensorHandle<T>) -> _AnyTensorHandle {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

@bgogul bgogul merged commit 738b7a5 into tensorflow:master Jun 3, 2019
@bgogul bgogul deleted the tensor_group_handle branch June 3, 2019 18:29
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.

Looking great!

public init(_owning tensorHandles: UnsafePointer<CTensorHandle>?) {
self.init(handle: TensorHandle(_owning: tensorHandles!.pointee))
}

public init<C: RandomAccessCollection>(
_handles: C) where C.Element == _AnyTensorHandle {
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
_handles: C) where C.Element == _AnyTensorHandle {
_handles: C
) where C.Element == _AnyTensorHandle {

public func _unpackTensorHandles(into address: UnsafeMutablePointer<CTensorHandle>?) {
address!.initialize(to: _cTensorHandle)
}

public init(_owning tensorHandles: UnsafePointer<CTensorHandle>?) {
self.init(owning: tensorHandles!.pointee)
}

public init<C: RandomAccessCollection>(
_handles: C) where C.Element == _AnyTensorHandle {
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
_handles: C) where C.Element == _AnyTensorHandle {
_handles: C
) where C.Element == _AnyTensorHandle {

public func _unpackTensorHandles(into address: UnsafeMutablePointer<CTensorHandle>?) {
address!.initialize(to: _cTensorHandle)
}

public init(_owning tensorHandles: UnsafePointer<CTensorHandle>?) {
self.init(_owning: tensorHandles!.pointee)
}

public init<C: RandomAccessCollection>(
_handles: C) where C.Element == _AnyTensorHandle {
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
_handles: C) where C.Element == _AnyTensorHandle {
_handles: C
) where C.Element == _AnyTensorHandle {

public func _unpackTensorHandles(into address: UnsafeMutablePointer<CTensorHandle>?) {
address!.initialize(to: handle._cTensorHandle)
}

public init(_owning tensorHandles: UnsafePointer<CTensorHandle>?) {
self.init(handle: TensorHandle(_owning: tensorHandles!.pointee))
}

public init<C: RandomAccessCollection>(
_handles: C) where C.Element == _AnyTensorHandle {
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
_handles: C) where C.Element == _AnyTensorHandle {
_handles: C
) where C.Element == _AnyTensorHandle {

public init(_owning tensorHandles: UnsafePointer<CTensorHandle>?) {
self.init(handle: TensorHandle(_owning: tensorHandles!.pointee))
}

public init<C: RandomAccessCollection>(
_handles: C) where C.Element == _AnyTensorHandle {
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
_handles: C) where C.Element == _AnyTensorHandle {
_handles: C
) where C.Element == _AnyTensorHandle {

}

public init<C: RandomAccessCollection>(
_handles: C) where C.Element == _AnyTensorHandle {
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
_handles: C) where C.Element == _AnyTensorHandle {
_handles: C
) where C.Element == _AnyTensorHandle {

}

public init<C: RandomAccessCollection>(
_handles: C) where C.Element == _AnyTensorHandle {
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
_handles: C) where C.Element == _AnyTensorHandle {
_handles: C
) where C.Element == _AnyTensorHandle {

}

public init<C: RandomAccessCollection>(
_handles: C) where C.Element == _AnyTensorHandle {
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
_handles: C) where C.Element == _AnyTensorHandle {
_handles: C
) where C.Element == _AnyTensorHandle {

}

public init<C: RandomAccessCollection>(
_handles: C) where C.Element == _AnyTensorHandle {
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
_handles: C) where C.Element == _AnyTensorHandle {
_handles: C
) where C.Element == _AnyTensorHandle {

}

public init<C: RandomAccessCollection>(
_handles: C) where C.Element == _AnyTensorHandle {
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
_handles: C) where C.Element == _AnyTensorHandle {
_handles: C
) where C.Element == _AnyTensorHandle {

bgogul added a commit to bgogul/swift-apis that referenced this pull request Jun 3, 2019
@bgogul
Copy link
Contributor Author

bgogul commented Jun 3, 2019

Oops, just noticed these messages. Here is a PR to fix the style issues: #170

bgogul added a commit that referenced this pull request Jun 3, 2019
@rxwei rxwei changed the title Add two new requirements to TensorGroup and TensorArrayProtocol Add two new requirements to _TensorArrayProtocol Jun 4, 2019
@rxwei rxwei changed the title Add two new requirements to _TensorArrayProtocol Add two new requirements to TensorArrayProtocol Jun 4, 2019
rxwei added a commit to rxwei/swift that referenced this pull request Jun 4, 2019
`TensorArrayProtocol` and `TensorGroup` have been [moved](tensorflow/swift-apis#139) to [tensorflow/swift-apis](https://github.com/tensorflow/swift-apis), and their derived conformances tests have been [copied](tensorflow/swift-apis#158) there as well. [tensorflow/swift-apis#165](tensorflow/swift-apis#165) changed the protocol requirements which made `TensorGroup` conformances no longer entirely derivable, but the derived conformances tests in this repo have not been updated, and it's blocking us from updating the checkout hash for tensorflow/swift-apis.

This PR removes `TensorGroup` derived conformance tests from apple/swift. We expect future changes to `TensorGroup` derived conformances to thoroughly test against tensorflow/swift-apis.
rxwei added a commit to swiftlang/swift that referenced this pull request Jun 4, 2019
`TensorArrayProtocol` and `TensorGroup` have been [moved](tensorflow/swift-apis#139) to [tensorflow/swift-apis](https://github.com/tensorflow/swift-apis), and their derived conformances tests have been [copied](tensorflow/swift-apis#158) there as well. [tensorflow/swift-apis#165](tensorflow/swift-apis#165) changed the protocol requirements which made `TensorGroup` conformances no longer entirely derivable, but the derived conformances tests in this repo have not been updated, and it's blocking us from updating the checkout hash for tensorflow/swift-apis.

This PR removes `TensorGroup` derived conformance tests from apple/swift. We expect future changes to `TensorGroup` derived conformances to thoroughly test against tensorflow/swift-apis.

Unblocks #25235.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants