private void TestGradientsSuccess(bool grad_inputs_provided) { var inputs = new TF_Output[2]; var outputs = new TF_Output[1]; var grad_outputs = new TF_Output[2]; var expected_grad_outputs = new TF_Output[2]; BuildSuccessGraph(inputs, outputs); BuildExpectedGraph(grad_inputs_provided, expected_grad_outputs); AddGradients(grad_inputs_provided, "gradients", inputs, 2, outputs, 1, grad_outputs); EXPECT_EQ(TF_OK, TF_GetCode(s_)); // Compare that the graphs match. GraphDef expected_gdef; GraphDef gdef; EXPECT_TRUE(GetGraphDef(expected_graph_, out expected_gdef)); EXPECT_TRUE(GetGraphDef(graph_, out gdef)); // Assert.IsTrue(expected_gdef.ToString().Equals(gdef.ToString())); // Compare that the output of the gradients of both graphs match. RunGraphsAndCompareOutputs(grad_outputs, expected_grad_outputs); }
private void BuildSuccessGraph(TF_Output[] inputs, TF_Output[] outputs) { // Construct the following graph: // | // z| // | // MatMul // / \ // ^ ^ // | | // x| y| // | | // | | // Const_0 Const_1 // var const0_val = new float[] { 1.0f, 2.0f, 3.0f, 4.0f }; var const1_val = new float[] { 1.0f, 0.0f, 0.0f, 1.0f }; var const0 = FloatConst2x2(graph_, s_, const0_val, "Const_0"); var const1 = FloatConst2x2(graph_, s_, const1_val, "Const_1"); var matmul = MatMul(graph_, s_, const0, const1, "MatMul"); inputs[0] = new TF_Output(const0, 0); inputs[1] = new TF_Output(const1, 0); outputs[0] = new TF_Output(matmul, 0); EXPECT_EQ(TF_OK, TF_GetCode(s_)); }
private void TestGradientsSuccess(bool grad_inputs_provided) { var inputs = new TF_Output[2]; var outputs = new TF_Output[1]; var grad_outputs = new TF_Output[2]; var expected_grad_outputs = new TF_Output[2]; BuildSuccessGraph(inputs, outputs); BuildExpectedGraph(grad_inputs_provided, expected_grad_outputs); AddGradients(grad_inputs_provided, string.Empty, inputs, 2, outputs, 1, grad_outputs); // EXPECT_EQ(TF_OK, TF_GetCode(s_)); // Compare that the graphs match. GraphDef expected_gdef; GraphDef gdef; EXPECT_TRUE(GetGraphDef(expected_graph_, out expected_gdef)); EXPECT_TRUE(GetGraphDef(graph_, out gdef)); //TF_EXPECT_GRAPH_EQ(expected_gdef, gdef); // Compare that the output of the gradients of both graphs match. RunGraphsAndCompareOutputs(grad_outputs, expected_grad_outputs); }
private void TestGradientsSuccess(bool grad_inputs_provided) { var inputs = new TF_Output[2]; var outputs = new TF_Output[1]; var grad_outputs = new TF_Output[2]; var expected_grad_outputs = new TF_Output[2]; BuildSuccessGraph(inputs, outputs); }
private void BuildExpectedGraph(bool grad_inputs_provided, TF_Output[] expected_grad_outputs) { // The expected graph looks like this if grad_inputs_provided. // If grad_inputs_provided is false, Const_0 will be a OnesLike op. // ^ ^ // dy| dx| // MatMul Gradient Graph // | | // MatMul_2 MatMul_1 // ^ ^ ^ ^ // | |----------| | // | ^ | // | dz| | // | | | // | Const_3 | // | | // | ^ | // | z| | // MatMul Forward Graph // | | | // | MatMul | // | / \ | // | ^ ^ | // | | | | // |---x| y|----| // | | // | | // Const_0 Const_1 // float[] const0_val = { 1.0f, 2.0f, 3.0f, 4.0f }; float[] const1_val = { 1.0f, 0.0f, 0.0f, 1.0f }; var const0 = FloatConst2x2(expected_graph_, s_, const0_val, "Const_0"); var const1 = FloatConst2x2(expected_graph_, s_, const1_val, "Const_1"); var matmul = MatMul(expected_graph_, s_, const0, const1, "MatMul"); Operation const3; if (grad_inputs_provided) { float[] const3_val = { 1.0f, 1.0f, 1.0f, 1.0f }; const3 = FloatConst2x2(expected_graph_, s_, const3_val, "GradInputs"); } else { const3 = OnesLike(expected_graph_, s_, matmul, "gradients/OnesLike"); } var matmul1 = MatMul(expected_graph_, s_, const3, const1, "gradients/MatMul", false, true); var matmul2 = MatMul(expected_graph_, s_, const0, const3, "gradients/MatMul_1", true, false); expected_grad_outputs[0] = new TF_Output(matmul1, 0); expected_grad_outputs[1] = new TF_Output(matmul2, 0); }
public static Operation Neg(Operation n, Graph graph, Status s, string name = "neg") { OperationDescription desc = c_api.TF_NewOperation(graph, "Neg", name); var neg_input = new TF_Output(n, 0); c_api.TF_AddInput(desc, neg_input); var op = c_api.TF_FinishOperation(desc, s); s.Check(); return(op); }
/*void TestGradientsError(bool grad_inputs_provided) * { * var inputs = new TF_Output[1]; * var outputs = new TF_Output[1]; * var grad_outputs = new TF_Output[1]; * * BuildErrorGraph(inputs, outputs); * * AddGradients(grad_inputs_provided, nullptr, inputs, 1, outputs, 1, * grad_outputs); * * string expected_msg = * "No gradient defined for op: TestOpWithNoGradient. Please see " * "https://www.tensorflow.org/code/" * "tensorflow/cc/gradients/README.md" * " for instructions on how to add C++ gradients."; * EXPECT_EQ(expected_msg, TF_Message(s_)); * }*/ private void AddGradients(bool grad_inputs_provided, string prefix, TF_Output[] inputs, int ninputs, TF_Output[] outputs, int noutputs, TF_Output[] grad_outputs) { if (grad_inputs_provided) { var grad_inputs = new TF_Output[1]; float[] grad_inputs_val = { 1.0f, 1.0f, 1.0f, 1.0f }; var grad_inputs_op = FloatConst2x2(graph_, s_, grad_inputs_val, "GradInputs"); grad_inputs[0] = new TF_Output(grad_inputs_op, 0); c_api.TF_AddGradientsWithPrefix(graph_, prefix, outputs, noutputs, inputs, ninputs, grad_inputs, s_, grad_outputs); } else { c_api.TF_AddGradientsWithPrefix(graph_, prefix, outputs, noutputs, inputs, ninputs, null, s_, grad_outputs); } }
public static Operation Add(Operation l, Operation r, Graph graph, Status s, string name = "add") { var desc = c_api.TF_NewOperation(graph, "AddN", name); var inputs = new TF_Output[] { new TF_Output(l, 0), new TF_Output(r, 0), }; c_api.TF_AddInputList(desc, inputs, inputs.Length); var op = c_api.TF_FinishOperation(desc, s); s.Check(); return(op); }
/*void TestGradientsError(bool grad_inputs_provided) * { * var inputs = new TF_Output[1]; * var outputs = new TF_Output[1]; * var grad_outputs = new TF_Output[1]; * * BuildErrorGraph(inputs, outputs); * * AddGradients(grad_inputs_provided, nullptr, inputs, 1, outputs, 1, * grad_outputs); * * string expected_msg = * "No gradient defined for op: TestOpWithNoGradient. Please see " * "https://www.tensorflow.org/code/" * "tensorflow/cc/gradients/README.md" * " for instructions on how to add C++ gradients."; * EXPECT_EQ(expected_msg, TF_Message(s_)); * }*/ private void AddGradients(bool grad_inputs_provided, string prefix, TF_Output[] inputs, int ninputs, TF_Output[] outputs, int noutputs, TF_Output[] grad_outputs) { if (grad_inputs_provided) { var grad_inputs = new TF_Output[1]; float[] grad_inputs_val = { 1.0f, 1.0f, 1.0f, 1.0f }; var grad_inputs_op = FloatConst2x2(graph_, s_, grad_inputs_val, "GradInputs"); grad_inputs[0] = new TF_Output(grad_inputs_op, 0); IntPtr[] handles = new IntPtr[2] { IntPtr.Zero, IntPtr.Zero }; c_api.TF_AddGradientsWithPrefix(graph_, prefix, outputs, noutputs, inputs, ninputs, grad_inputs, s_, handles); var op = new Operation(handles[0]); } else { //c_api.TF_AddGradientsWithPrefix(graph_, prefix, outputs, noutputs, inputs, //ninputs, null, s_, grad_outputs); } }
public void Session() { lock (Locks.ProcessWide) { var s = new Status(); var graph = new Graph().as_default(); // Make a placeholder operation. var feed = c_test_util.Placeholder(graph, s); // Make a constant operation with the scalar "2". var two = c_test_util.ScalarConst(2, graph, s); // Add operation. var add = c_test_util.Add(feed, two, graph, s); var csession = new CSession(graph, s); ASSERT_EQ(TF_Code.TF_OK, s.Code); // Run the graph. var inputs = new Dictionary <Operation, Tensor>(); inputs.Add(feed, new Tensor(3)); csession.SetInputs(inputs); var outputs = new TF_Output[] { new TF_Output(add, 0) }; csession.SetOutputs(outputs); csession.Run(s); Tensor outTensor = csession.output_tensor(0); EXPECT_EQ(TF_DataType.TF_INT32, outTensor.dtype); EXPECT_EQ(0, outTensor.NDims); ASSERT_EQ((ulong)sizeof(uint), outTensor.bytesize); var output_contents = outTensor.ToArray <int>(); EXPECT_EQ(3 + 2, output_contents[0]); // Add another operation to the graph. var neg = c_test_util.Neg(add, graph, s); ASSERT_EQ(TF_Code.TF_OK, s.Code); // Run up to the new operation. inputs = new Dictionary <Operation, Tensor>(); inputs.Add(feed, new Tensor(7)); csession.SetInputs(inputs); outputs = new TF_Output[] { new TF_Output(neg, 0) }; csession.SetOutputs(outputs); csession.Run(s); ASSERT_EQ(TF_Code.TF_OK, s.Code); outTensor = csession.output_tensor(0); ASSERT_TRUE(outTensor != IntPtr.Zero); EXPECT_EQ(TF_DataType.TF_INT32, outTensor.dtype); EXPECT_EQ(0, outTensor.NDims); // scalar ASSERT_EQ((ulong)sizeof(uint), outTensor.bytesize); output_contents = outTensor.ToArray <int>(); EXPECT_EQ(-(7 + 2), output_contents[0]); // Clean up csession.CloseAndDelete(s); ASSERT_EQ(TF_Code.TF_OK, s.Code); } }
public void SetShape() { var s = new Status(); var graph = new Graph().as_default(); var feed = c_test_util.Placeholder(graph, s); var feed_out_0 = new TF_Output(feed, 0); // Fetch the shape, it should be completely unknown. int num_dims = c_api.TF_GraphGetTensorNumDims(graph, feed_out_0, s.Handle); Assert.IsTrue(s.Code == TF_Code.TF_OK); EXPECT_EQ(-1, num_dims); // Set the shape to be unknown, expect no change. c_api.TF_GraphSetTensorShape(graph, feed_out_0, null, -1, s.Handle); Assert.IsTrue(s.Code == TF_Code.TF_OK); num_dims = c_api.TF_GraphGetTensorNumDims(graph, feed_out_0, s.Handle); EXPECT_EQ(-1, num_dims); // Set the shape to be 2 x Unknown long[] dims = { 2, -1 }; c_api.TF_GraphSetTensorShape(graph, feed_out_0, dims, dims.Length, s.Handle); Assert.IsTrue(s.Code == TF_Code.TF_OK); num_dims = c_api.TF_GraphGetTensorNumDims(graph, feed_out_0, s.Handle); EXPECT_EQ(2, num_dims); // Get the dimension vector appropriately. var returned_dims = new long[dims.Length]; c_api.TF_GraphGetTensorShape(graph, feed_out_0, returned_dims, num_dims, s.Handle); Assert.IsTrue(s.Code == TF_Code.TF_OK); Assert.IsTrue(Enumerable.SequenceEqual(dims, returned_dims)); // Set to a new valid shape: [2, 3] dims[1] = 3; c_api.TF_GraphSetTensorShape(graph, feed_out_0, dims, dims.Length, s.Handle); Assert.IsTrue(s.Code == TF_Code.TF_OK); // Fetch and see that the new value is returned. c_api.TF_GraphGetTensorShape(graph, feed_out_0, returned_dims, num_dims, s.Handle); Assert.IsTrue(s.Code == TF_Code.TF_OK); Assert.IsTrue(Enumerable.SequenceEqual(dims, returned_dims)); // Try to set 'unknown' with unknown rank on the shape and see that // it doesn't change. c_api.TF_GraphSetTensorShape(graph, feed_out_0, null, -1, s.Handle); Assert.IsTrue(s.Code == TF_Code.TF_OK); c_api.TF_GraphGetTensorShape(graph, feed_out_0, returned_dims, num_dims, s.Handle); Assert.IsTrue(s.Code == TF_Code.TF_OK); EXPECT_EQ(2, num_dims); EXPECT_EQ(2, (int)returned_dims[0]); EXPECT_EQ(3, (int)returned_dims[1]); // Try to set 'unknown' with same rank on the shape and see that // it doesn't change. dims[0] = -1; dims[1] = -1; c_api.TF_GraphSetTensorShape(graph, feed_out_0, dims, 2, s.Handle); Assert.IsTrue(s.Code == TF_Code.TF_OK); c_api.TF_GraphGetTensorShape(graph, feed_out_0, returned_dims, num_dims, s.Handle); Assert.IsTrue(s.Code == TF_Code.TF_OK); EXPECT_EQ(2, num_dims); EXPECT_EQ(2, (int)returned_dims[0]); EXPECT_EQ(3, (int)returned_dims[1]); // Try to fetch a shape with the wrong num_dims c_api.TF_GraphGetTensorShape(graph, feed_out_0, returned_dims, 5, s.Handle); Assert.IsTrue(s.Code == TF_Code.TF_INVALID_ARGUMENT); // Try to set an invalid shape (cannot change 2x3 to a 2x5). dims[1] = 5; c_api.TF_GraphSetTensorShape(graph, feed_out_0, dims, 2, s.Handle); Assert.IsTrue(s.Code == TF_Code.TF_INVALID_ARGUMENT); // Test for a scalar. var three = c_test_util.ScalarConst(3, graph, s); Assert.IsTrue(s.Code == TF_Code.TF_OK); var three_out_0 = new TF_Output(three, 0); num_dims = c_api.TF_GraphGetTensorNumDims(graph, three_out_0, s.Handle); Assert.IsTrue(s.Code == TF_Code.TF_OK); EXPECT_EQ(0, num_dims); c_api.TF_GraphGetTensorShape(graph, feed_out_0, null, num_dims, s.Handle); //Assert.IsTrue(s.Code == TF_Code.TF_OK); // graph.Dispose(); s.Dispose(); }
protected void TF_AddInput(OperationDescription desc, TF_Output input) { c_api.TF_AddInput(desc, input); }