Skip to content

Commit e575583

Browse files
dje-devOceania2018
authored andcommitted
Complete implementation of bitwise bitwise_ops and corresponding unit tests.
1 parent 925b3cb commit e575583

File tree

2 files changed

+157
-8
lines changed

2 files changed

+157
-8
lines changed

src/TensorFlowNET.Core/Operations/bitwise_ops.cs

Lines changed: 94 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ limitations under the License.
2121

2222
namespace Tensorflow.Operations
2323
{
24+
/// <summary>
25+
/// Operations for bitwise manipulation of integers.
26+
/// https://www.tensorflow.org/api_docs/python/tf/bitwise
27+
/// </summary>
2428
public class bitwise_ops
2529
{
2630
/// <summary>
@@ -31,20 +35,107 @@ public class bitwise_ops
3135
/// <param name="y"></param>
3236
/// <param name="name"></param>
3337
/// <returns></returns>
34-
public Tensor left_shift(Tensor x, Tensor y, string name = null)
38+
public Tensor left_shift(Tensor x, Tensor y, string name = null) => binary_op(x, y, "LeftShift", name);
39+
40+
/// <summary>
41+
/// Elementwise computes the bitwise right-shift of `x` and `y`.
42+
/// https://www.tensorflow.org/api_docs/python/tf/bitwise/right_shift
43+
/// </summary>
44+
/// <param name="x"></param>
45+
/// <param name="y"></param>
46+
/// <param name="name"></param>
47+
/// <returns></returns>
48+
public Tensor right_shift(Tensor x, Tensor y, string name = null) => binary_op(x, y, "RightShift", name);
49+
50+
/// <summary>
51+
/// Elementwise computes the bitwise inversion of `x`.
52+
/// https://www.tensorflow.org/api_docs/python/tf/bitwise/invert
53+
/// </summary>
54+
/// <param name="x"></param>
55+
/// <param name="name"></param>
56+
/// <returns></returns>
57+
public Tensor invert(Tensor x, string name = null) => unary_op(x, "Invert", name);
58+
59+
/// <summary>
60+
/// Elementwise computes the bitwise AND of `x` and `y`.
61+
/// https://www.tensorflow.org/api_docs/python/tf/bitwise/bitwise_and
62+
/// </summary>
63+
/// <param name="x"></param>
64+
/// <param name="y"></param>
65+
/// <param name="name"></param>
66+
/// <returns></returns>
67+
public Tensor bitwise_and(Tensor x, Tensor y, string name = null) => binary_op(x, y, "BitwiseAnd", name);
68+
69+
/// <summary>
70+
/// Elementwise computes the bitwise OR of `x` and `y`.
71+
/// https://www.tensorflow.org/api_docs/python/tf/bitwise/bitwise_or
72+
/// </summary>
73+
/// <param name="x"></param>
74+
/// <param name="y"></param>
75+
/// <param name="name"></param>
76+
/// <returns></returns>
77+
public Tensor bitwise_or(Tensor x, Tensor y, string name = null) => binary_op(x, y, "BitwiseOr", name);
78+
79+
/// <summary>
80+
/// Elementwise computes the bitwise XOR of `x` and `y`.
81+
/// https://www.tensorflow.org/api_docs/python/tf/bitwise/bitwise_xor
82+
/// </summary>
83+
/// <param name="x"></param>
84+
/// <param name="y"></param>
85+
/// <param name="name"></param>
86+
/// <returns></returns>
87+
public Tensor bitwise_xor(Tensor x, Tensor y, string name = null) => binary_op(x, y, "BitwiseXor", name);
88+
89+
90+
#region Private helper methods
91+
92+
/// <summary>
93+
/// Helper method to invoke unary operator with specified name.
94+
/// </summary>
95+
/// <param name="x"></param>
96+
/// <param name="opName"></param>
97+
/// <param name="name"></param>
98+
/// <returns></returns>
99+
Tensor unary_op(Tensor x, string opName, string name)
100+
{
101+
if (tf.Context.executing_eagerly())
102+
{
103+
var results = tf.Runner.TFE_FastPathExecute(tf.Context, tf.Context.DeviceName,
104+
opName, name,
105+
null,
106+
x);
107+
108+
return results[0];
109+
}
110+
111+
var _op = tf.OpDefLib._apply_op_helper(opName, name, args: new { x });
112+
return _op.output;
113+
}
114+
115+
/// <summary>
116+
/// Helper method to invoke binary operator with specified name.
117+
/// </summary>
118+
/// <param name="x"></param>
119+
/// <param name="y"></param>
120+
/// <param name="opName"></param>
121+
/// <param name="name"></param>
122+
/// <returns></returns>
123+
Tensor binary_op(Tensor x, Tensor y, string opName, string name)
35124
{
36125
if (tf.Context.executing_eagerly())
37126
{
38127
var results = tf.Runner.TFE_FastPathExecute(tf.Context, tf.Context.DeviceName,
39-
"LeftShift", name,
128+
opName, name,
40129
null,
41130
x, y);
42131

43132
return results[0];
44133
}
45134

46-
var _op = tf.OpDefLib._apply_op_helper("LeftShift", name, args: new { x, y });
135+
var _op = tf.OpDefLib._apply_op_helper(opName, name, args: new { x, y });
47136
return _op.output;
48137
}
138+
139+
#endregion
49140
}
50141
}
Lines changed: 63 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
11
using Microsoft.VisualStudio.TestTools.UnitTesting;
2-
using System;
3-
using System.Collections.Generic;
42
using System.Linq;
5-
using System.Text;
63
using Tensorflow;
74
using static Tensorflow.Binding;
85

