Move AddBuiltin and AddCustom out of the interface.

To get the desired code size reduction from the newer API for adding
builtin operators, we need the AddBuiltin function to be removed by the linker.

However, linkers currently have limited support for removing unused functions
that are virtual.

This change moves the AddBuiltin function out of the interface (and AddCustom as
well for consistency).

https://stackoverflow.com/q/17433791
https://reviews.llvm.org/D63932
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.kui0101a/armlink_bhcgeaid.htm

PiperOrigin-RevId: 315372426
Change-Id: I0dd1fc8a62dbe60076c7c847b43294ac273d0bad
This commit is contained in:
Advait Jain 2020-06-08 16:01:48 -07:00 committed by TensorFlower Gardener
parent 031d85fc24
commit 477c1312ba
3 changed files with 91 additions and 89 deletions

View File

@ -172,18 +172,6 @@ class MockOpResolver : public MicroOpResolver {
// ParseOpData.
return ParseOpData;
}
TfLiteStatus AddBuiltin(tflite::BuiltinOperator op,
TfLiteRegistration* registration) override {
// This function is currently not used in the tests.
return kTfLiteError;
}
TfLiteStatus AddCustom(const char* name,
TfLiteRegistration* registration) override {
// This function is currently not used in the tests.
return kTfLiteError;
}
};
} // namespace

View File

