BitShift#
Domain:
ai.onnxSince version: 28
Bitwise shift operator performs element-wise operation. For each input element, if the attribute “direction” is “RIGHT”, this operator moves its binary representation toward the right side. If the attribute “direction” is “LEFT”, bits of binary representation move toward the left side. The input X is the tensor to be shifted and another input Y specifies the amounts of shifting. For example, if “direction” is “RIGHT”, X is [1, 4], and Y is [1, 1], the corresponding output Z would be [0, 2]. If “direction” is “LEFT” with X=[1, 2] and Y=[1, 2], the corresponding output Z would be [2, 8].
For a signed T the right shift is an arithmetic shift (sign-extending). The vacated high bits are filled with copies of the sign bit, so a negative X stays negative. For a signed T a left shift can move bits into and past the sign bit, and bits shifted past the sign bit are discarded.
If Y is negative, or is greater than or equal to the number of bits of T, then the result is whatever the sign bit extension alone produces: -1 for a right shift on a negative X, where the fill is a sign bit of 1, and 0 in every other case.
This operator supports multidirectional (i.e., Numpy-style) broadcasting; for more details please check the doc.
Inputs
X (T): First operand, input to be shifted.
Y (T): Second operand, amounts of shift.
Outputs
Z (T): Output tensor
Attributes
direction (string): Direction of moving bits. It can be either “RIGHT” (for right shift) or “LEFT” (for left shift).
Type Constraints
T: Constrain input and output types to integer tensors. Allowed types: tensor(int16), tensor(int32), tensor(int64), tensor(int8), tensor(uint16), tensor(uint32), tensor(uint64), tensor(uint8).
Examples#
test_bitshift_left_int16
Node:
BitShift(x, y) -> (z)
Attributes:
direction = "LEFT"
Inputs:
x: shape=(3,), dtype=int16
[16, 4, 1]
y: shape=(3,), dtype=int16
[1, 2, 3]
Outputs:
z: shape=(3,), dtype=int16
[32, 16, 8]
test_bitshift_left_int32
Node:
BitShift(x, y) -> (z)
Attributes:
direction = "LEFT"
Inputs:
x: shape=(3,), dtype=int32
[16, 4, 1]
y: shape=(3,), dtype=int32
[1, 2, 3]
Outputs:
z: shape=(3,), dtype=int32
[32, 16, 8]
test_bitshift_left_int32_negative_shift
Node:
BitShift(x, y) -> (z)
Attributes:
direction = "LEFT"
Inputs:
x: shape=(3,), dtype=int32
[-8, 4, -1]
y: shape=(3,), dtype=int32
[ -1, -32, -64]
Outputs:
z: shape=(3,), dtype=int32
[0, 0, 0]
test_bitshift_left_int32_overflow
Node:
BitShift(x, y) -> (z)
Attributes:
direction = "LEFT"
Inputs:
x: shape=(3,), dtype=int32
[ 1073741824, 1, -1073741824]
y: shape=(3,), dtype=int32
[ 1, 31, 1]
Outputs:
z: shape=(3,), dtype=int32
[-2147483648, -2147483648, -2147483648]
test_bitshift_left_int32_shift_ge_width
Node:
BitShift(x, y) -> (z)
Attributes:
direction = "LEFT"
Inputs:
x: shape=(3,), dtype=int32
[-8, 4, -1]
y: shape=(3,), dtype=int32
[ 32, 33, 100]
Outputs:
z: shape=(3,), dtype=int32
[0, 0, 0]
test_bitshift_left_int64
Node:
BitShift(x, y) -> (z)
Attributes:
direction = "LEFT"
Inputs:
x: shape=(3,), dtype=int64
[16, 4, 1]
y: shape=(3,), dtype=int64
[1, 2, 3]
Outputs:
z: shape=(3,), dtype=int64
[32, 16, 8]
test_bitshift_left_int8
Node:
BitShift(x, y) -> (z)
Attributes:
direction = "LEFT"
Inputs:
x: shape=(3,), dtype=int8
[16, 4, 1]
y: shape=(3,), dtype=int8
[1, 2, 3]
Outputs:
z: shape=(3,), dtype=int8
[32, 16, 8]
test_bitshift_left_int8_negative_shift
Node:
BitShift(x, y) -> (z)
Attributes:
direction = "LEFT"
Inputs:
x: shape=(3,), dtype=int8
[-8, 4, -1]
y: shape=(3,), dtype=int8
[ -1, -8, -16]
Outputs:
z: shape=(3,), dtype=int8
[0, 0, 0]
test_bitshift_left_int8_overflow
Node:
BitShift(x, y) -> (z)
Attributes:
direction = "LEFT"
Inputs:
x: shape=(3,), dtype=int8
[ 64, 1, -64]
y: shape=(3,), dtype=int8
[1, 7, 1]
Outputs:
z: shape=(3,), dtype=int8
[-128, -128, -128]
test_bitshift_left_int8_shift_ge_width
Node:
BitShift(x, y) -> (z)
Attributes:
direction = "LEFT"
Inputs:
x: shape=(3,), dtype=int8
[-8, 4, -1]
y: shape=(3,), dtype=int8
[ 8, 9, 127]
Outputs:
z: shape=(3,), dtype=int8
[0, 0, 0]
test_bitshift_right_int16
Node:
BitShift(x, y) -> (z)
Attributes:
direction = "RIGHT"
Inputs:
x: shape=(3,), dtype=int16
[16, 4, 1]
y: shape=(3,), dtype=int16
[1, 2, 3]
Outputs:
z: shape=(3,), dtype=int16
[8, 1, 0]
test_bitshift_right_int32
Node:
BitShift(x, y) -> (z)
Attributes:
direction = "RIGHT"
Inputs:
x: shape=(3,), dtype=int32
[16, 4, 1]
y: shape=(3,), dtype=int32
[1, 2, 3]
Outputs:
z: shape=(3,), dtype=int32
[8, 1, 0]
test_bitshift_right_int32_negative_input
Node:
BitShift(x, y) -> (z)
Attributes:
direction = "RIGHT"
Inputs:
x: shape=(3,), dtype=int32
[ -8, -1, -2147483648]
y: shape=(3,), dtype=int32
[1, 1, 1]
Outputs:
z: shape=(3,), dtype=int32
[ -4, -1, -1073741824]
test_bitshift_right_int32_negative_shift
Node:
BitShift(x, y) -> (z)
Attributes:
direction = "RIGHT"
Inputs:
x: shape=(3,), dtype=int32
[-8, 4, -1]
y: shape=(3,), dtype=int32
[ -1, -32, -64]
Outputs:
z: shape=(3,), dtype=int32
[-1, 0, -1]
test_bitshift_right_int32_shift_ge_width
Node:
BitShift(x, y) -> (z)
Attributes:
direction = "RIGHT"
Inputs:
x: shape=(3,), dtype=int32
[-8, 4, -1]
y: shape=(3,), dtype=int32
[ 32, 33, 100]
Outputs:
z: shape=(3,), dtype=int32
[-1, 0, -1]
test_bitshift_right_int64
Node:
BitShift(x, y) -> (z)
Attributes:
direction = "RIGHT"
Inputs:
x: shape=(3,), dtype=int64
[16, 4, 1]
y: shape=(3,), dtype=int64
[1, 2, 3]
Outputs:
z: shape=(3,), dtype=int64
[8, 1, 0]
test_bitshift_right_int8
Node:
BitShift(x, y) -> (z)
Attributes:
direction = "RIGHT"
Inputs:
x: shape=(3,), dtype=int8
[16, 4, 1]
y: shape=(3,), dtype=int8
[1, 2, 3]
Outputs:
z: shape=(3,), dtype=int8
[8, 1, 0]
test_bitshift_right_int8_negative_input
Node:
BitShift(x, y) -> (z)
Attributes:
direction = "RIGHT"
Inputs:
x: shape=(3,), dtype=int8
[ -8, -1, -128]
y: shape=(3,), dtype=int8
[1, 1, 1]
Outputs:
z: shape=(3,), dtype=int8
[ -4, -1, -64]
test_bitshift_right_int8_negative_shift
Node:
BitShift(x, y) -> (z)
Attributes:
direction = "RIGHT"
Inputs:
x: shape=(3,), dtype=int8
[-8, 4, -1]
y: shape=(3,), dtype=int8
[ -1, -8, -16]
Outputs:
z: shape=(3,), dtype=int8
[-1, 0, -1]
test_bitshift_right_int8_shift_ge_width
Node:
BitShift(x, y) -> (z)
Attributes:
direction = "RIGHT"
Inputs:
x: shape=(3,), dtype=int8
[-8, 4, -1]
y: shape=(3,), dtype=int8
[ 8, 9, 127]
Outputs:
z: shape=(3,), dtype=int8
[-1, 0, -1]
Differences with previous version (11)#
SchemaDiff: BitShift (domain 'ai.onnx')
old version: 11
new version: 28
breaking: no
Type constraints:
changed ‘T’: added types: [‘tensor(int16)’, ‘tensor(int32)’, ‘tensor(int64)’, ‘tensor(int8)’]
Documentation:
line similarity: 0.34 (+15/-8 lines)
--- BitShift v11
+++ BitShift v28
@@ -1,14 +1,21 @@
Bitwise shift operator performs element-wise operation. For each input element, if the
attribute "direction" is "RIGHT", this operator moves its binary representation toward
-the right side so that the input value is effectively decreased. If the attribute "direction"
-is "LEFT", bits of binary representation moves toward the left side, which results the
-increase of its actual value. The input X is the tensor to be shifted and another input
-Y specifies the amounts of shifting. For example, if "direction" is "Right", X is [1, 4],
-and S is [1, 1], the corresponding output Z would be [0, 2]. If "direction" is "LEFT" with
-X=[1, 2] and S=[1, 2], the corresponding output Y would be [2, 8].
+the right side. If the attribute "direction" is "LEFT", bits of binary representation
+move toward the left side. The input X is the tensor to be shifted and another
+input Y specifies the amounts of shifting. For example, if "direction" is
+"RIGHT", X is [1, 4], and Y is [1, 1], the corresponding output Z would be
+[0, 2]. If "direction" is "LEFT" with X=[1, 2] and Y=[1, 2], the corresponding
+output Z would be [2, 8].
-Because this operator supports Numpy-style broadcasting, X's and Y's shapes are
-not necessarily identical.
+For a signed T the right shift is an arithmetic shift (sign-extending). The
+vacated high bits are filled with copies of the sign bit, so a negative X stays
+negative. For a signed T a left shift can move bits into and past the sign bit,
+and bits shifted past the sign bit are discarded.
+
+If Y is negative, or is greater than or equal to the number of bits of T, then
+the result is whatever the sign bit extension alone produces: -1 for a right
+shift on a negative X, where the fill is a sign bit of 1, and 0 in every other
+case.
This operator supports **multidirectional (i.e., Numpy-style) broadcasting**; for more details please check [the doc](Broadcasting.md).