Browse Source

TensorHandleDevices

tags/v0.20
Oceania2018 5 years ago
parent
commit
88d0e968ce
15 changed files with 214 additions and 33 deletions
  1. +0
    -18
      TensorFlow.NET.sln
  2. +1
    -1
      src/TensorFlowNET.Core/APIs/tf.math.cs
  3. +13
    -0
      src/TensorFlowNET.Core/Binding.Util.cs
  4. +23
    -1
      src/TensorFlowNET.Core/Device/c_api.device.cs
  5. +22
    -0
      src/TensorFlowNET.Core/Eager/c_api.eager.cs
  6. +9
    -2
      src/TensorFlowNET.Core/Eager/pywrap_tfe_src.cs
  7. +32
    -7
      src/TensorFlowNET.Core/Operations/gen_math_ops.cs
  8. +16
    -0
      src/TensorFlowNET.Core/Operations/math_ops.cs
  9. +1
    -1
      src/TensorFlowNET.Core/Tensors/Tensor.Operators.cs
  10. +3
    -0
      src/TensorFlowNET.Core/ops.cs
  11. +24
    -0
      test/TensorFlowNET.UnitTest/CApiTest.cs
  12. +1
    -1
      test/TensorFlowNET.UnitTest/Eager/CApi.Eager.Context.cs
  13. +43
    -0
      test/TensorFlowNET.UnitTest/Eager/CApi.Eager.TensorHandleDevices.cs
  14. +25
    -0
      test/TensorFlowNET.UnitTest/Eager/CApi.Eager.cs
  15. +1
    -2
      test/TensorFlowNET.UnitTest/Tensorflow.UnitTest.csproj

+ 0
- 18
TensorFlow.NET.sln View File