@ -68,63 +68,13 @@ class MicroMutableOpResolver : public MicroOpResolver {
return nullptr;
}
// The Add* functions below add the various Builtin operators to the
// MicroMutableOpResolver object.
// Registers a Custom Operator with the MicroOpResolver.
//
// This API is currently experimental (and only supported for a small subset
// of operators). It will soon be preferred over the AddBuiltin override of
// the MicroOpResolver interface for the following reason:
// * If all calls to AddBuiltin for an application use this API, the code
// size will be smaller by 5-8K (compared to the using the AddBuiltin
// override).
TfLiteStatus AddDequantize() {
// TODO(b/149408647): Replace ParseOpData with the operator specific parse
// function once cl/313453102 lands.
return AddBuiltin(BuiltinOperator_DEQUANTIZE,
*tflite::ops::micro::Register_DEQUANTIZE(), ParseOpData);
}
TfLiteStatus AddFullyConnected() {
// TODO(b/149408647): Replace ParseOpData with the operator specific parse
// function once cl/313453102 lands.
return AddBuiltin(BuiltinOperator_FULLY_CONNECTED,
*tflite::ops::micro::Register_FULLY_CONNECTED(),
ParseOpData);
}
TfLiteStatus AddQuantize() {
// TODO(b/149408647): Replace ParseOpData with the operator specific parse
// function once cl/313453102 lands.
return AddBuiltin(BuiltinOperator_QUANTIZE,
*tflite::ops::micro::Register_QUANTIZE(), ParseOpData);
}
TfLiteStatus AddSoftmax() {
// TODO(b/149408647): Replace ParseOpData with the operator specific parse
// function once cl/313453102 lands.
return AddBuiltin(BuiltinOperator_SOFTMAX,
*tflite::ops::micro::Register_SOFTMAX(), ParseOpData);
}
TfLiteStatus AddSvdf() {
// TODO(b/149408647): Replace ParseOpData with the operator specific parse
// function once cl/313453102 lands.
return AddBuiltin(BuiltinOperator_SVDF,
*tflite::ops::micro::Register_SVDF(), ParseOpData);
}
TfLiteStatus AddBuiltin(tflite::BuiltinOperator op,
TfLiteRegistration* registration) override {
TFLITE_DCHECK(registration != nullptr);
// For code that is not switched over to the new selective registration of
// the parse function, we pass in ParseOpData. This allows for backwards
// compatibility.
return AddBuiltin(op, *registration, ParseOpData);
}
TfLiteStatus AddCustom(const char* name,
TfLiteRegistration* registration) override {
// Only the first call for a given name will be successful. i.e. if this
// function is called again for a previously added Custom Operator, the
// MicroOpResolver will be unchanged and this function will return
// kTfLiteError.
TfLiteStatus AddCustom(const char* name, TfLiteRegistration* registration) {
if (registrations_len_ >= tOpCount) {
if (error_reporter_) {
TF_LITE_REPORT_ERROR(
@ -154,6 +104,91 @@ class MicroMutableOpResolver : public MicroOpResolver {
return kTfLiteOk;
}
// Registers a Builtin Operator with the MicroOpResolver.
//
// Only the first call for a given BuiltinOperator enum will be successful.
// i.e. if this function is called again for a previously added
// BuiltinOperator, the MicroOpResolver will be unchanged and this function
// will return kTfLiteError.
//
// TODO(b/149408647): remove this API once the BuiltinOperator specific Add
// functions are fully implemented.
TfLiteStatus AddBuiltin(tflite::BuiltinOperator op,
TfLiteRegistration* registration) {
TFLITE_DCHECK(registration != nullptr);
// For code that is not switched over to the new selective registration of
// the parse function, we pass in ParseOpData. This allows for backwards
// compatibility.
return AddBuiltin(op, *registration, ParseOpData);
}
// The Add* functions below add the various Builtin operators to the
// MicroMutableOpResolver object.
//
// This API is currently experimental (and only supported for a small subset
// of operators). It will soon be preferred over the AddBuiltin function for
// the following reason:
// * If all calls to AddBuiltin for an application use this API, the code
// size will be smaller by 5-8K (compared to the using the AddBuiltin
// override).
TfLiteStatus AddConv2D() {
// TODO(b/149408647): Replace ParseOpData with the operator specific parse
// function once cl/313453102 lands.
return AddBuiltin(BuiltinOperator_CONV_2D,
*tflite::ops::micro::Register_CONV_2D(), ParseOpData);
}
TfLiteStatus AddDequantize() {
// TODO(b/149408647): Replace ParseOpData with the operator specific parse
// function once cl/313453102 lands.
return AddBuiltin(BuiltinOperator_DEQUANTIZE,
*tflite::ops::micro::Register_DEQUANTIZE(), ParseOpData);
}
TfLiteStatus AddFullyConnected() {
// TODO(b/149408647): Replace ParseOpData with the operator specific parse
// function once cl/313453102 lands.
return AddBuiltin(BuiltinOperator_FULLY_CONNECTED,
*tflite::ops::micro::Register_FULLY_CONNECTED(),
ParseOpData);
}
TfLiteStatus AddLogistic() {
// TODO(b/149408647): Replace ParseOpData with the operator specific parse
// function once cl/313453102 lands.
return AddBuiltin(BuiltinOperator_LOGISTIC,
*tflite::ops::micro::Register_LOGISTIC(), ParseOpData);
}
TfLiteStatus AddQuantize() {
// TODO(b/149408647): Replace ParseOpData with the operator specific parse
// function once cl/313453102 lands.
return AddBuiltin(BuiltinOperator_QUANTIZE,
*tflite::ops::micro::Register_QUANTIZE(), ParseOpData);
}
TfLiteStatus AddReshape() {
// TODO(b/149408647): Replace ParseOpData with the operator specific parse
// function once cl/313453102 lands.
return AddBuiltin(BuiltinOperator_RESHAPE,
*tflite::ops::micro::Register_RESHAPE(), ParseOpData);
}
TfLiteStatus AddSoftmax() {
// TODO(b/149408647): Replace ParseOpData with the operator specific parse
// function once cl/313453102 lands.
return AddBuiltin(BuiltinOperator_SOFTMAX,
*tflite::ops::micro::Register_SOFTMAX(), ParseOpData);
}
TfLiteStatus AddSvdf() {
// TODO(b/149408647): Replace ParseOpData with the operator specific parse
// function once cl/313453102 lands.
return AddBuiltin(BuiltinOperator_SVDF,
*tflite::ops::micro::Register_SVDF(), ParseOpData);
}
unsigned int GetRegistrationLength() { return registrations_len_; }
private:

View File

@ -44,27 +44,6 @@ class MicroOpResolver : public OpResolver {
BuiltinDataAllocator* allocator,
void** builtin_data);
// Registers a Builtin Operator with the MicroOpResolver.
//
// Only the first call for a given BuiltinOperator enum will be successful.
// i.e. if this function is called again for a previously added
// BuiltinOperator, the MicroOpResolver will be unchanged and this function
// will return kTfLiteError.
//
// TODO(b/149408647): remove this API once the templated AddBuiltin API in
// MicroMutableOpResolver is properly implemented.
virtual TfLiteStatus AddBuiltin(tflite::BuiltinOperator op,
TfLiteRegistration* registration) = 0;
// Registers a Custom Operator with the MicroOpResolver.
//
// Only the first call for a given name will be successful. i.e. if this
// function is called again for a previously added Custom Operator, the
// MicroOpResolver will be unchanged and this function will return
// kTfLiteError.
virtual TfLiteStatus AddCustom(const char* name,
TfLiteRegistration* registration) = 0;
// Returns the Op registration struct corresponding to the enum code from the
// flatbuffer schema. Returns nullptr if the op is not found or if op ==
// BuiltinOperator_CUSTOM.