Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor conv to share code between reference and optimized kernels #47112

Merged
merged 2 commits into from Feb 17, 2021

Conversation

njeffrie
Copy link
Contributor

@njeffrie njeffrie commented Feb 12, 2021

Summary:

Move shared structs / helper functions into conv_common.cc
Clean up some of the existing code to directly call the reference implementations (made possible by the refactor of the helper functions).

Tested with:
make -j8 -f tensorflow/lite/micro/tools/make/Makefile test_kernel_conv_test

make -j8 -f tensorflow/lite/micro/tools/make/Makefile OPTIMIZED_KERNEL_DIR=cmsis_nn TARGET=stm32f4 test_kernel_conv_test

make -f tensorflow/lite/micro/tools/make/Makefile -j8 TARGET=xtensa OPTIMIZED_KERNEL_DIR=xtensa TARGET_ARCH=hifimini XTENSA_CORE=mini1m1m_RG test_kernel_conv_test

@google-ml-butler google-ml-butler bot added the size:L CL Change Size: Large label Feb 12, 2021
@google-ml-butler
Copy link

Thanks for contributing to TensorFlow Lite Micro.

To keep this process moving along, we'd like to make sure that you have completed the items on this list:

We would like to have a discussion on the Github issue first to determine the best path forward, and then proceed to the PR review.

@gbaned gbaned self-assigned this Feb 12, 2021
@gbaned gbaned added the comp:micro Related to TensorFlow Lite Microcontrollers label Feb 12, 2021
@gbaned gbaned added this to Assigned Reviewer in PR Queue via automation Feb 12, 2021
Copy link
Member

@advaitjain advaitjain left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

some of my comments are for the existing code and not just the refactor -- apologies for that.

Comment on lines 139 to 141
cc_library(
name = "conv",
srcs = [
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we are ordering the build rules alphabetically.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@@ -178,144 +92,70 @@ TfLiteStatus Prepare(TfLiteContext* context, TfLiteNode* node) {
data->output_zero_point = output->params.zero_point;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can these also be moved inside the CacluateOpDataConv function?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Comment on lines 49 to 50
// Index to buffer for optimizations if applicable.
int buffer_idx;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is only needed for cmsis_nn, right?

Let's follow the pattern of fully_connected where we only add the extra op data members for the optimized kernels that need them:

struct OpData {
OpDataFullyConnected reference_op_data;
// Index to buffer for optimizations if applicable.
int buffer_idx;
};

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.


// Returns a ConvParams struct with all the parameters needed for a
// quantized computation.
ConvParams ConvParamsQuantized(TfLiteConvParams* params,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks like params is also an input param, make it const TfLiteConvParams& params?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Comment on lines 73 to 83
inline PaddingType RuntimePaddingType(TfLitePadding padding) {
switch (padding) {
case TfLitePadding::kTfLitePaddingSame:
return PaddingType::kSame;
case TfLitePadding::kTfLitePaddingValid:
return PaddingType::kValid;
case TfLitePadding::kTfLitePaddingUnknown:
default:
return PaddingType::kNone;
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's move the definition to the .cc to avoid overuse of inline.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Comment on lines 138 to 143
int input_width = input->dims->data[2];
int input_height = input->dims->data[1];
int filter_width = filter->dims->data[2];
int filter_height = filter->dims->data[1];
int output_width = output->dims->data[2];
int output_height = output->dims->data[1];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

make all of these const?

Copy link
Contributor Author

@njeffrie njeffrie Feb 13, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Comment on lines 161 to 163
TF_LITE_ENSURE(context, affine_quantization);
TF_LITE_ENSURE(context, affine_quantization->scale);
TF_LITE_ENSURE(context, affine_quantization->zero_point);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we really should be passing in bools to TF_LITE_ENSURE.

We are simply checking for scale and zero point being not null?

Let's make them DCHECK(scale != nullptr), DCHECK(affine_quatization != nullptr), DCHECK(zero_point != nullptr)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Comment on lines 177 to 179
data->input_zero_point = input->params.zero_point;
data->filter_zero_point = filter->params.zero_point;
data->output_zero_point = output->params.zero_point;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

move these to CalculateOpDataConv?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Comment on lines 119 to 122
void* InitConv(TfLiteContext* context, const char* buffer, size_t length) {
TFLITE_DCHECK(context->AllocatePersistentBuffer != nullptr);
return context->AllocatePersistentBuffer(context, sizeof(OpDataConv));
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove? It is not declared in conv.h

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Comment on lines 242 to 249
TfLiteStatus Prepare(TfLiteContext* context, TfLiteNode* node) {
TFLITE_DCHECK(node->user_data != nullptr);
TFLITE_DCHECK(node->builtin_data != nullptr);
auto* params = reinterpret_cast<TfLiteConvParams*>(node->builtin_data);

TfLiteTensor* output = GetOutput(context, node, kOutputTensor);
const TfLiteTensor* input = GetInput(context, node, kInputTensor);
const TfLiteTensor* filter = GetInput(context, node, kFilterTensor);
TfLiteTensor* output = GetOutput(context, node, kConvOutputTensor);
const TfLiteTensor* input = GetInput(context, node, kConvInputTensor);
const TfLiteTensor* filter = GetInput(context, node, kConvWeightsTensor);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks identical to the Prepare in the reference kernel.

You do have PrepareConv in conv_common.cc but not in conv.h. Did you mean to share this code between the reference and xtensa kernels?

As a minor nit, at least in softmax.h we are going with the naming convention of SoftmaxInit and SoftmaxPrepare.

Copy link
Contributor Author

@njeffrie njeffrie Feb 13, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed in favor of shared ConvPrepare method.

PR Queue automation moved this from Assigned Reviewer to Reviewer Requested Changes Feb 12, 2021
PR Queue automation moved this from Reviewer Requested Changes to Approved by Reviewer Feb 16, 2021
@google-ml-butler google-ml-butler bot added kokoro:force-run Tests on submitted change ready to pull PR ready for merge process labels Feb 16, 2021
@kokoro-team kokoro-team removed the kokoro:force-run Tests on submitted change label Feb 16, 2021
@copybara-service copybara-service bot merged commit 2ebd622 into tensorflow:master Feb 17, 2021
PR Queue automation moved this from Approved by Reviewer to Merged Feb 17, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cla: yes comp:micro Related to TensorFlow Lite Microcontrollers ready to pull PR ready for merge process size:L CL Change Size: Large
Projects
PR Queue
  
Merged
Development

Successfully merging this pull request may close these issues.

None yet

4 participants