@@ -13,8 +13,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tensorflow.Keras", "src\Ten
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tensorflow.Keras.UnitTest", "test\Tensorflow.Keras.UnitTest\Tensorflow.Keras.UnitTest.csproj", "{EB92DD90-6346-41FB-B967-2B33A860AD98}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tensorflow.Hub", "src\TensorFlowNET.Hub\Tensorflow.Hub.csproj", "{95B077C1-E21B-486F-8BDD-1C902FE687AB}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -107,22 +105,6 @@ Global
{EB92DD90-6346-41FB-B967-2B33A860AD98}.Release|Any CPU.Build.0 = Release|Any CPU
{EB92DD90-6346-41FB-B967-2B33A860AD98}.Release|x64.ActiveCfg = Release|Any CPU
{EB92DD90-6346-41FB-B967-2B33A860AD98}.Release|x64.Build.0 = Release|Any CPU
{95B077C1-E21B-486F-8BDD-1C902FE687AB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{95B077C1-E21B-486F-8BDD-1C902FE687AB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{95B077C1-E21B-486F-8BDD-1C902FE687AB}.Debug|x64.ActiveCfg = Debug|Any CPU
{95B077C1-E21B-486F-8BDD-1C902FE687AB}.Debug|x64.Build.0 = Debug|Any CPU
{95B077C1-E21B-486F-8BDD-1C902FE687AB}.Debug-Minimal|Any CPU.ActiveCfg = Debug|Any CPU
{95B077C1-E21B-486F-8BDD-1C902FE687AB}.Debug-Minimal|Any CPU.Build.0 = Debug|Any CPU
{95B077C1-E21B-486F-8BDD-1C902FE687AB}.Debug-Minimal|x64.ActiveCfg = Debug|Any CPU
{95B077C1-E21B-486F-8BDD-1C902FE687AB}.Debug-Minimal|x64.Build.0 = Debug|Any CPU
{95B077C1-E21B-486F-8BDD-1C902FE687AB}.Publish|Any CPU.ActiveCfg = Debug|Any CPU
{95B077C1-E21B-486F-8BDD-1C902FE687AB}.Publish|Any CPU.Build.0 = Debug|Any CPU
{95B077C1-E21B-486F-8BDD-1C902FE687AB}.Publish|x64.ActiveCfg = Debug|Any CPU
{95B077C1-E21B-486F-8BDD-1C902FE687AB}.Publish|x64.Build.0 = Debug|Any CPU
{95B077C1-E21B-486F-8BDD-1C902FE687AB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{95B077C1-E21B-486F-8BDD-1C902FE687AB}.Release|Any CPU.Build.0 = Release|Any CPU
{95B077C1-E21B-486F-8BDD-1C902FE687AB}.Release|x64.ActiveCfg = Release|Any CPU
{95B077C1-E21B-486F-8BDD-1C902FE687AB}.Release|x64.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE


+ 1
- 1
src/TensorFlowNET.Core/APIs/tf.math.cs View File

@@ -261,7 +261,7 @@ namespace Tensorflow


public Tensor divide(Tensor a, Tensor b)
=> gen_math_ops.real_div(a, b);
=> a / b;

public Tensor sqrt(Tensor a, string name = null)
=> gen_math_ops.sqrt(a, name);


+ 13
- 0
src/TensorFlowNET.Core/Binding.Util.cs View File

@@ -77,6 +77,19 @@ namespace Tensorflow
Console.WriteLine(_tostring(obj));
}

public static void print(string format, params object[] objects)
{
if (!format.Contains("{}"))
Console.WriteLine(format, string.Join(" ", objects.Select(x => x.ToString())));

foreach(var obj in objects)
{

}

Console.WriteLine(format);
}

public static int len(object a)
{
switch (a)


+ 23
- 1
src/TensorFlowNET.Core/Device/c_api.device.cs View File

@@ -37,6 +37,16 @@ namespace Tensorflow
[DllImport(TensorFlowLibName)]
public static extern int TF_DeviceListCount(IntPtr list);

/// <summary>
/// Retrieves the type of the device at the given index.
/// </summary>
/// <param name="list">TF_DeviceList*</param>
/// <param name="index">int</param>
/// <param name="status">TF_Status*</param>
/// <returns></returns>
[DllImport(TensorFlowLibName)]
public static extern IntPtr TF_DeviceListType(IntPtr list, int index, IntPtr status);

/// <summary>
/// Deallocates the device list.
/// </summary>
@@ -44,6 +54,18 @@ namespace Tensorflow
[DllImport(TensorFlowLibName)]
public static extern void TF_DeleteDeviceList(IntPtr list);

/// <summary>
/// Create a new TFE_TensorHandle with the same contents as 'h' but placed
/// in the memory of the device name 'device_name'.
/// </summary>
/// <param name="h">TFE_TensorHandle*</param>
/// <param name="ctx">TFE_Context*</param>
/// <param name="device_name">char*</param>
/// <param name="status">TF_Status*</param>
/// <returns>TFE_TensorHandle*</returns>
[DllImport(TensorFlowLibName)]
public static extern IntPtr TFE_TensorHandleCopyToDevice(IntPtr h, IntPtr ctx, string device_name, IntPtr status);

/// <summary>
/// Retrieves the full name of the device (e.g. /job:worker/replica:0/...)
/// The return value will be a pointer to a null terminated string. The caller
@@ -54,6 +76,6 @@ namespace Tensorflow
/// <param name="index"></param>
/// <param name="status">TF_Status*</param>
[DllImport(TensorFlowLibName)]
public static extern string TF_DeviceListName(IntPtr list, int index, IntPtr status);
public static extern IntPtr TF_DeviceListName(IntPtr list, int index, IntPtr status);
}
}

+ 22
- 0
src/TensorFlowNET.Core/Eager/c_api.eager.cs View File

@@ -159,6 +159,28 @@ namespace Tensorflow
[DllImport(TensorFlowLibName)]
public static extern int TFE_TensorHandleNumDims(IntPtr h, IntPtr status);

/// <summary>
/// Returns the device of the operation that produced `h`. If `h` was produced by
/// a copy, returns the destination device of the copy. Note that the returned
/// device name is not always the device holding the tensor handle's memory. If
/// you want the latter, use TFE_TensorHandleBackingDeviceName. This function
/// will block till the operation that produces `h` has completed.
/// </summary>
/// <param name="h">TFE_TensorHandle*</param>
/// <param name="status">TF_Status*</param>
/// <returns></returns>
[DllImport(TensorFlowLibName)]
public static extern IntPtr TFE_TensorHandleDeviceName(IntPtr h, IntPtr status);

/// <summary>
/// Returns the name of the device in whose memory `h` resides.
/// </summary>
/// <param name="h">TFE_TensorHandle*</param>
/// <param name="status">TF_Status*</param>
/// <returns></returns>
[DllImport(TensorFlowLibName)]
public static extern IntPtr TFE_TensorHandleBackingDeviceName(IntPtr h, IntPtr status);

/// <summary>
///
/// </summary>


+ 9
- 2
src/TensorFlowNET.Core/Eager/pywrap_tfe_src.cs View File

@@ -14,7 +14,7 @@ namespace Tensorflow.Eager
string device_name,
string opName,
string name,
params Tensor[] inputs)
params object[] inputs)
{
IntPtr op = IntPtr.Zero;
var attr_list_sizes = new Dictionary<string, int>();
@@ -42,7 +42,14 @@ namespace Tensorflow.Eager
else
{
// The item is a single item.
AddInputToOp(inputs[i], true, input_arg, op, status);
switch (inputs[i])
{
case Tensor inputTensor:
AddInputToOp(inputTensor, true, input_arg, op, status);
break;
default:
throw new NotImplementedException("");
}
}
}