@@ -11,16 +8,77 @@ namespace TensorFlowNET.UnitTest.TF_API
118
[TestClass]
129
public class BitwiseApiTest : TFNetApiTest
1310
{
14-
Tensor lhs = tf.constant(new int[] { -1, -5, -3, -14 });
15-
Tensor rhs = tf.constant(new int[] { 5, 0, 7, 11 });
11+
12+
[TestMethod]
13+
public void BitwiseAnd()
14+
{
15+
Tensor lhs = tf.constant(new int[] { 0, 5, 3, 14 });
16+
Tensor rhs = tf.constant(new int[] { 5, 0, 7, 11 });
17+
18+
var bitwise_and_result = tf.bitwise.bitwise_and(lhs, rhs);
19+
var expected = new int[] { 0, 0, 3, 10 };
20+
var actual = bitwise_and_result.ToArray<int>();
21+
Assert.IsTrue(Enumerable.SequenceEqual(expected, actual));
22+
}
23+
24+
[TestMethod]
25+
public void BitwiseOr()
26+
{
27+
Tensor lhs = tf.constant(new int[] { 0, 5, 3, 14 });
28+
Tensor rhs = tf.constant(new int[] { 5, 0, 7, 11 });
29+
30+
var bitwise_or_result = tf.bitwise.bitwise_or(lhs, rhs);
31+
var expected = new int[] { 5, 5, 7, 15 };
32+
var actual = bitwise_or_result.ToArray<int>();
33+
Assert.IsTrue(Enumerable.SequenceEqual(expected, actual));
34+
}
35+
36+
[TestMethod]
37+
public void BitwiseXOR()
38+
{
39+
Tensor lhs = tf.constant(new int[] { 0, 5, 3, 14 });
40+
Tensor rhs = tf.constant(new int[] { 5, 0, 7, 11 });
41+
42+
var bitwise_xor_result = tf.bitwise.bitwise_xor(lhs, rhs);
43+
var expected = new int[] { 5, 5, 4, 5 };
44+
var actual = bitwise_xor_result.ToArray<int>();
45+
Assert.IsTrue(Enumerable.SequenceEqual(expected, actual));
46+
}
47+
48+
[TestMethod]
49+
public void Invert()
50+
{
51+
Tensor lhs = tf.constant(new int[] { 0, 1, -3, int.MaxValue });
52+
53+
var invert_result = tf.bitwise.invert(lhs);
54+
var expected = new int[] { -1, -2, 2, int.MinValue };
55+
var actual = invert_result.ToArray<int>();
56+
Assert.IsTrue(Enumerable.SequenceEqual(expected, actual));
57+
}
1658

1759
[TestMethod]
1860
public void LeftShift()
1961
{
62+
Tensor lhs = tf.constant(new int[] { -1, -5, -3, -14 });
63+
Tensor rhs = tf.constant(new int[] { 5, 0, 7, 11 });
64+
2065
var left_shift_result = tf.bitwise.left_shift(lhs, rhs);
2166
var expected = new int[] { -32, -5, -384, -28672 };
2267
var actual = left_shift_result.ToArray<int>();
2368
Assert.IsTrue(Enumerable.SequenceEqual(expected, actual));
2469
}
70+
71+
[TestMethod]
72+
public void RightShift()
73+
{
74+
Tensor lhs = tf.constant(new int[] { -2, 64, 101, 32 });
75+
Tensor rhs = tf.constant(new int[] { -1, -5, -3, -14 });
76+
77+
var right_shift_result = tf.bitwise.right_shift(lhs, rhs);
78+
var expected = new int[] { -2, 64, 101, 32 };
79+
var actual = right_shift_result.ToArray<int>();
80+
Assert.IsTrue(Enumerable.SequenceEqual(expected, actual));
81+
}
82+
2583
}
2684
}

0 commit comments

Comments
 (0)