Skip to content

Commit 21c9824

Browse files
Merge pull request tensorflow#52576 from johan-gras:upstream/batchspaceint16
PiperOrigin-RevId: 525449619
2 parents c7d809a + bd57f89 commit 21c9824

File tree

14 files changed

+321
-95
lines changed

14 files changed

+321
-95
lines changed

RELEASE.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@
4343
clustering.
4444
* Add int16x8 support for the built-in op `exp`
4545
* Add int16x8 support for the built-in op `mirror_pad`
46+
* Add int16x8 support for the built-in ops `space_to_batch_nd` and
47+
`batch_to_space_nd`
4648
* Add 16-bit int type support for built-in op `less`, `greater_than`,
4749
`equal`
4850
* Add 8-bit and 16-bit support for `floor_div` and `floor_mod`.

tensorflow/compiler/mlir/lite/ir/tfl_ops.td

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3588,13 +3588,13 @@ def TFL_BatchToSpaceNdOp: TFL_Op<"batch_to_space_nd", [
35883588
}];
35893589

35903590
let arguments = (ins
3591-
TFL_TensorOf<[F32, I8, I32, I64, UI8, QI8, QUI8]>:$input,
3591+
TFL_TensorOf<[F32, I8, I32, I64, UI8, QI8, QUI8, QI16]>:$input,
35923592
TFL_TensorOf<[I32]>:$block_shape,
35933593
TFL_TensorOf<[I32]>:$indices
35943594
);
35953595

35963596
let results = (outs
3597-
TFL_TensorOf<[F32, I16, I32, I64, UI8, QI8, QUI8]>:$output
3597+
TFL_TensorOf<[F32, I16, I32, I64, UI8, QI8, QUI8, QI16]>:$output
35983598
);
35993599
}
36003600

@@ -3613,13 +3613,13 @@ def TFL_SpaceToBatchNdOp: TFL_Op<"space_to_batch_nd", [
36133613
}];
36143614

36153615
let arguments = (ins
3616-
TFL_TensorOf<[F32, I32, I64, QI8, QUI8, TFL_Quint8]>:$input,
3616+
TFL_TensorOf<[F32, I32, I64, QI8, QUI8, TFL_Quint8, QI16]>:$input,
36173617
TFL_I32Tensor:$block_shape,
36183618
TFL_I32Tensor:$paddings
36193619
);
36203620

36213621
let results = (outs
3622-
TFL_TensorOf<[F32, I32, I64, QI8, QUI8, TFL_Quint8]>:$output
3622+
TFL_TensorOf<[F32, I32, I64, QI8, QUI8, TFL_Quint8, QI16]>:$output
36233623
);
36243624
}
36253625

