Skip to content

Commit 5ca850f

Browse files
committed
Sync from upstream TF.
1 parent e0b2c28 commit 5ca850f

20 files changed

Lines changed: 400 additions & 343 deletions

tensorflow/lite/core/c/common.h

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ limitations under the License.
5656
#include <stdbool.h>
5757
#include <stddef.h>
5858
#include <stdint.h>
59+
#include <stdio.h>
5960

6061
#include "tensorflow/lite/core/c/c_api_types.h" // IWYU pragma: export
6162

@@ -277,13 +278,34 @@ void TfLiteFloatArrayFree(TfLiteFloatArray* a);
277278
} \
278279
} while (0)
279280

280-
#define TF_LITE_ENSURE_OK(context, status) \
281-
do { \
282-
const TfLiteStatus s = (status); \
283-
if ((s) != kTfLiteOk) { \
284-
return s; \
285-
} \
281+
#ifndef TF_LITE_STRIP_ERROR_STRINGS
282+
#define TF_LITE_VAR_ARG_HEAD(FIRST, ...) FIRST
283+
#define TF_LITE_STRINGIFY_HELPER(x) #x
284+
#define TF_LITE_STRINGIFY(x) TF_LITE_STRINGIFY_HELPER(x)
285+
// Checks that `status` evaluates to `kTfLiteOk`.
286+
//
287+
// Can take a printf style log message and its parameters after the status. The
288+
// message will be printed using `TF_LITE_KERNEL_LOG` in case of error.
289+
#define TF_LITE_ENSURE_OK(context, status, ...) \
290+
do { \
291+
const TfLiteStatus s = (status); \
292+
if (s != kTfLiteOk) { \
293+
if (sizeof(TF_LITE_VAR_ARG_HEAD("" __VA_ARGS__)) > sizeof("")) { \
294+
TF_LITE_MAYBE_KERNEL_LOG((context), __FILE__ ":" TF_LITE_STRINGIFY( \
295+
__LINE__) ": " __VA_ARGS__); \
296+
} \
297+
return s; \
298+
} \
286299
} while (0)
300+
#else
301+
#define TF_LITE_ENSURE_OK(context, status, ...) \
302+
do { \
303+
const TfLiteStatus s = (status); \
304+
if ((s) != kTfLiteOk) { \
305+
return s; \
306+
} \
307+
} while (0)
308+
#endif
287309

288310
// `std::unreachable` not available until CC23.
289311
#ifdef __GNUC__ // GCC, Clang, ICC
@@ -1060,6 +1082,13 @@ typedef struct TfLiteContext {
10601082
/// WARNING: This is an experimental interface that is subject to change.
10611083
TfLiteStatus (*ReleaseSubgraphContext)(struct TfLiteContext* context,
10621084
int subgraph_index);
1085+
#if defined(_WIN32)
1086+
/// Create a array of a given `size` (uninitialized entries).
1087+
TfLiteIntArray* (*TfLiteIntArrayCreate)(int size); // NOLINT
1088+
1089+
/// Free memory of array `a`.
1090+
void (*TfLiteIntArrayFree)(TfLiteIntArray* a); // NOLINT
1091+
#endif // defined(_WIN32)
10631092
} TfLiteContext;
10641093

10651094
/// `TfLiteOperator` is an external version of `TfLiteRegistration`

tensorflow/lite/kernels/internal/common.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,9 @@ bool ReduceDimensionsForBroadcast(const RuntimeShape& input1_shape,
7979
broadcast_input1 = true;
8080
broadcast_input2 = false;
8181
num_compressed_dims++;
82+
if (num_compressed_dims > MAX_DIM) {
83+
return false;
84+
}
8285
}
8386
compressed_input2_shape[num_compressed_dims - 1] *= input2_dim;
8487
compressed_output_shape[num_compressed_dims - 1] *= input2_dim;
@@ -87,6 +90,9 @@ bool ReduceDimensionsForBroadcast(const RuntimeShape& input1_shape,
8790
broadcast_input1 = false;
8891
broadcast_input2 = true;
8992
num_compressed_dims++;
93+
if (num_compressed_dims > MAX_DIM) {
94+
return false;
95+
}
9096
}
9197
compressed_input1_shape[num_compressed_dims - 1] *= input1_dim;
9298
compressed_output_shape[num_compressed_dims - 1] *= input1_dim;
@@ -96,6 +102,9 @@ bool ReduceDimensionsForBroadcast(const RuntimeShape& input1_shape,
96102
broadcast_input1 = false;
97103
broadcast_input2 = false;
98104
num_compressed_dims++;
105+
if (num_compressed_dims > MAX_DIM) {
106+
return false;
107+
}
99108
}
100109
compressed_input1_shape[num_compressed_dims - 1] *= input1_dim;
101110
compressed_input2_shape[num_compressed_dims - 1] *= input1_dim;
@@ -106,6 +115,9 @@ bool ReduceDimensionsForBroadcast(const RuntimeShape& input1_shape,
106115
if (num_input1_dims > num_input2_dims) {
107116
if (!broadcast_input2) {
108117
num_compressed_dims++;
118+
if (num_compressed_dims > MAX_DIM) {
119+
return false;
120+
}
109121
}
110122
for (size_t i = 0; i < num_input1_dims - num_input2_dims; i++) {
111123
const size_t input1_dim = input1_dims[i];
@@ -118,6 +130,9 @@ bool ReduceDimensionsForBroadcast(const RuntimeShape& input1_shape,
118130
} else if (num_input2_dims > num_input1_dims) {
119131
if (!broadcast_input1) {
120132
num_compressed_dims++;
133+
if (num_compressed_dims > MAX_DIM) {
134+
return false;
135+
}
121136
}
122137
for (size_t i = 0; i < num_input2_dims - num_input1_dims; i++) {
123138
const size_t input2_dim = input2_dims[i];

tensorflow/lite/kernels/internal/reference/add.h

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ limitations under the License.
2323
#include "fixedpoint/fixedpoint.h"
2424
#include "tensorflow/lite/kernels/internal/common.h"
2525
#include "tensorflow/lite/kernels/internal/compatibility.h"
26+
#include "tensorflow/lite/kernels/internal/reference/broadcast_loop.h"
2627

2728
namespace tflite {
2829

@@ -39,7 +40,7 @@ inline void Add(const ArithmeticParams& params,
3940
const int flat_size =
4041
MatchingElementsSize(input1_shape, input2_shape, output_shape);
4142
for (int i = 0; i < flat_size; ++i) {
42-
output_data[i] = ActivationFunctionWithMinMax(
43+
output_data[i] = ActivationFunctionWithMinMax<T>(
4344
input1_data[i] + input2_data[i], activation_min, activation_max);
4445
}
4546
}
@@ -328,6 +329,20 @@ BroadcastAdd6DSlow(const ArithmeticParams& params,
328329
constexpr int kMaxBroadcastDim = 6;
329330
T activation_min, activation_max;
330331
GetActivationParams(params, &activation_min, &activation_max);
332+
const int broadcast_rank = std::max(
333+
output_shape.DimensionsCount(),
334+
std::max(input1_shape.DimensionsCount(), input2_shape.DimensionsCount()));
335+
if (broadcast_rank > kMaxBroadcastDim) {
336+
ForEachBroadcastedElement(
337+
input1_shape, input2_shape, output_shape,
338+
[&](int output_index, int input1_index, int input2_index) {
339+
output_data[output_index] = ActivationFunctionWithMinMax(
340+
static_cast<T>(input1_data[input1_index] +
341+
input2_data[input2_index]),
342+
activation_min, activation_max);
343+
});
344+
return;
345+
}
331346

332347
// In Tensorflow, the dimensions are canonically named (batch_number, row,
333348
// col, channel), with extents (batches, height, width, depth), with the
@@ -421,6 +436,19 @@ BroadcastAdd6DSlow(const ArithmeticParams& params,
421436
const RuntimeShape& input2_shape, const T* input2_data,
422437
const RuntimeShape& output_shape, T* output_data) {
423438
constexpr int kMaxBroadcastDim = 6;
439+
const int broadcast_rank = std::max(
440+
output_shape.DimensionsCount(),
441+
std::max(input1_shape.DimensionsCount(), input2_shape.DimensionsCount()));
442+
if (broadcast_rank > kMaxBroadcastDim) {
443+
ForEachBroadcastedElement(
444+
input1_shape, input2_shape, output_shape,
445+
[&](int output_index, int input1_index, int input2_index) {
446+
AddElementwise(1, params, input1_data + input1_index,
447+
input2_data + input2_index,
448+
output_data + output_index);
449+
});
450+
return;
451+
}
424452

425453
// In Tensorflow, the dimensions are canonically named (batch_number, row,
426454
// col, channel), with extents (batches, height, width, depth), with the

0 commit comments

Comments
 (0)