Skip to content

Commit bd35e62

Browse files
hariharans29wschin
authored andcommitted
Fix some backend tests (#2335)
* Fix some node tests * PR comments and docs * Update Changelog.md
1 parent 23bb6ea commit bd35e62

9 files changed

Lines changed: 88 additions & 54 deletions

File tree

docs/Changelog.md

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11434,11 +11434,9 @@ This version of the operator has been available since version 11 of the default
1143411434
### <a name="Hardmax-11"></a>**Hardmax-11**</a>
1143511435

1143611436
The operator computes the hardmax (1 for the first maximum value, and 0 for all others) values for each layer in the batch
11437-
of the given input. The input is a 2-D tensor (Tensor<float>) of size
11438-
(batch_size x input_feature_dimensions). The output tensor has the same shape
11439-
and contains the hardmax values of the corresponding input.
11437+
of the given input.
1144011438

11441-
Input does not need to explicitly be a 2D vector; rather, it will be
11439+
The input does not need to explicitly be a 2D vector; rather, it will be
1144211440
coerced into one. For an arbitrary n-dimensional tensor
1144311441
input \in [a_0, a_1, ..., a_{k-1}, a_k, ..., a_{n-1}] and k is
1144411442
the axis provided, then input will be coerced into a 2-dimensional tensor with
@@ -11447,7 +11445,8 @@ This version of the operator has been available since version 11 of the default
1144711445
of dimensions [a_0, a_1 * ... * a_{n-1}], where a_0 is often the batch size.
1144811446
In this situation, we must have a_0 = N and a_1 * ... * a_{n-1} = D.
1144911447
Each of these dimensions must be matched correctly, or else the operator
11450-
will throw errors.
11448+
will throw errors. The output tensor has the same shape
11449+
and contains the hardmax values of the corresponding input.
1145111450

1145211451
#### Version
1145311452

@@ -11484,11 +11483,9 @@ This version of the operator has been available since version 11 of the default
1148411483
### <a name="LogSoftmax-11"></a>**LogSoftmax-11**</a>
1148511484

1148611485
The operator computes the logsoftmax (log of softmax) values for each layer in the batch
11487-
of the given input. The input is a 2-D tensor (Tensor<float>) of size
11488-
(batch_size x input_feature_dimensions). The output tensor has the same shape
11489-
and contains the logsoftmax values of the corresponding input.
11486+
of the given input.
1149011487

11491-
Input does not need to explicitly be a 2D vector; rather, it will be
11488+
The input does not need to explicitly be a 2D vector; rather, it will be
1149211489
coerced into one. For an arbitrary n-dimensional tensor
1149311490
input \in [a_0, a_1, ..., a_{k-1}, a_k, ..., a_{n-1}] and k is
1149411491
the axis provided, then input will be coerced into a 2-dimensional tensor with
@@ -11497,7 +11494,8 @@ This version of the operator has been available since version 11 of the default
1149711494
of dimensions [a_0, a_1 * ... * a_{n-1}], where a_0 is often the batch size.
1149811495
In this situation, we must have a_0 = N and a_1 * ... * a_{n-1} = D.
1149911496
Each of these dimensions must be matched correctly, or else the operator
11500-
will throw errors.
11497+
will throw errors. The output tensor has the same shape
11498+
and contains the logsoftmax values of the corresponding input.
1150111499

1150211500
#### Version
1150311501

@@ -13362,11 +13360,9 @@ This version of the operator has been available since version 11 of the default
1336213360
### <a name="Softmax-11"></a>**Softmax-11**</a>
1336313361

1336413362
The operator computes the softmax (normalized exponential) values for each layer in the batch
13365-
of the given input. The input is a 2-D tensor (Tensor<float>) of size
13366-
(batch_size x input_feature_dimensions). The output tensor has the same shape
13367-
and contains the softmax values of the corresponding input.
13363+
of the given input.
1336813364

13369-
Input does not need to explicitly be a 2D vector; rather, it will be
13365+
The input does not need to explicitly be a 2D vector; rather, it will be
1337013366
coerced into one. For an arbitrary n-dimensional tensor
1337113367
input \in [a_0, a_1, ..., a_{k-1}, a_k, ..., a_{n-1}] and k is
1337213368
the axis provided, then input will be coerced into a 2-dimensional tensor with
@@ -13375,7 +13371,8 @@ This version of the operator has been available since version 11 of the default
1337513371
of dimensions [a_0, a_1 * ... * a_{n-1}], where a_0 is often the batch size.
1337613372
In this situation, we must have a_0 = N and a_1 * ... * a_{n-1} = D.
1337713373
Each of these dimensions must be matched correctly, or else the operator
13378-
will throw errors.
13374+
will throw errors. The output tensor has the same shape
13375+
and contains the softmax values of the corresponding input.
1337913376

1338013377
#### Version
1338113378

docs/Operators.md

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5221,7 +5221,7 @@ node = onnx.helper.make_node(
52215221
'Gather',
52225222
inputs=['data', 'indices'],
52235223
outputs=['y'],
5224-
axis=1,
5224+
axis=0,
52255225
)
52265226
data = np.arange(10).astype(np.float32)
52275227
indices = np.array([0, -9, -10])
@@ -5738,7 +5738,7 @@ node = onnx.helper.make_node(
57385738
)
57395739
a = np.random.ranf([2, 3]).astype(np.float32)
57405740
b = np.random.ranf([3, 4]).astype(np.float32)
5741-
c = np.array(3.14)
5741+
c = np.array(3.14).astype(np.float32)
57425742
y = gemm_reference_implementation(a, b, c)
57435743
expect(node, inputs=[a, b, c], outputs=[y],
57445744
name='test_gemm_default_scalar_bias')
@@ -6218,11 +6218,9 @@ expect(node, inputs=[x], outputs=[y],
62186218
### <a name="Hardmax"></a><a name="hardmax">**Hardmax**</a>
62196219

62206220
The operator computes the hardmax (1 for the first maximum value, and 0 for all others) values for each layer in the batch
6221-
of the given input. The input is a 2-D tensor (Tensor<float>) of size
6222-
(batch_size x input_feature_dimensions). The output tensor has the same shape
6223-
and contains the hardmax values of the corresponding input.
6221+
of the given input.
62246222

6225-
Input does not need to explicitly be a 2D vector; rather, it will be
6223+
The input does not need to explicitly be a 2D vector; rather, it will be
62266224
coerced into one. For an arbitrary n-dimensional tensor
62276225
input \in [a_0, a_1, ..., a_{k-1}, a_k, ..., a_{n-1}] and k is
62286226
the axis provided, then input will be coerced into a 2-dimensional tensor with
@@ -6231,7 +6229,8 @@ expect(node, inputs=[x], outputs=[y],
62316229
of dimensions [a_0, a_1 * ... * a_{n-1}], where a_0 is often the batch size.
62326230
In this situation, we must have a_0 = N and a_1 * ... * a_{n-1} = D.
62336231
Each of these dimensions must be matched correctly, or else the operator
6234-
will throw errors.
6232+
will throw errors. The output tensor has the same shape
6233+
and contains the hardmax values of the corresponding input.
62356234

62366235
#### Version
62376236

@@ -7303,11 +7302,9 @@ expect(node, inputs=[x], outputs=[y],
73037302
### <a name="LogSoftmax"></a><a name="logsoftmax">**LogSoftmax**</a>
73047303

73057304
The operator computes the logsoftmax (log of softmax) values for each layer in the batch
7306-
of the given input. The input is a 2-D tensor (Tensor<float>) of size
7307-
(batch_size x input_feature_dimensions). The output tensor has the same shape
7308-
and contains the logsoftmax values of the corresponding input.
7305+
of the given input.
73097306

7310-
Input does not need to explicitly be a 2D vector; rather, it will be
7307+
The input does not need to explicitly be a 2D vector; rather, it will be
73117308
coerced into one. For an arbitrary n-dimensional tensor
73127309
input \in [a_0, a_1, ..., a_{k-1}, a_k, ..., a_{n-1}] and k is
73137310
the axis provided, then input will be coerced into a 2-dimensional tensor with
@@ -7316,7 +7313,8 @@ expect(node, inputs=[x], outputs=[y],
73167313
of dimensions [a_0, a_1 * ... * a_{n-1}], where a_0 is often the batch size.
73177314
In this situation, we must have a_0 = N and a_1 * ... * a_{n-1} = D.
73187315
Each of these dimensions must be matched correctly, or else the operator
7319-
will throw errors.
7316+
will throw errors. The output tensor has the same shape
7317+
and contains the logsoftmax values of the corresponding input.
73207318

73217319
#### Version
73227320

@@ -16427,11 +16425,9 @@ expect(node, inputs=[x, starts, ends, axes, steps], outputs=[y],
1642716425
### <a name="Softmax"></a><a name="softmax">**Softmax**</a>
1642816426

1642916427
The operator computes the softmax (normalized exponential) values for each layer in the batch
16430-
of the given input. The input is a 2-D tensor (Tensor<float>) of size
16431-
(batch_size x input_feature_dimensions). The output tensor has the same shape
16432-
and contains the softmax values of the corresponding input.
16428+
of the given input.
1643316429

16434-
Input does not need to explicitly be a 2D vector; rather, it will be
16430+
The input does not need to explicitly be a 2D vector; rather, it will be
1643516431
coerced into one. For an arbitrary n-dimensional tensor
1643616432
input \in [a_0, a_1, ..., a_{k-1}, a_k, ..., a_{n-1}] and k is
1643716433
the axis provided, then input will be coerced into a 2-dimensional tensor with
@@ -16440,7 +16436,8 @@ expect(node, inputs=[x, starts, ends, axes, steps], outputs=[y],
1644016436
of dimensions [a_0, a_1 * ... * a_{n-1}], where a_0 is often the batch size.
1644116437
In this situation, we must have a_0 = N and a_1 * ... * a_{n-1} = D.
1644216438
Each of these dimensions must be matched correctly, or else the operator
16443-
will throw errors.
16439+
will throw errors. The output tensor has the same shape
16440+
and contains the softmax values of the corresponding input.
1644416441

1644516442
#### Version
1644616443

docs/TestCoverage.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2898,7 +2898,7 @@ node = onnx.helper.make_node(
28982898
'Gather',
28992899
inputs=['data', 'indices'],
29002900
outputs=['y'],
2901-
axis=1,
2901+
axis=0,
29022902
)
29032903
data = np.arange(10).astype(np.float32)
29042904
indices = np.array([0, -9, -10])
@@ -3147,7 +3147,7 @@ node = onnx.helper.make_node(
31473147
)
31483148
a = np.random.ranf([2, 3]).astype(np.float32)
31493149
b = np.random.ranf([3, 4]).astype(np.float32)
3150-
c = np.array(3.14)
3150+
c = np.array(3.14).astype(np.float32)
31513151
y = gemm_reference_implementation(a, b, c)
31523152
expect(node, inputs=[a, b, c], outputs=[y],
31533153
name='test_gemm_default_scalar_bias')

onnx/backend/test/case/node/gather.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ def export_gather_negative_indices(): # type: () -> None
4848
'Gather',
4949
inputs=['data', 'indices'],
5050
outputs=['y'],
51-
axis=1,
51+
axis=0,
5252
)
5353
data = np.arange(10).astype(np.float32)
5454
indices = np.array([0, -9, -10])

onnx/backend/test/case/node/gemm.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ def export_default_scalar_bias(): # type: () -> None
6060
)
6161
a = np.random.ranf([2, 3]).astype(np.float32)
6262
b = np.random.ranf([3, 4]).astype(np.float32)
63-
c = np.array(3.14)
63+
c = np.array(3.14).astype(np.float32)
6464
y = gemm_reference_implementation(a, b, c)
6565
expect(node, inputs=[a, b, c], outputs=[y],
6666
name='test_gemm_default_scalar_bias')
Binary file not shown.
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
 BcJ��Q� @
1+
BcJ��H@

onnx/defs/math/defs.cc

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,9 @@ std::function<void(OpSchema&)> SoftmaxFamilyDocGenerator(
4141
return [=](OpSchema& schema) {
4242
std::string doc = R"DOC(
4343
The operator computes the {name} ({description}) values for each layer in the batch
44-
of the given input. The input is a 2-D tensor (Tensor<float>) of size
45-
(batch_size x input_feature_dimensions). The output tensor has the same shape
46-
and contains the {name} values of the corresponding input.
44+
of the given input.
4745

48-
Input does not need to explicitly be a 2D vector; rather, it will be
46+
The input does not need to explicitly be a 2D vector; rather, it will be
4947
coerced into one. For an arbitrary n-dimensional tensor
5048
input \in [a_0, a_1, ..., a_{k-1}, a_k, ..., a_{n-1}] and k is
5149
the axis provided, then input will be coerced into a 2-dimensional tensor with
@@ -54,7 +52,8 @@ case where axis=1, this means the input tensor will be coerced into a 2D tensor
5452
of dimensions [a_0, a_1 * ... * a_{n-1}], where a_0 is often the batch size.
5553
In this situation, we must have a_0 = N and a_1 * ... * a_{n-1} = D.
5654
Each of these dimensions must be matched correctly, or else the operator
57-
will throw errors.
55+
will throw errors. The output tensor has the same shape
56+
and contains the {name} values of the corresponding input.
5857
)DOC";
5958
ReplaceAll(doc, "{name}", name);
6059
ReplaceAll(doc, "{description}", description);
@@ -84,27 +83,26 @@ will throw errors.
8483
{"tensor(float16)", "tensor(float)", "tensor(double)"},
8584
"Constrain input and output types to float tensors.");
8685
schema.TypeAndShapeInferenceFunction([](InferenceContext& ctx) {
86+
// Type inference
8787
propagateElemTypeFromInputToOutput(ctx, 0, 0);
88+
89+
// Shape inference starts
8890
if (!hasNInputShapes(ctx, 1)) {
8991
return;
9092
}
91-
propagateShapeFromInputToOutput(ctx, 0, 0);
93+
94+
// Validate the value of 'axis'
9295
const TensorShapeProto& input_shape =
9396
ctx.getInputType(0)->tensor_type().shape();
9497
int r = input_shape.dim_size();
95-
if (r != 2) {
96-
fail_shape_inference("Input tensor must have rank == 2");
97-
}
9898
int axis = static_cast<int>(getAttribute(ctx, "axis", 1));
99-
if (axis){
100-
if (axis < -r || axis >= r) {
99+
if (axis < -r || axis >= r) {
101100
fail_shape_inference(
102-
"'axis' must be in [-rank(indices), rank(indices)-1]");
103-
}
104-
if (axis < 0) {
105-
axis += r;
106-
}
101+
"'axis' must be in [" -r, " , " , (r-1) , "]. Its actual value is: ", axis);
107102
}
103+
104+
// Shape inference
105+
propagateShapeFromInputToOutput(ctx, 0, 0);
108106
});
109107
};
110108
}

onnx/test/shape_inference_test.py

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1135,13 +1135,55 @@ def test_GLU(self): # type: () -> None
11351135
make_tensor_value_info('a', TensorProto.FLOAT, (5, 3, 7)),
11361136
make_tensor_value_info('b', TensorProto.FLOAT, (5, 3, 7))])
11371137

1138-
def test_softmax(self): # type: () -> None
1138+
def test_softmax_2d(self): # type: () -> None
11391139
graph = self._make_graph(
11401140
[('x', TensorProto.FLOAT, (4, 5))],
11411141
[make_node('Softmax', ['x'], 'z')],
11421142
[])
11431143
self._assert_inferred(graph, [make_tensor_value_info('z', TensorProto.FLOAT, (4, 5))])
11441144

1145+
def test_softmax_3d(self): # type: () -> None
1146+
graph = self._make_graph(
1147+
[('x', TensorProto.FLOAT, (4, 5, 6))],
1148+
[make_node('Softmax', ['x'], 'z')],
1149+
[])
1150+
self._assert_inferred(graph, [make_tensor_value_info('z', TensorProto.FLOAT, (4, 5, 6))])
1151+
1152+
def test_hardmax_2d(self): # type: () -> None
1153+
graph = self._make_graph(
1154+
[('x', TensorProto.FLOAT, (4, 5))],
1155+
[make_node('Hardmax', ['x'], 'z')],
1156+
[])
1157+
self._assert_inferred(graph, [make_tensor_value_info('z', TensorProto.FLOAT, (4, 5))])
1158+
1159+
def test_hardmax_3d(self): # type: () -> None
1160+
graph = self._make_graph(
1161+
[('x', TensorProto.FLOAT, (4, 5, 6))],
1162+
[make_node('Hardmax', ['x'], 'z')],
1163+
[])
1164+
self._assert_inferred(graph, [make_tensor_value_info('z', TensorProto.FLOAT, (4, 5, 6))])
1165+
1166+
def test_logsoftmax_2d(self): # type: () -> None
1167+
graph = self._make_graph(
1168+
[('x', TensorProto.FLOAT, (4, 5))],
1169+
[make_node('LogSoftmax', ['x'], 'z')],
1170+
[])
1171+
self._assert_inferred(graph, [make_tensor_value_info('z', TensorProto.FLOAT, (4, 5))])
1172+
1173+
def test_logsoftmax_3d(self): # type: () -> None
1174+
graph = self._make_graph(
1175+
[('x', TensorProto.FLOAT, (4, 5, 6))],
1176+
[make_node('LogSoftmax', ['x'], 'z')],
1177+
[])
1178+
self._assert_inferred(graph, [make_tensor_value_info('z', TensorProto.FLOAT, (4, 5, 6))])
1179+
1180+
def test_logsoftmax_3d_negative_axis(self): # type: () -> None
1181+
graph = self._make_graph(
1182+
[('x', TensorProto.FLOAT, (4, 5, 6))],
1183+
[make_node('LogSoftmax', ['x'], 'z', axis=-1)],
1184+
[])
1185+
self._assert_inferred(graph, [make_tensor_value_info('z', TensorProto.FLOAT, (4, 5, 6))])
1186+
11451187
def test_maxpool(self): # type: () -> None
11461188
graph = self._make_graph(
11471189
[("X", TensorProto.FLOAT, (5, 3, 4, 4))],

0 commit comments

Comments
 (0)