| @@ -1,5 +1,6 @@ | |||||
| using System; | using System; | ||||
| using System.Runtime.InteropServices; | using System.Runtime.InteropServices; | ||||
| using TFE_Executor = System.IntPtr; | |||||
| namespace Tensorflow | namespace Tensorflow | ||||
| { | { | ||||
| @@ -196,5 +197,55 @@ namespace Tensorflow | |||||
| /// <param name="h">TFE_TensorHandle*</param> | /// <param name="h">TFE_TensorHandle*</param> | ||||
| [DllImport(TensorFlowLibName)] | [DllImport(TensorFlowLibName)] | ||||
| public static extern void TFE_DeleteTensorHandle(IntPtr h); | public static extern void TFE_DeleteTensorHandle(IntPtr h); | ||||
| /// <summary> | |||||
| /// Creates a new eager Executor. Nodes in one executor are guaranteed to be | |||||
| /// executed in sequence. Assigning nodes to different executors allows executing | |||||
| /// nodes in parallel. | |||||
| /// </summary> | |||||
| /// <param name="is_async"></param> | |||||
| /// <returns>TFE_Executor*</returns> | |||||
| [DllImport(TensorFlowLibName)] | |||||
| public static extern IntPtr TFE_NewExecutor(bool is_async); | |||||
| /// <summary> | |||||
| /// Deletes the eager Executor without waiting for enqueued nodes. Please call | |||||
| /// TFE_ExecutorWaitForAllPendingNodes before calling this API if you want to | |||||
| /// make sure all nodes are finished. | |||||
| /// </summary> | |||||
| /// <param name="e">TFE_Executor*</param> | |||||
| [DllImport(TensorFlowLibName)] | |||||
| public static extern void TFE_DeleteExecutor(IntPtr executor); | |||||
| /// <summary> | |||||
| /// Causes the calling thread to block till all ops dispatched in this executor | |||||
| /// have been executed. Note that "execution" here refers to kernel execution / | |||||
| /// scheduling of copies, etc. Similar to sync execution, it doesn't guarantee | |||||
| /// that lower level device queues (like GPU streams) have been flushed. | |||||
| /// | |||||
| /// This call may not block for execution of ops enqueued concurrently with this | |||||
| /// call. | |||||
| /// </summary> | |||||
| /// <param name="executor">TFE_Executor*</param> | |||||
| /// <param name="status">TF_Status*</param> | |||||
| [DllImport(TensorFlowLibName)] | |||||
| public static extern void TFE_ExecutorWaitForAllPendingNodes(TFE_Executor executor, IntPtr status); | |||||
| /// <summary> | |||||
| /// Sets a custom Executor for current thread. All nodes created by this thread | |||||
| /// will be added to this Executor. It will override current executor. | |||||
| /// </summary> | |||||
| /// <param name="ctx"></param> | |||||
| /// <param name="executor"></param> | |||||
| [DllImport(TensorFlowLibName)] | |||||
| public static extern void TFE_ContextSetExecutorForThread(IntPtr ctx, TFE_Executor executor); | |||||
| /// <summary> | |||||
| /// Returns the Executor for current thread. | |||||
| /// </summary> | |||||
| /// <param name="ctx"></param> | |||||
| /// <returns>TFE_Executor*</returns> | |||||
| [DllImport(TensorFlowLibName)] | |||||
| public static extern TFE_Executor TFE_ContextGetExecutorForThread(IntPtr ctx); | |||||
| } | } | ||||
| } | } | ||||
| @@ -100,6 +100,15 @@ namespace TensorFlowNET.UnitTest | |||||
| protected void TFE_DeleteOp(IntPtr op) | protected void TFE_DeleteOp(IntPtr op) | ||||
| => c_api.TFE_DeleteOp(op); | => c_api.TFE_DeleteOp(op); | ||||
| protected void TFE_DeleteExecutor(IntPtr executor) | |||||
| => c_api.TFE_DeleteExecutor(executor); | |||||
| protected IntPtr TFE_ContextGetExecutorForThread(IntPtr ctx) | |||||
| => c_api.TFE_ContextGetExecutorForThread(ctx); | |||||
| protected void TFE_ExecutorWaitForAllPendingNodes(IntPtr executor, IntPtr status) | |||||
| => c_api.TFE_ExecutorWaitForAllPendingNodes(executor, status); | |||||
| protected IntPtr TFE_TensorHandleResolve(IntPtr h, IntPtr status) | protected IntPtr TFE_TensorHandleResolve(IntPtr h, IntPtr status) | ||||
| => c_api.TFE_TensorHandleResolve(h, status); | => c_api.TFE_TensorHandleResolve(h, status); | ||||
| @@ -127,6 +136,9 @@ namespace TensorFlowNET.UnitTest | |||||
| protected IntPtr TFE_TensorHandleCopyToDevice(IntPtr h, IntPtr ctx, string device_name, IntPtr status) | protected IntPtr TFE_TensorHandleCopyToDevice(IntPtr h, IntPtr ctx, string device_name, IntPtr status) | ||||
| => c_api.TFE_TensorHandleCopyToDevice(h, ctx, device_name, status); | => c_api.TFE_TensorHandleCopyToDevice(h, ctx, device_name, status); | ||||
| protected void TFE_OpSetDevice(IntPtr op, string device_name, IntPtr status) | |||||
| => c_api.TFE_OpSetDevice(op, device_name, status); | |||||
| protected unsafe void memcpy(void * src, IntPtr dst, ulong size) | protected unsafe void memcpy(void * src, IntPtr dst, ulong size) | ||||
| { | { | ||||
| Buffer.MemoryCopy(src, dst.ToPointer(), size, size); | Buffer.MemoryCopy(src, dst.ToPointer(), size, size); | ||||
| @@ -36,8 +36,36 @@ namespace TensorFlowNET.UnitTest.Eager | |||||
| var hgpu = TFE_TensorHandleCopyToDevice(hcpu, ctx, gpu_device_name, status); | var hgpu = TFE_TensorHandleCopyToDevice(hcpu, ctx, gpu_device_name, status); | ||||
| ASSERT_TRUE(TF_GetCode(status) == TF_OK, TF_Message(status)); | ASSERT_TRUE(TF_GetCode(status) == TF_OK, TF_Message(status)); | ||||
| // shape_op = ShapeOp(ctx, hgpu); | |||||
| var shape_op = ShapeOp(ctx, hgpu); | |||||
| TFE_OpSetDevice(shape_op, gpu_device_name, status); | |||||
| ASSERT_TRUE(TF_GetCode(status) == TF_OK, TF_Message(status)); | |||||
| var retvals = new IntPtr[1]; | |||||
| int num_retvals = 1; | |||||
| c_api.TFE_Execute(shape_op, retvals, ref num_retvals, status); | |||||
| ASSERT_TRUE(TF_GetCode(status) == TF_OK, TF_Message(status)); | |||||
| // .device of shape is GPU since the op is executed on GPU | |||||
| device_name = TFE_TensorHandleDeviceName(retvals[0], status); | |||||
| ASSERT_EQ(TF_OK, TF_GetCode(status), TF_Message(status)); | |||||
| ASSERT_TRUE(device_name.Contains("GPU:0")); | |||||
| // .backing_device of shape is CPU since the tensor is backed by CPU | |||||
| backing_device_name = TFE_TensorHandleBackingDeviceName(retvals[0], status); | |||||
| ASSERT_EQ(TF_OK, TF_GetCode(status), TF_Message(status)); | |||||
| ASSERT_TRUE(backing_device_name.Contains("CPU:0")); | |||||
| TFE_DeleteOp(shape_op); | |||||
| TFE_DeleteTensorHandle(retvals[0]); | |||||
| TFE_DeleteTensorHandle(hgpu); | |||||
| } | } | ||||
| TFE_DeleteTensorHandle(hcpu); | |||||
| // not export api | |||||
| /*var executor = TFE_ContextGetExecutorForThread(ctx); | |||||
| TFE_ExecutorWaitForAllPendingNodes(executor, status); | |||||
| ASSERT_EQ(TF_OK, TF_GetCode(status), TF_Message(status)); | |||||
| TFE_DeleteExecutor(executor);*/ | |||||
| TFE_DeleteContext(ctx); | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| @@ -1,8 +1,6 @@ | |||||
| using Microsoft.VisualStudio.TestTools.UnitTesting; | using Microsoft.VisualStudio.TestTools.UnitTesting; | ||||
| using System; | using System; | ||||
| using Tensorflow; | using Tensorflow; | ||||
| using Tensorflow.Eager; | |||||
| using Buffer = System.Buffer; | |||||
| namespace TensorFlowNET.UnitTest.Eager | namespace TensorFlowNET.UnitTest.Eager | ||||
| { | { | ||||
| @@ -67,5 +65,19 @@ namespace TensorFlowNET.UnitTest.Eager | |||||
| TF_DeleteDeviceList(devices); | TF_DeleteDeviceList(devices); | ||||
| return false; | return false; | ||||
| } | } | ||||
| IntPtr ShapeOp(IntPtr ctx, IntPtr a) | |||||
| { | |||||
| var status = TF_NewStatus(); | |||||
| var op = TFE_NewOp(ctx, "Shape", status); | |||||
| CHECK_EQ(TF_OK, TF_GetCode(status), TF_Message(status)); | |||||
| TFE_OpAddInput(op, a, status); | |||||
| CHECK_EQ(TF_OK, TF_GetCode(status), TF_Message(status)); | |||||
| TF_DeleteStatus(status); | |||||
| TFE_OpSetAttrType(op, "T", TFE_TensorHandleDataType(a)); | |||||
| return op; | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| @@ -33,7 +33,7 @@ | |||||
| <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0" /> | <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0" /> | ||||
| <PackageReference Include="MSTest.TestAdapter" Version="2.1.0" /> | <PackageReference Include="MSTest.TestAdapter" Version="2.1.0" /> | ||||
| <PackageReference Include="MSTest.TestFramework" Version="2.1.0" /> | <PackageReference Include="MSTest.TestFramework" Version="2.1.0" /> | ||||
| <PackageReference Include="SciSharp.TensorFlow.Redist-Windows-GPU" Version="1.15.1" /> | |||||
| <PackageReference Include="SciSharp.TensorFlow.Redist" Version="1.15.1" /> | |||||
| </ItemGroup> | </ItemGroup> | ||||
| <ItemGroup> | <ItemGroup> | ||||