tensorflow/lite/core/kernels/register.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,10 +96,10 @@ BuiltinOpResolver::BuiltinOpResolver() {
9696
/* max_version */ 5);
9797
AddBuiltin(BuiltinOperator_SPACE_TO_BATCH_ND, Register_SPACE_TO_BATCH_ND(),
9898
/* min_version = */ 1,
99-
/* max_version = */ 3);
99+
/* max_version = */ 4);
100100
AddBuiltin(BuiltinOperator_BATCH_TO_SPACE_ND, Register_BATCH_TO_SPACE_ND(),
101101
/* min_version = */ 1,
102-
/* max_version = */ 3);
102+
/* max_version = */ 4);
103103
AddBuiltin(BuiltinOperator_MUL, Register_MUL(), /* min_version = */ 1,
104104
/* max_version = */ 7);
105105
AddBuiltin(BuiltinOperator_L2_NORMALIZATION, Register_L2_NORMALIZATION(),

tensorflow/lite/kernels/batch_to_space_nd.cc

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,20 @@ TfLiteStatus Prepare(TfLiteContext* context, TfLiteNode* node) {
103103
NumDimensions(op_context.input) <= kInputMaxDimensionNum);
104104
TF_LITE_ENSURE_EQ(context, op_context.input->type, op_context.output->type);
105105

106+
if (op_context.input->type == kTfLiteUInt8 ||
107+
op_context.input->type == kTfLiteInt8 ||
108+
op_context.input->type == kTfLiteInt16) {
109+
TF_LITE_ENSURE_EQ(context, op_context.input->params.scale,
110+
op_context.output->params.scale);
111+
TF_LITE_ENSURE_EQ(context, op_context.input->params.zero_point,
112+
op_context.output->params.zero_point);
113+
}
114+
115+
if (op_context.input->type == kTfLiteInt16) {
116+
TF_LITE_ENSURE_EQ(context, op_context.input->params.zero_point, 0);
117+
TF_LITE_ENSURE_EQ(context, op_context.output->params.zero_point, 0);
118+
}
119+
106120
if (!IsConstantOrPersistentTensor(op_context.block_shape) ||
107121
!IsConstantOrPersistentTensor(op_context.crops)) {
108122
SetTensorToDynamic(op_context.output);
@@ -151,6 +165,13 @@ TfLiteStatus Eval(TfLiteContext* context, TfLiteNode* node) {
151165
TF_LITE_BATCH_TO_SPACE_ND(optimized_ops, int8_t);
152166
}
153167
break;
168+
case kTfLiteInt16:
169+
if (kernel_type == kReference) {
170+
TF_LITE_BATCH_TO_SPACE_ND(reference_ops, int16_t);
171+
} else {
172+
TF_LITE_BATCH_TO_SPACE_ND(optimized_ops, int16_t);
173+
}
174+
break;
154175
case kTfLiteInt32:
155176
if (kernel_type == kReference) {
156177
TF_LITE_BATCH_TO_SPACE_ND(reference_ops, int32_t);

tensorflow/lite/kernels/batch_to_space_nd_test.cc

Lines changed: 128 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,19 @@ class BatchToSpaceNDOpModel : public SingleOpModel {
4444
PopulateTensor<int>(crops_, data);
4545
}
4646

47+
int input_tensor_id() { return input_; }
48+
4749
template <typename T>
4850
std::vector<T> GetOutput() {
4951
return ExtractVector<T>(output_);
5052
}
5153

54+
template <typename T>
55+
std::vector<float> GetDequantizedOutput() {
56+
return Dequantize<T>(ExtractVector<T>(output_), GetScale(output_),
57+
GetZeroPoint(output_));
58+
}
59+
5260
int32_t GetOutputSize() { return GetTensorSize(output_); }
5361
std::vector<int> GetOutputShape() { return GetTensorShape(output_); }
5462

@@ -67,20 +75,20 @@ class BatchToSpaceNDOpModel : public SingleOpModel {
6775
// m.Invoke();
6876
class BatchToSpaceNDOpConstModel : public BatchToSpaceNDOpModel {
6977
public:
70-
BatchToSpaceNDOpConstModel(std::initializer_list<int> input_shape,
78+
BatchToSpaceNDOpConstModel(const TensorData& input,
7179
std::initializer_list<int> block_shape,
7280
std::initializer_list<int> crops,
73-
const TensorType& type = TensorType_FLOAT32) {
81+
const TensorData& output) {
7482
int spatial_dims = static_cast<int>(block_shape.size());
75-
input_ = AddInput({type, input_shape});
83+
input_ = AddInput(input);
7684
block_shape_ = AddConstInput(TensorType_INT32, block_shape, {spatial_dims});
7785
crops_ = AddConstInput(TensorType_INT32, crops, {spatial_dims, 2});
78-
output_ = AddOutput(type);
86+
output_ = AddOutput(output);
7987

8088
SetBuiltinOp(BuiltinOperator_BATCH_TO_SPACE_ND,
8189
BuiltinOptions_BatchToSpaceNDOptions,
8290
CreateBatchToSpaceNDOptions(builder_).Union());
83-
BuildInterpreter({input_shape});
91+
BuildInterpreter({GetShape(input_)});
8492
}
8593
};
8694

@@ -94,23 +102,32 @@ class BatchToSpaceNDOpConstModel : public BatchToSpaceNDOpModel {
94102
// m.Invoke();
95103
class BatchToSpaceNDOpDynamicModel : public BatchToSpaceNDOpModel {
96104
public:
97-
BatchToSpaceNDOpDynamicModel(std::initializer_list<int> input_shape,
98-
const TensorType& type = TensorType_FLOAT32) {
99-
input_ = AddInput({type, input_shape});
105+
BatchToSpaceNDOpDynamicModel(const TensorData& input,
106+
const TensorData& output) {
107+
input_ = AddInput(input);
100108
block_shape_ = AddInput(TensorType_INT32);
101109
crops_ = AddInput(TensorType_INT32);
102-
output_ = AddOutput(type);
110+
output_ = AddOutput(output);
103111

104-
int spatial_dims = static_cast<int>(input_shape.size()) - 2;
112+
int spatial_dims = static_cast<int>(GetShape(input_).size()) - 2;
105113
SetBuiltinOp(BuiltinOperator_BATCH_TO_SPACE_ND,
106114
BuiltinOptions_BatchToSpaceNDOptions,
107115
CreateBatchToSpaceNDOptions(builder_).Union());
108-
BuildInterpreter({input_shape, {spatial_dims}, {spatial_dims, 2}});
116+
BuildInterpreter({GetShape(input_), {spatial_dims}, {spatial_dims, 2}});
109117
}
110118
};
111119

120+
template <typename integer_type>
121+
float GetTolerance(float min, float max) {
122+
float kQuantizedStep =
123+
(max - min) / (std::numeric_limits<integer_type>::max() -
124+
std::numeric_limits<integer_type>::min());
125+
return kQuantizedStep;
126+
}
127+
112128
TEST(BatchToSpaceNDOpTest, SimpleConstTest) {
113-
BatchToSpaceNDOpConstModel m({4, 2, 2, 1}, {2, 2}, {0, 0, 0, 0});
129+
BatchToSpaceNDOpConstModel m({TensorType_FLOAT32, {4, 2, 2, 1}}, {2, 2},
130+
{0, 0, 0, 0}, {TensorType_FLOAT32});
114131
m.SetInput<float>({1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16});
115132
ASSERT_EQ(m.Invoke(), kTfLiteOk);
116133
EXPECT_THAT(m.GetOutputShape(), ElementsAreArray({1, 4, 4, 1}));
@@ -120,8 +137,8 @@ TEST(BatchToSpaceNDOpTest, SimpleConstTest) {
120137
}
121138

122139
TEST(BatchToSpaceNDOpTest, SimpleConstTestInt8) {
123-
BatchToSpaceNDOpConstModel m({4, 2, 2, 1}, {2, 2}, {0, 0, 0, 0},
124-
TensorType_INT8);
140+
BatchToSpaceNDOpConstModel m({TensorType_INT8, {4, 2, 2, 1}}, {2, 2},
141+
{0, 0, 0, 0}, {TensorType_INT8});
125142
m.SetInput<int8_t>({1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16});
126143
ASSERT_EQ(m.Invoke(), kTfLiteOk);
127144
EXPECT_THAT(m.GetOutputShape(), ElementsAreArray({1, 4, 4, 1}));
@@ -131,7 +148,8 @@ TEST(BatchToSpaceNDOpTest, SimpleConstTestInt8) {
131148
}
132149

133150
TEST(BatchToSpaceNDOpTest, BatchOneConstTest) {
134-
BatchToSpaceNDOpConstModel m({1, 2, 2, 1}, {1, 1}, {0, 0, 0, 0});
151+
BatchToSpaceNDOpConstModel m({TensorType_FLOAT32, {1, 2, 2, 1}}, {1, 1},
152+
{0, 0, 0, 0}, {TensorType_FLOAT32});
135153
m.SetInput<float>({1, 2, 3, 4});
136154
ASSERT_EQ(m.Invoke(), kTfLiteOk);
137155
EXPECT_THAT(m.GetOutputShape(), ElementsAreArray({1, 2, 2, 1}));
@@ -144,16 +162,17 @@ TEST(BatchToSpaceNDOpTest, SimpleConstTestInt8EmptyOutput) {
144162
return;
145163
}
146164

147-
BatchToSpaceNDOpConstModel m({4, 2, 2, 1}, {2, 2}, {0, 0, 2, 2},
148-
TensorType_INT8);
165+
BatchToSpaceNDOpConstModel m({TensorType_INT8, {4, 2, 2, 1}}, {2, 2},
166+
{0, 0, 2, 2}, {TensorType_INT8});
149167
m.SetInput<int8_t>({1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16});
150168
ASSERT_EQ(m.Invoke(), kTfLiteOk);
151169
EXPECT_THAT(m.GetOutputShape(), ElementsAreArray({1, 4, 0, 1}));
152170
EXPECT_THAT(m.GetOutputSize(), 0);
153171
}
154172

155173
TEST(BatchToSpaceNDOpTest, SimpleDynamicTest) {
156-
BatchToSpaceNDOpDynamicModel m({4, 2, 2, 1});
174+
BatchToSpaceNDOpDynamicModel m({TensorType_FLOAT32, {4, 2, 2, 1}},
175+
{TensorType_FLOAT32});
157176
m.SetInput<float>({1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16});
158177
m.SetBlockShape({2, 2});
159178
m.SetCrops({0, 0, 0, 0});
@@ -165,7 +184,8 @@ TEST(BatchToSpaceNDOpTest, SimpleDynamicTest) {
165184
}
166185

167186
TEST(BatchToSpaceNDOpTest, SimpleDynamicTestInt8) {
168-
BatchToSpaceNDOpDynamicModel m({4, 2, 2, 1}, TensorType_INT8);
187+
BatchToSpaceNDOpDynamicModel m({TensorType_INT8, {4, 2, 2, 1}},
188+
{TensorType_INT8});
169189
m.SetInput<int8_t>({1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16});
170190
m.SetBlockShape({2, 2});
171191
m.SetCrops({0, 0, 0, 0});
@@ -177,7 +197,8 @@ TEST(BatchToSpaceNDOpTest, SimpleDynamicTestInt8) {
177197
}
178198

179199
TEST(BatchToSpaceNDOpTest, InvalidCropsDynamicTest) {
180-
BatchToSpaceNDOpDynamicModel m({4, 2, 2, 1});
200+
BatchToSpaceNDOpDynamicModel m({TensorType_FLOAT32, {4, 2, 2, 1}},
201+
{TensorType_FLOAT32});
181202
m.SetInput<float>({1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16});
182203
m.SetBlockShape({2, 2});
183204
m.SetCrops({0, 0, -1, 0});
@@ -190,7 +211,8 @@ TEST(BatchToSpaceNDOpTest, SimpleDynamicTestInt8EmptyOutput) {
190211
return;
191212
}
192213

193-
BatchToSpaceNDOpDynamicModel m({4, 2, 2, 1}, TensorType_INT8);
214+
BatchToSpaceNDOpDynamicModel m({TensorType_INT8, {4, 2, 2, 1}},
215+
{TensorType_INT8});
194216
m.SetInput<int8_t>({1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16});
195217
m.SetBlockShape({2, 2});
196218
m.SetCrops({2, 2, 0, 0});
@@ -201,18 +223,23 @@ TEST(BatchToSpaceNDOpTest, SimpleDynamicTestInt8EmptyOutput) {
201223

202224
#if GTEST_HAS_DEATH_TEST
203225
TEST(BatchToSpaceNDOpTest, InvalidShapeTest) {
204-
EXPECT_DEATH(BatchToSpaceNDOpConstModel({3, 2, 2, 1}, {2, 2}, {0, 0, 0, 0}),
205-
"Cannot allocate tensors");
226+
EXPECT_DEATH(
227+
BatchToSpaceNDOpConstModel({TensorType_FLOAT32, {3, 2, 2, 1}}, {2, 2},
228+
{0, 0, 0, 0}, {TensorType_FLOAT32}),
229+
"Cannot allocate tensors");
206230
}
207231

208232
TEST(BatchToSpaceNDOpTest, InvalidCropsConstTest) {
209-
EXPECT_DEATH(BatchToSpaceNDOpConstModel({3, 2, 2, 1}, {2, 2}, {0, 0, 0, -1}),
210-
"crops.i. >= 0 was not true.");
233+
EXPECT_DEATH(
234+
BatchToSpaceNDOpConstModel({TensorType_FLOAT32, {3, 2, 2, 1}}, {2, 2},
235+
{0, 0, 0, -1}, {TensorType_FLOAT32}),
236+
"crops.i. >= 0 was not true.");
211237
}
212238
#endif
213239

214240
TEST(BatchToSpaceNDOpTest, Simple3DConstTest) {
215-
BatchToSpaceNDOpConstModel m({4, 4, 1}, {2}, {0, 0});
241+
BatchToSpaceNDOpConstModel m({TensorType_FLOAT32, {4, 4, 1}}, {2}, {0, 0},
242+
{TensorType_FLOAT32});
216243
m.SetInput<float>({1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16});
217244
ASSERT_EQ(m.Invoke(), kTfLiteOk);
218245
EXPECT_THAT(m.GetOutputShape(), ElementsAreArray({2, 8, 1}));
@@ -222,16 +249,52 @@ TEST(BatchToSpaceNDOpTest, Simple3DConstTest) {
222249
}
223250

224251
TEST(BatchToSpaceNDOpTest, Simple3DConstTestWithCrops) {
225-
BatchToSpaceNDOpConstModel m({4, 4, 1}, {2}, {1, 1});
252+
BatchToSpaceNDOpConstModel m({TensorType_FLOAT32, {4, 4, 1}}, {2}, {1, 1},
253+
{TensorType_FLOAT32});
226254
m.SetInput<float>({1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16});
227255
ASSERT_EQ(m.Invoke(), kTfLiteOk);
228256
EXPECT_THAT(m.GetOutputShape(), ElementsAreArray({2, 6, 1}));
229257
EXPECT_THAT(m.GetOutput<float>(),
230258
ElementsAreArray({9, 2, 10, 3, 11, 4, 13, 6, 14, 7, 15, 8}));
231259
}
232260

261+
template <typename integer_dtype>
262+
void Simple3DConstTestWithCropsQuant() {
263+
const float kMin = -1;
264+
const float kMax =
265+
std::numeric_limits<integer_dtype>::max() /
266+
static_cast<float>(std::numeric_limits<integer_dtype>::max() + 1);
267+
float kQuantizedTolerance = GetTolerance<integer_dtype>(-16.0f, 16.0f);
268+
BatchToSpaceNDOpConstModel m(
269+
{GetTensorType<integer_dtype>(), {4, 4, 1}, 16.0f * kMin, 16.0f * kMax},
270+
{2}, {1, 1},
271+
{GetTensorType<integer_dtype>(), {}, 16.0f * kMin, 16.0f * kMax});
272+
m.QuantizeAndPopulate<integer_dtype>(
273+
m.input_tensor_id(),
274+
{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16});
275+
m.Invoke();
276+
EXPECT_THAT(m.GetOutputShape(), ElementsAreArray({2, 6, 1}));
277+
EXPECT_THAT(
278+
m.GetDequantizedOutput<integer_dtype>(),
279+
ElementsAreArray(ArrayFloatNear({9, 2, 10, 3, 11, 4, 13, 6, 14, 7, 15, 8},
280+
kQuantizedTolerance)));
281+
}
282+
283+
TEST(BatchToSpaceNDOpTest, Simple3DConstTestWithCropsUINT8) {
284+
Simple3DConstTestWithCropsQuant<uint8_t>();
285+
}
286+
287+
TEST(BatchToSpaceNDOpTest, Simple3DConstTestWithCropsINT8) {
288+
Simple3DConstTestWithCropsQuant<int8_t>();
289+
}
290+
291+
TEST(BatchToSpaceNDOpTest, Simple3DConstTestWithCropsINT16) {
292+
Simple3DConstTestWithCropsQuant<int16_t>();
293+
}
294+
233295
TEST(BatchToSpaceNDOpTest, Simple3DDynamicTest) {
234-
BatchToSpaceNDOpDynamicModel m({4, 4, 1});
296+
BatchToSpaceNDOpDynamicModel m({TensorType_FLOAT32, {4, 4, 1}},
297+
{TensorType_FLOAT32});
235298
m.SetInput<float>({1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16});
236299
m.SetBlockShape({2});
237300
m.SetCrops({0, 0});
@@ -243,7 +306,8 @@ TEST(BatchToSpaceNDOpTest, Simple3DDynamicTest) {
243306
}
244307

245308
TEST(BatchToSpaceNDOpTest, Simple3DDynamicTestWithCrops) {
246-
BatchToSpaceNDOpDynamicModel m({4, 4, 1});
309+
BatchToSpaceNDOpDynamicModel m({TensorType_FLOAT32, {4, 4, 1}},
310+
{TensorType_FLOAT32});
247311
m.SetInput<float>({1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16});
248312
m.SetBlockShape({2});
249313
m.SetCrops({1, 1});
@@ -253,5 +317,40 @@ TEST(BatchToSpaceNDOpTest, Simple3DDynamicTestWithCrops) {
253317
ElementsAreArray({9, 2, 10, 3, 11, 4, 13, 6, 14, 7, 15, 8}));
254318
}
255319

320+
template <typename integer_dtype>
321+
void Simple3DDynamicTestWithCropsQuant() {
322+
const float kMin = -1;
323+
const float kMax =
324+
std::numeric_limits<integer_dtype>::max() /
325+
static_cast<float>(std::numeric_limits<integer_dtype>::max() + 1);
326+
float kQuantizedTolerance = GetTolerance<integer_dtype>(-16.0, 16.0);
327+
BatchToSpaceNDOpDynamicModel m(
328+
{GetTensorType<integer_dtype>(), {4, 4, 1}, 16.0f * kMin, 16.0f * kMax},
329+
{GetTensorType<integer_dtype>(), {}, 16.0f * kMin, 16.0f * kMax});
330+
m.QuantizeAndPopulate<integer_dtype>(
331+
m.input_tensor_id(),
332+
{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16});
333+
m.SetBlockShape({2});
334+
m.SetCrops({1, 1});
335+
m.Invoke();
336+
EXPECT_THAT(m.GetOutputShape(), ElementsAreArray({2, 6, 1}));
337+
EXPECT_THAT(
338+
m.GetDequantizedOutput<integer_dtype>(),
339+
ElementsAreArray(ArrayFloatNear({9, 2, 10, 3, 11, 4, 13, 6, 14, 7, 15, 8},
340+
kQuantizedTolerance)));
341+
}
342+
343+
TEST(BatchToSpaceNDOpTest, Simple3DDynamicTestWithCropsQuantUINT8) {
344+
Simple3DDynamicTestWithCropsQuant<uint8_t>();
345+
}
346+
347+
TEST(BatchToSpaceNDOpTest, Simple3DDynamicTestWithCropsQuantINT8) {
348+
Simple3DDynamicTestWithCropsQuant<int8_t>();
349+
}
350+
351+
TEST(BatchToSpaceNDOpTest, Simple3DDynamicTestWithCropsQuantINT16) {
352+
Simple3DDynamicTestWithCropsQuant<int16_t>();
353+
}
354+
256355
} // namespace
257356
} // namespace tflite

tensorflow/lite/kernels/register_ref.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -281,11 +281,11 @@ BuiltinRefOpResolver::BuiltinRefOpResolver() {
281281
AddBuiltin(BuiltinOperator_SPACE_TO_BATCH_ND,
282282
Register_SPACE_TO_BATCH_ND_REF(),
283283
/* min_version = */ 1,
284-
/* max_version = */ 3);
284+
/* max_version = */ 4);
285285
AddBuiltin(BuiltinOperator_BATCH_TO_SPACE_ND,
286286
Register_BATCH_TO_SPACE_ND_REF(),
287287
/* min_version = */ 1,
288-
/* max_version = */ 3);
288+
/* max_version = */ 4);
289289
AddBuiltin(BuiltinOperator_MUL, Register_MUL_REF(), /* min_version = */ 1,
290290
/* max_version = */ 7);
291291
AddBuiltin(BuiltinOperator_L2_NORMALIZATION, Register_L2NORM_REF(),

0 commit comments

Comments
 (0)