+ 32
- 7
src/TensorFlowNET.Core/Operations/gen_math_ops.cs View File

@@ -140,19 +140,14 @@ namespace Tensorflow
return _op.outputs[0];
}

public static EagerTensor add(Tensor x, Tensor y, string name = null)
public static Tensor add<Tx, Ty>(Tx x, Ty y, string name = null)
{
if (tf.context.executing_eagerly())
{
var _result = pywrap_tfe_src.TFE_Py_FastPathExecute(tf.context, "", "Add", name, new[] { x, y });
var _result = pywrap_tfe_src.TFE_Py_FastPathExecute(tf.context, "", "Add", name, x, y);
return _result;
}

return null;
}

public static Tensor add<Tx, Ty>(Tx x, Ty y, string name = null)
{
var _op = _op_def_lib._apply_op_helper("Add", name, args: new { x, y });

return _op.output;
@@ -469,6 +464,12 @@ namespace Tensorflow

public static Tensor cast(Tensor x, TF_DataType DstT, bool Truncate= false, string name= null)
{
if (tf.context.executing_eagerly())
{
var _result = pywrap_tfe_src.TFE_Py_FastPathExecute(tf.context, "", "Cast", name, x, "DstT", DstT, "Truncate", Truncate);
return _result;
}

var _op = _op_def_lib._apply_op_helper("Cast", name, args: new { x, DstT, Truncate });

return _op.outputs[0];
@@ -490,6 +491,12 @@ namespace Tensorflow

public static Tensor sub<Tx, Ty>(Tx x, Ty y, string name = null)
{
if (tf.context.executing_eagerly())
{
var _result = pywrap_tfe_src.TFE_Py_FastPathExecute(tf.context, "", "Sub", name, x, y);
return _result;
}

var _op = _op_def_lib._apply_op_helper("Sub", name, args: new { x, y });

return _op.outputs[0];
@@ -535,6 +542,12 @@ namespace Tensorflow

public static Tensor mul<Tx, Ty>(Tx x, Ty y, string name = null)
{
if (tf.context.executing_eagerly())
{
var _result = pywrap_tfe_src.TFE_Py_FastPathExecute(tf.context, "", "Mul", name, x, y);
return _result;
}

var _op = _op_def_lib._apply_op_helper("Mul", name, args: new { x, y });

return _op.outputs[0];
@@ -549,6 +562,12 @@ namespace Tensorflow

public static Tensor real_div(Tensor x, Tensor y, string name = null)
{
if (tf.context.executing_eagerly())
{
var _result = pywrap_tfe_src.TFE_Py_FastPathExecute(tf.context, "", "RealDiv", name, x, y);
return _result;
}

var _op = _op_def_lib._apply_op_helper("RealDiv", name, args: new { x, y });

return _op.outputs[0];
@@ -570,6 +589,12 @@ namespace Tensorflow

public static Tensor floor_div(Tensor x, Tensor y, string name = null)
{
if (tf.context.executing_eagerly())
{
var _result = pywrap_tfe_src.TFE_Py_FastPathExecute(tf.context, "", "FloorDiv", name, x, y);
return _result;
}

var _op = _op_def_lib._apply_op_helper("FloorDiv", name, args: new { x, y });

return _op.outputs[0];


+ 16
- 0
src/TensorFlowNET.Core/Operations/math_ops.cs View File

@@ -712,6 +712,22 @@ namespace Tensorflow
var x_dtype = x.dtype.as_base_dtype();
var y_dtype = y.dtype.as_base_dtype();

if (x_dtype != y_dtype)
throw new TypeError($"x and y must have the same dtype, got {x_dtype} != {y_dtype}");

var dtype = x_dtype switch
{
TF_DataType.TF_UINT8 => TF_DataType.TF_FLOAT,
TF_DataType.TF_INT8 => TF_DataType.TF_FLOAT,
TF_DataType.TF_INT16 => TF_DataType.TF_FLOAT,
TF_DataType.TF_UINT16 => TF_DataType.TF_FLOAT,
TF_DataType.TF_INT32 => TF_DataType.TF_DOUBLE,
TF_DataType.TF_INT64 => TF_DataType.TF_DOUBLE,
_ => x_dtype
};
x = cast(x, dtype);
y = cast(y, dtype);

return gen_math_ops.real_div(x, y, name: name);
});
}


+ 1
- 1
src/TensorFlowNET.Core/Tensors/Tensor.Operators.cs View File

@@ -130,7 +130,7 @@ namespace Tensorflow
public static Tensor operator *(double lhs, Tensor rhs) => BinaryOpWrapper("mul", lhs, rhs);
public static Tensor operator *(Tensor lhs, Complex rhs) => BinaryOpWrapper("mul", lhs, rhs);
public static Tensor operator *(Complex lhs, Tensor rhs) => BinaryOpWrapper("mul", lhs, rhs);
public static Tensor operator /(Tensor lhs, Tensor rhs) => BinaryOpWrapper("div", lhs, rhs);
public static Tensor operator /(Tensor lhs, Tensor rhs) => BinaryOpWrapper("truediv", lhs, rhs);
public static Tensor operator /(Tensor lhs, NDArray rhs) => BinaryOpWrapper("div", lhs, rhs);
public static Tensor operator /(NDArray lhs, Tensor rhs) => BinaryOpWrapper("div", lhs, rhs);
public static Tensor operator /(Tensor lhs, sbyte rhs) => BinaryOpWrapper("div", lhs, rhs);


+ 3
- 0
src/TensorFlowNET.Core/ops.cs View File

@@ -97,6 +97,9 @@ namespace Tensorflow
/// <returns></returns>
public static Tensor convert_to_tensor(object value, TF_DataType dtype = TF_DataType.DtInvalid, string name = null, TF_DataType preferred_dtype = TF_DataType.DtInvalid)
{
if (value is Tensor tensor)
return tensor;

return convert_to_tensor_v2(value, dtype, preferred_dtype, name);
}



+ 24
- 0
test/TensorFlowNET.UnitTest/CApiTest.cs View File

@@ -103,6 +103,30 @@ namespace TensorFlowNET.UnitTest
protected IntPtr TFE_TensorHandleResolve(IntPtr h, IntPtr status)
=> c_api.TFE_TensorHandleResolve(h, status);

protected string TFE_TensorHandleDeviceName(IntPtr h, IntPtr status)
=> c_api.StringPiece(c_api.TFE_TensorHandleDeviceName(h, status));

protected string TFE_TensorHandleBackingDeviceName(IntPtr h, IntPtr status)
=> c_api.StringPiece(c_api.TFE_TensorHandleBackingDeviceName(h, status));

protected IntPtr TFE_ContextListDevices(IntPtr ctx, IntPtr status)
=> c_api.TFE_ContextListDevices(ctx, status);

protected int TF_DeviceListCount(IntPtr list)
=> c_api.TF_DeviceListCount(list);

protected string TF_DeviceListType(IntPtr list, int index, IntPtr status)
=> c_api.StringPiece(c_api.TF_DeviceListType(list, index, status));

protected string TF_DeviceListName(IntPtr list, int index, IntPtr status)
=> c_api.StringPiece(c_api.TF_DeviceListName(list, index, status));

protected void TF_DeleteDeviceList(IntPtr list)
=> c_api.TF_DeleteDeviceList(list);

protected IntPtr TFE_TensorHandleCopyToDevice(IntPtr h, IntPtr ctx, string device_name, IntPtr status)
=> c_api.TFE_TensorHandleCopyToDevice(h, ctx, device_name, status);

protected unsafe void memcpy(void * src, IntPtr dst, ulong size)
{
Buffer.MemoryCopy(src, dst.ToPointer(), size, size);


+ 1
- 1
test/TensorFlowNET.UnitTest/Eager/CApi.Eager.Context.cs View File

@@ -33,7 +33,7 @@ namespace TensorFlowNET.UnitTest.Eager
EXPECT_EQ(TF_OK, TF_GetCode(status), TF_Message(status));
}

// c_api.TF_DeleteDeviceList(devices);
c_api.TF_DeleteDeviceList(devices);
c_api.TF_DeleteStatus(status);
}
}


+ 43
- 0
test/TensorFlowNET.UnitTest/Eager/CApi.Eager.TensorHandleDevices.cs View File

@@ -0,0 +1,43 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using Tensorflow;
using Tensorflow.Eager;
using Buffer = System.Buffer;

namespace TensorFlowNET.UnitTest.Eager
{
public partial class CApiEagerTest
{
/// <summary>
/// TEST(CAPI, TensorHandleDevices)
/// </summary>
[TestMethod]
public unsafe void TensorHandleDevices()
{
var status = c_api.TF_NewStatus();
var opts = TFE_NewContextOptions();
var ctx = TFE_NewContext(opts, status);
TFE_DeleteContextOptions(opts);
ASSERT_EQ(TF_OK, TF_GetCode(status), TF_Message(status));

var hcpu = TestMatrixTensorHandle();
var device_name = TFE_TensorHandleDeviceName(hcpu, status);
ASSERT_EQ(TF_OK, TF_GetCode(status), TF_Message(status));
ASSERT_TRUE(device_name.Contains("CPU:0"));

var backing_device_name = TFE_TensorHandleBackingDeviceName(hcpu, status);
ASSERT_EQ(TF_OK, TF_GetCode(status), TF_Message(status));
ASSERT_TRUE(backing_device_name.Contains("CPU:0"));

// Disable the test if no GPU is present.
string gpu_device_name = "";
if(GetDeviceName(ctx, ref gpu_device_name, "GPU"))
{
var hgpu = TFE_TensorHandleCopyToDevice(hcpu, ctx, gpu_device_name, status);
ASSERT_TRUE(TF_GetCode(status) == TF_OK, TF_Message(status));

// shape_op = ShapeOp(ctx, hgpu);
}
}
}
}

+ 25
- 0
test/TensorFlowNET.UnitTest/Eager/CApi.Eager.cs View File

@@ -42,5 +42,30 @@ namespace TensorFlowNET.UnitTest.Eager

return op;
}

