Ops listed in 'experimental_select_user_tf_ops' not being recognized by tf lite converter
Hi @anselmo0v 

As per the [documentation](https://www.tensorflow.org/lite/api_docs/python/tf/lite/TargetSpec#attributes), it should only be used if  we are using TF ops that may not be linked in by default with the TF ops that are provided when using the SELECT_TF_OPS path.

I guess adding the regular select ops flag does the similar job as `RandomUniform` and `Mul `are already a part of [Select TF Ops](https://www.tensorflow.org/lite/guide/op_select_allowlist#tensorflow_core_operators). Please check this [gist](https://colab.research.google.com/gist/pjpratik/7860512ac86d586c96365cad4bf9d711/61662.ipynb).

For reducing the binary size of the TFLite model consider https://www.tensorflow.org/lite/guide/reduce_binary_size

Thanks. Hi @pjpratik, thank you very much for your response.

So, I understand what I am doing is not the intended use for the experimental_select_user_tf_ops flag. I had checked the guide to reduce binary size before, the thing is my laptop is freezing in the middle of the build with bazel when I set SELECT_TF_OPS, and that's why I wanted to reduce the number of ops included. 

Any chance there is a method to manually specify just some ops from the tf_ops set to be included in the build? Hi @anselmo0v 

Thanks for the information.

As of now, we can only reduce the binary size by model, not using the list of ops. Selective building will include the necessary operators for your models.

> I had checked the guide to reduce binary size before, the thing is my laptop is freezing in the middle of the build with bazel when I set SELECT_TF_OPS

Regarding freezing issues during Bazel builds with the SELECT_TF_OPS flag, it's advisable to consider using a more powerful machine with robust CPU and memory configurations for smooth compilation of model,  incase they are complex. 

Is it possible to share the error stack trace and TFLite model to reproduce the issue?

Thanks.

 Hi @pjpratik,

I'll try to find a better machine to run the build and contact again with error trace if any. 

Thank you very much for your help. Hi @anselmo0v 

Did you get a chance to run the build?

Thanks. Hi @pjpratik.

Yes, I have been following the reduce binary size [guide](https://www.tensorflow.org/lite/guide/reduce_binary_size) in various machines both Mac and Linux with no sucess at building tensorflowlite_flex. 

I decided to use an AWS EC2 instance with Docker to avoid possible dependency conflicts, but still the build fails. The instance has this specifications:

RAM: 32GB
vCPU: 16
Architecture: x86_64
OS: Ubuntu 22.0.4 Server

I use the same simple model of my first comment, previously converted and saved to a .tflite, setting _tf.lite.OpsSet.TFLITE_BUILTINS_ and _tf.lite.OpsSet.SELECT_TF_OPS_ .

These are the BUILD file inside the created _tmp_ folder and the Dockerfile I am using:
[Dockerfile.txt](https://github.com/tensorflow/tensorflow/files/12551233/Dockerfile.txt)
[BUILD.txt](https://github.com/tensorflow/tensorflow/files/12551234/BUILD.txt)

This is the error I get:
[error_logs.txt](https://github.com/tensorflow/tensorflow/files/12551260/error_logs.txt)

It seems to be a consistent error in all the Intel - Linux machines I've tried. At lines _52 to 60_ of my Dockerfile I tried to solve this issue by including the source files from oneAPI into the source files of Tensorflow, but the same error keeps showing.

I appreciate your help. Hi @pjpratik .

So I followed the [guide](https://www.tensorflow.org/lite/android/lite_build) to build .aar files for Java from the AWS EC2 instance I mentioned before and it was successful. 

Now I've tried to follow similar steps to build for C++. I've copied and modified the build_aar.sh file:
[build_tf_flex.sh](https://github.com/tensorflow/tensorflow/files/12591917/build_tf_flex.txt)

And divided my previous BUILD file into to different files:
[BUILD_tfliteops](https://github.com/tensorflow/tensorflow/files/12591931/BUILD_tfliteops.txt)
[BUILD_tfops](https://github.com/tensorflow/tensorflow/files/12591925/BUILD_tfops.txt)

I also deleted lines _52 to 60_ (that added oneapi source files) from my Dockerfile:
[Dockerfile](https://github.com/tensorflow/tensorflow/files/12591937/Dockerfile.txt)

The _tensorflowlite.so_ file is successfully created, but I get a lot of undefined reference errors when building the _tensorflowlite_flex.so_ file:
[stderr-2](https://github.com/tensorflow/tensorflow/files/12591997/stderr-2.txt)

This is the command I'm using from the Docker container to build:
`bash custom_files/build_tf_flex.sh --input_models=custom_files/cpp_tf_test.tflite --target_archs=arm64-v8a` Not sure if this is the correct target when building .so files for android, since other guides say you should use _android_arm64_.

I can work for now with the .aar files but the reason I need to build for C++ is because I'm looking for cross platform integration.

I really appreciate any help you can provide.




 Hi @anselmo0v 

Sorry for the delayed response. Thanks for the information.

Just wanted to know if you tried with just `--config=andorid_arm64` without monolithic build?

```
bazel build -c opt --cxxopt=--std=c++17 --config=android_arm64  --host_crosstool_top=@bazel_tools//tools/cpp:toolchain //tmp:tensorflowlite_flex 
```

Thanks.

 Hi @pjpratik.

I retried as suggested, no `--config=monolithic` option and using `--confing=android_arm64` as target.

This is my new .sh file:
[build_tf_flex.sh](https://github.com/tensorflow/tensorflow/files/12694149/build_tf_flex_2.txt)

It is back to the error related to missing dnnl files:
[error_logs](https://github.com/tensorflow/tensorflow/files/12694147/error_logs_2.txt)

 Hi @anselmo0v 

Thanks for the information.

@pkgoogle Could you please check this issue?
 Hi @anselmo0v, Can you review this and see if it helps you.
https://www.tensorflow.org/lite/guide/ops_select#cc
https://www.tensorflow.org/lite/android/development#tools_for_building_with_c_and_c

if that doesn't work can you please give me your exact steps (as if you are writing a shell script or Dockerfile) to reproduce the issue you are seeing. There's probably a way to get it from all the above but putting it all into one message will make things easier to debug. Hi @pkgoogle, thanks for taking a look at this issue. These are the steps I'm following:

**1.** I create my .tflite file from this Google Colab Notebook [here](https://github.com/anselmo0v/test-tf-lite/blob/main/tflite_dummy_model.ipynb).

**2.** I connect my local terminal by ssh to the AWS EC2 instance I use (RAM: 32GB, vCPU: 16, Architecture: x86_64, OS: Ubuntu 22.0.4 Server).

**3.** I clone [my files](https://github.com/anselmo0v/test-tf-lite/tree/main/tf-builder-docker) from terminal.

**4.** Then I build the docker image from my [Dockerfile](https://github.com/anselmo0v/test-tf-lite/blob/main/tf-builder-docker/Dockerfile):
```
 cd tf-builder-docker
 sudo docker build . -t tf-builder -f Dockerfile
```

**5.** Next I run the container and go inside it:
`sudo docker run -it -v $PWD:/host_dir tf-builder bash`

**6.** Inside the running container, I go to the tensorflow source folder:
`cd home/tensorflow-2.13.0`

**7.** From there, I run my [build_tf_flex.sh](https://github.com/anselmo0v/test-tf-lite/blob/main/tf-builder-docker/build_tf_flex.sh) file:
`bash custom_files/build_tf_flex.sh --input_models=custom_files/cpp_tf_test.tflite --target_archs=android_arm64`

The custom_files folder is created at my Dockerfile and contains the BUILD files, the build_tf_flex.sh file and the .tflite model. 

The build_tf_flex.sh file is a customized file I made by taking the build_aar.sh file from tensorflow source code and modifying it to:

      - Build the tensorflowlite.so with the command: 
      bazel ${CACHE_DIR_FLAG} build -c opt --cxxopt='--std=c++17' --config=${TARGET_ARCHS} //tmp:tensorflowlite --verbose_failures
      
      - Build the tensorflowlite_flex.so with the command:
      bazel ${CACHE_DIR_FLAG} build -c opt --cxxopt='--std=c++17' --config=${TARGET_ARCHS} --host_crosstool_top=@bazel_tools//tools/cpp:toolchain //tmp:tensorflowlite_flex --verbose_failures

The tensorflowlite.so file is successfully created, but at the tensorflowlite_flex.so building step I obtain the mentioned error:
`fatal error: dnnl.hpp: No such file or directory`

This is the log file: 
[error_logs](https://github.com/tensorflow/tensorflow/files/12743392/error_logs_2.txt)
 Hi @anselmo0v,

I was able to replicate your issue with the following steps:

```
git clone https://github.com/anselmo0v/test-tf-lite.git
cd test-tf-lite/tf-builder-docker
sudo docker build . -t tf-builder -f Dockerfile
sudo docker run -it -v $PWD:/host_dir tf-builder bash
cd home/tensorflow-2.13.0
bash custom_files/build_tf_flex.sh --input_models=custom_files/cpp_tf_test.tflite --target_archs=android_arm64
```

It seems like that header (dnnl.hpp) is only included with some build_with_mkl flags, I tried a couple of different things but they all failed as well.

I added a --define=build_with_mkl=true flag but that wasn't it, but it seems it got further
```
+ bazel-bin/tensorflow/lite/tools/list_flex_ops_no_kernel_main --graphs=custom_files/cpp_tf_test.tflite
++ cat /home/tensorflow-2.13.0/tmp//ops_list.txt
+ [[ ["Mul","RandomUniform"] != \[\] ]]
+ generate_flex_so
+ pushd /home/tensorflow-2.13.0/tmp/
/home/tensorflow-2.13.0/tmp /home/tensorflow-2.13.0
+ cp /home/tensorflow-2.13.0/custom_files/BUILD_tfops /home/tensorflow-2.13.0/tmp//BUILD
+ popd
/home/tensorflow-2.13.0
+ bazel --output_user_root=/home/bazel-results/cache build -c opt --cxxopt=--std=c++17 --config=android_arm64 --host_crosstool_top=@bazel_tools//tools/cpp:toolchain --define=build_with_mkl=true //tmp:tensorflowlite_flex --verbose_failures
```
produces eventually:
```
tensorflow/core/kernels/mkl/mkl_avgpooling_op.cc:19:10: fatal error: dnnl.hpp: No such file or directory
   19 | #include "dnnl.hpp"
      |          ^~~~~~~~~~
compilation terminated.
Target //tmp:tensorflowlite_flex failed to build
INFO: Elapsed time: 55.406s, Critical Path: 39.28s
INFO: 776 processes: 50 internal, 726 local.
```

@terryheo, can you please take a look? Thanks. Hi @pkgoogle , @terryheo. 

Just checking if you have any updates on this issue.

Thanks.
### 1. System information

- Google Colab Notebook

### 2. Code

_#### Model Definition ---------_
```
class CppTfTest(tf.Module):

    def __init__(self, name=None):
        super().__init__(name=name)

    @tf.function
    def call(self):

        frames = tf.range(600)

        bpm = tf.random.uniform(
            tf.TensorShape([600,]),
            minval=0,
            maxval=90,
            dtype=tf.dtypes.float64
            )

        return bpm, frames
```

_#### Model Saving ------------_
```
cpp_tf_test = CppTfTest()
tf.saved_model.save(
    cpp_tf_test,
    'cpp_tf_test',
    signatures=cpp_tf_test.call.get_concrete_function()
    )
```

_#### Model Conversion -----------_
```
converter = tf.lite.TFLiteConverter.from_saved_model('cpp_tf_test')

converter.target_spec = tf.lite.TargetSpec(
    supported_ops=[tf.lite.OpsSet.TFLITE_BUILTINS],
    experimental_select_user_tf_ops=[
        'RandomUniform', 'Mul'
        ]
)

tflite_model = converter.convert()

with open('cpp_tf_test.tflite', 'wb') as f:
  f.write(tflite_model)
```


---------------------------------------------------------------------------

> 
> ConverterError                            Traceback (most recent call last)
> 
> [<ipython-input-88-4a7f170f3f72>](https://localhost:8080/#) in <cell line: 47>()
>      45 #converter.allow_custom_ops=True
>      46 
> ---> 47 tflite_model = converter.convert()
>      48 
>      49 with open('cpp_tf_test.tflite', 'wb') as f:
> 
> 7 frames
> 
> [/usr/local/lib/python3.10/dist-packages/tensorflow/lite/python/lite.py](https://localhost:8080/#) in wrapper(self, *args, **kwargs)
>     960   def wrapper(self, *args, **kwargs):
>     961     # pylint: disable=protected-access
> --> 962     return self._convert_and_export_metrics(convert_func, *args, **kwargs)
>     963     # pylint: enable=protected-access
>     964 
> 
> [/usr/local/lib/python3.10/dist-packages/tensorflow/lite/python/lite.py](https://localhost:8080/#) in _convert_and_export_metrics(self, convert_func, *args, **kwargs)
>     938     self._save_conversion_params_metric()
>     939     start_time = time.process_time()
> --> 940     result = convert_func(self, *args, **kwargs)
>     941     elapsed_time_ms = (time.process_time() - start_time) * 1000
>     942     if result:
> 
> [/usr/local/lib/python3.10/dist-packages/tensorflow/lite/python/lite.py](https://localhost:8080/#) in convert(self)
>    1245           graph_def)
>    1246 
> -> 1247     return self._convert_from_saved_model(graph_def)
>    1248 
>    1249 
> 
> [/usr/local/lib/python3.10/dist-packages/tensorflow/lite/python/lite.py](https://localhost:8080/#) in _convert_from_saved_model(self, graph_def)
>    1128     converter_kwargs.update(quant_mode.converter_flags())
>    1129 
> -> 1130     result = _convert_saved_model(**converter_kwargs)
>    1131     return self._optimize_tflite_model(
>    1132         result, quant_mode, quant_io=self.experimental_new_quantizer)
> 
> [/usr/local/lib/python3.10/dist-packages/tensorflow/lite/python/convert_phase.py](https://localhost:8080/#) in wrapper(*args, **kwargs)
>     210         else:
>     211           report_error_message(str(converter_error))
> --> 212         raise converter_error from None  # Re-throws the exception.
>     213       except Exception as error:
>     214         report_error_message(str(error))
> 
> [/usr/local/lib/python3.10/dist-packages/tensorflow/lite/python/convert_phase.py](https://localhost:8080/#) in wrapper(*args, **kwargs)
>     203     def wrapper(*args, **kwargs):
>     204       try:
> --> 205         return func(*args, **kwargs)
>     206       except ConverterError as converter_error:
>     207         if converter_error.errors:
> 
> [/usr/local/lib/python3.10/dist-packages/tensorflow/lite/python/convert.py](https://localhost:8080/#) in convert_saved_model(**kwargs)
>     830   model_flags = build_model_flags(**kwargs)
>     831   conversion_flags = build_conversion_flags(**kwargs)
> --> 832   data = convert(
>     833       model_flags.SerializeToString(),
>     834       conversion_flags.SerializeToString(),
> 
> [/usr/local/lib/python3.10/dist-packages/tensorflow/lite/python/convert.py](https://localhost:8080/#) in convert(model_flags_str, conversion_flags_str, input_data_str, debug_info_str, enable_mlir_converter)
>     320       for error_data in _metrics_wrapper.retrieve_collected_errors():
>     321         converter_error.append_error(error_data)
> --> 322       raise converter_error
>     323 
>     324   return _run_deprecated_conversion_binary(model_flags_str,
> 
> ConverterError: <unknown>:0: error: loc(callsite(callsite(fused["RandomUniform:", "random_uniform/RandomUniform@__inference_call_11165"] at fused["StatefulPartitionedCall:", "StatefulPartitionedCall@__inference_signature_wrapper_11173"]) at fused["StatefulPartitionedCall:", "StatefulPartitionedCall"])): 'tf.RandomUniform' op is neither a custom op nor a flex op
> <unknown>:0: note: loc(fused["StatefulPartitionedCall:", "StatefulPartitionedCall"]): called from
> <unknown>:0: note: loc(callsite(callsite(fused["RandomUniform:", "random_uniform/RandomUniform@__inference_call_11165"] at fused["StatefulPartitionedCall:", "StatefulPartitionedCall@__inference_signature_wrapper_11173"]) at fused["StatefulPartitionedCall:", "StatefulPartitionedCall"])): Error code: ERROR_NEEDS_FLEX_OPS
> <unknown>:0: error: loc(callsite(callsite(fused["Mul:", "random_uniform/Mul@__inference_call_11165"] at fused["StatefulPartitionedCall:", "StatefulPartitionedCall@__inference_signature_wrapper_11173"]) at fused["StatefulPartitionedCall:", "StatefulPartitionedCall"])): 'tf.Mul' op is neither a custom op nor a flex op
> <unknown>:0: note: loc(fused["StatefulPartitionedCall:", "StatefulPartitionedCall"]): called from
> <unknown>:0: note: loc(callsite(callsite(fused["Mul:", "random_uniform/Mul@__inference_call_11165"] at fused["StatefulPartitionedCall:", "StatefulPartitionedCall@__inference_signature_wrapper_11173"]) at fused["StatefulPartitionedCall:", "StatefulPartitionedCall"])): Error code: ERROR_NEEDS_FLEX_OPS
> <unknown>:0: error: failed while converting: 'main': 
> Some ops are not supported by the native TFLite runtime, you can enable TF kernels fallback using TF Select. See instructions: https://www.tensorflow.org/lite/guide/ops_select 
> TF Select ops: Mul, RandomUniform
> Details:
> 	tf.Mul(tensor<600xf64>, tensor<f64>) -> (tensor<600xf64>) : {device = ""}
> 	tf.RandomUniform(tensor<1xi32>) -> (tensor<600xf64>) : {device = "", seed = 0 : i64, seed2 = 0 : i64}


I'm trying to convert this simple model to Tensorflow Lite using the _experimental_select_user_tf_ops_ flag to tell the converter what operations from the tf_ops set to include. I need this to run with just a subset of the tf_ops set since I have a bigger model that I need to optimize for a mobile app. I've try many things but the _experimental_select_user_tf_ops_ flag just doesn't seem to work.