From ebf0b8733e477121ead08b5078b6449471e5c59e Mon Sep 17 00:00:00 2001 From: Michelle Casbon Date: Fri, 3 Jul 2020 18:24:54 +0000 Subject: [PATCH 1/3] Remove rm statement --- Dockerfile | 1 - 1 file changed, 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index baff8f328..fafca5a3f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -77,7 +77,6 @@ RUN /swift-tensorflow-toolchain/usr/bin/swift build -c release WORKDIR /fastai_dev/swift/FastaiNotebook_11_imagenette -RUN rm Package.resolved RUN /swift-tensorflow-toolchain/usr/bin/swift build RUN /swift-tensorflow-toolchain/usr/bin/swift build -c release From 673182c3a8b622027e83930c7130c0b4ecdfb5ed Mon Sep 17 00:00:00 2001 From: Michelle Casbon Date: Fri, 11 Sep 2020 04:12:43 +0000 Subject: [PATCH 2/3] Retrieve device from TFEager libraries --- Sources/x10/swift_bindings/Device.swift | 49 ++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 2 deletions(-) diff --git a/Sources/x10/swift_bindings/Device.swift b/Sources/x10/swift_bindings/Device.swift index 897c311cc..c0f9d9b70 100644 --- a/Sources/x10/swift_bindings/Device.swift +++ b/Sources/x10/swift_bindings/Device.swift @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +import CTensorFlow +import Foundation @_implementationOnly import x10_device_wrapper extension DeviceType { @@ -127,6 +129,8 @@ public struct Device { #endif } + static var defaultOrdinal: Int { 0 } + /// The default `Device`. public static var `default`: Device { switch defaultBackend { @@ -146,8 +150,49 @@ public struct Device { /// The current TF Eager device. public static var defaultTFEager: Device { - // TODO: Pull this from withDevice() {} mechanism? - return Device(kind: .CPU, ordinal: 0, backend: .TF_EAGER) + // Create a dummy tensor on any TFEager device. + var kind: Kind = .CPU + var ordinal = defaultOrdinal + let device = Device(kind: kind, ordinal: defaultOrdinal, backend: .TF_EAGER) + let tensor = Tensor(zeros: [1], on: device) + let handle = tensor.handle._cTensorHandle + let status = TF_NewStatus() + + // Find out what the underlying libraries think the default is. + if let cString = TFE_TensorHandleDeviceName(handle, status) { + checkOk(status) + + // TODO: What's the best way to deallocate this memory? + // defer { DeleteString(str) } + let tfDeviceName = String(cString: cString) + + // Parse type and ordinal from a string with the expected syntax: + // /job:localhost/replica:0/task:0/device:CPU:0 + let pattern = ".+device:(.+):(\\d+)$" + let regex = try! NSRegularExpression(pattern: pattern) + let nsrange = NSRange(tfDeviceName.startIndex..., in: tfDeviceName) + if let match = regex.firstMatch(in: tfDeviceName, range: nsrange) { + if let kindRange = Range(match.range(at: 1), in: tfDeviceName) { + switch String(tfDeviceName[kindRange]).uppercased() { + case "CPU": + kind = .CPU + case "GPU": + kind = .GPU + case "TPU": + kind = .TPU + case "REMOTE_TPU": + kind = .REMOTE_TPU + default: + kind = .CPU + } + } + if let ordinalRange = Range(match.range(at: 2), in: tfDeviceName) { + ordinal = Int(tfDeviceName[ordinalRange]) ?? defaultOrdinal + } + } + } + + return Device(kind: kind, ordinal: ordinal, backend: .TF_EAGER) } /// An array of all devices. From 3547ab1bd69b0d6ac88da5b43897c91514316a25 Mon Sep 17 00:00:00 2001 From: Michelle Casbon Date: Fri, 11 Sep 2020 22:15:53 +0000 Subject: [PATCH 3/3] Move to Tensor.device --- Sources/TensorFlow/Core/Tensor.swift | 36 +++++++++++++++++- Sources/x10/swift_bindings/Device.swift | 49 +------------------------ 2 files changed, 37 insertions(+), 48 deletions(-) diff --git a/Sources/TensorFlow/Core/Tensor.swift b/Sources/TensorFlow/Core/Tensor.swift index 2c45ca7b5..5bb8ad71e 100644 --- a/Sources/TensorFlow/Core/Tensor.swift +++ b/Sources/TensorFlow/Core/Tensor.swift @@ -13,6 +13,7 @@ // limitations under the License. import CTensorFlow +import Foundation import _Differentiation infix operator .==: ComparisonPrecedence @@ -768,7 +769,40 @@ extension Tensor: Differentiable & EuclideanDifferentiable where Scalar: TensorF case .XLA: return xlaTensor.device case .TF_EAGER: - return Device.defaultTFEager + var kind: Device.Kind = .CPU + var ordinal = 0 + let status = _ExecutionContext.global.status + + // Find out what the underlying libraries think the default is. + if let cString = TFE_TensorHandleDeviceName(handle._cTensorHandle, status) { + checkOk(status) + let tfDeviceName = String(cString: cString) + + // Parse type and ordinal from a string with the expected syntax: + // /job:localhost/replica:0/task:0/device:CPU:0 + let pattern = ".+device:(.+):(\\d+)$" + let regex = try! NSRegularExpression(pattern: pattern) + let nsrange = NSRange(tfDeviceName.startIndex..., in: tfDeviceName) + if let match = regex.firstMatch(in: tfDeviceName, range: nsrange) { + if let kindRange = Range(match.range(at: 1), in: tfDeviceName) { + switch String(tfDeviceName[kindRange]).uppercased() { + case "CPU": + kind = .CPU + case "GPU": + kind = .GPU + case "TPU": + kind = .TPU + default: + kind = .CPU + } + } + if let ordinalRange = Range(match.range(at: 2), in: tfDeviceName) { + ordinal = Int(tfDeviceName[ordinalRange]) ?? 0 + } + } + } + + return Device(kind: kind, ordinal: ordinal, backend: .TF_EAGER) } } } diff --git a/Sources/x10/swift_bindings/Device.swift b/Sources/x10/swift_bindings/Device.swift index c0f9d9b70..897c311cc 100644 --- a/Sources/x10/swift_bindings/Device.swift +++ b/Sources/x10/swift_bindings/Device.swift @@ -12,8 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -import CTensorFlow -import Foundation @_implementationOnly import x10_device_wrapper extension DeviceType { @@ -129,8 +127,6 @@ public struct Device { #endif } - static var defaultOrdinal: Int { 0 } - /// The default `Device`. public static var `default`: Device { switch defaultBackend { @@ -150,49 +146,8 @@ public struct Device { /// The current TF Eager device. public static var defaultTFEager: Device { - // Create a dummy tensor on any TFEager device. - var kind: Kind = .CPU - var ordinal = defaultOrdinal - let device = Device(kind: kind, ordinal: defaultOrdinal, backend: .TF_EAGER) - let tensor = Tensor(zeros: [1], on: device) - let handle = tensor.handle._cTensorHandle - let status = TF_NewStatus() - - // Find out what the underlying libraries think the default is. - if let cString = TFE_TensorHandleDeviceName(handle, status) { - checkOk(status) - - // TODO: What's the best way to deallocate this memory? - // defer { DeleteString(str) } - let tfDeviceName = String(cString: cString) - - // Parse type and ordinal from a string with the expected syntax: - // /job:localhost/replica:0/task:0/device:CPU:0 - let pattern = ".+device:(.+):(\\d+)$" - let regex = try! NSRegularExpression(pattern: pattern) - let nsrange = NSRange(tfDeviceName.startIndex..., in: tfDeviceName) - if let match = regex.firstMatch(in: tfDeviceName, range: nsrange) { - if let kindRange = Range(match.range(at: 1), in: tfDeviceName) { - switch String(tfDeviceName[kindRange]).uppercased() { - case "CPU": - kind = .CPU - case "GPU": - kind = .GPU - case "TPU": - kind = .TPU - case "REMOTE_TPU": - kind = .REMOTE_TPU - default: - kind = .CPU - } - } - if let ordinalRange = Range(match.range(at: 2), in: tfDeviceName) { - ordinal = Int(tfDeviceName[ordinalRange]) ?? defaultOrdinal - } - } - } - - return Device(kind: kind, ordinal: ordinal, backend: .TF_EAGER) + // TODO: Pull this from withDevice() {} mechanism? + return Device(kind: .CPU, ordinal: 0, backend: .TF_EAGER) } /// An array of all devices.