bool GetDeviceName(IntPtr ctx, ref string device_name, string device_type)
{
var status = TF_NewStatus();
var devices = TFE_ContextListDevices(ctx, status);
CHECK_EQ(TF_OK, TF_GetCode(status), TF_Message(status));

int num_devices = TF_DeviceListCount(devices);
for (int i = 0; i < num_devices; ++i)
{
var dev_type = TF_DeviceListType(devices, i, status);
CHECK_EQ(TF_GetCode(status), TF_OK, TF_Message(status));
var dev_name = TF_DeviceListName(devices, i, status);
CHECK_EQ(TF_GetCode(status), TF_OK, TF_Message(status));
if (dev_type == device_type)
{
device_name = dev_name;
TF_DeleteDeviceList(devices);
return true;
}
}

TF_DeleteDeviceList(devices);
return false;
}
}
}

+ 1
- 2
test/TensorFlowNET.UnitTest/Tensorflow.UnitTest.csproj View File

@@ -33,12 +33,11 @@
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0" />
<PackageReference Include="MSTest.TestAdapter" Version="2.1.0" />
<PackageReference Include="MSTest.TestFramework" Version="2.1.0" />
<PackageReference Include="SciSharp.TensorFlow.Redist" Version="1.15.1" />
<PackageReference Include="SciSharp.TensorFlow.Redist-Windows-GPU" Version="1.15.1" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\TensorFlowNET.Core\Tensorflow.Binding.csproj" />
<ProjectReference Include="..\..\src\TensorFlowNET.Hub\Tensorflow.Hub.csproj" />
</ItemGroup>

<ItemGroup>


Loading…
Cancel
Save