tensorflow: iOS error: No OpKernel was registered to support Op 'Mul' with these attrs [T=DT_INT32]

I have some issues performing a multiplication of int32 data on iOS. Session::Run fails with the error shown below, indicating that this particular multiplication op is not supported. I’ve already checked tf_op_files.txt, and ‘tensorflow/core/kernels/cwise_op_mul.cc’ is there, obviously, and it looks to like the int32 version should also get registered there.

Do I need to take any extra steps to enable int32 multiplication on iOS?

This is the exact error message I’m getting:

No OpKernel was registered to support Op 'Mul' with these attrs
     [[Node: mul = Mul[T=DT_INT32](Cast, Cast)]]

I’m using TensorFlow 0.10. Here is how I create the graph def file in Python:

import tensorflow as tf
from tensorflow.python.framework import graph_util

input = tf.placeholder(tf.float32, shape=(1,4), name='input')

v = tf.cast(input, tf.int32)
v = v * v
output = tf.cast(v, tf.float32, name='output')

with tf.Session() as sess:
    output_graph_def = graph_util.convert_variables_to_constants(sess, sess.graph_def, ['output'])

with tf.gfile.GFile('/tmp/test_graph.pb', 'wb') as f:
    f.write(output_graph_def.SerializeToString())

Thanks a lot, Peter

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Comments: 28 (13 by maintainers)

Commits related to this issue

Most upvoted comments

But the code for cwise ops makes some assumptions about the order of types, assuming that only the first two arguments to REGISTER macros should be used

It looks like only the first argument is used if __ANDROID_TYPES_SLIM__ is defined. In addition to REGISTER5(BinaryOp, CPU, "Mul", functor::mul, float, int32, double, uint8, Eigen::half);

I changed REGISTER5 to

#define REGISTER5(OP, D, N, F, T0, T1, T2, T3, T4) \
    REGISTER(OP, D, N, F, T0) \
    REGISTER(OP, D, N, F, T1)

Note that by setting __ANDROID_TYPES_FULL__ library size increases significantly and should probably be avoided.

I actually just had a chance to look into this, and I believe it’s a bug with our op registration code. It’s expected that we only register float and int32 variants of kernels on mobile platforms: https://github.com/tensorflow/tensorflow/blob/master/tensorflow/core/framework/register_types.h

But the code for cwise ops makes some assumptions about the order of types, assuming that only the first two arguments to REGISTER<N> macros should be used, in the hope that they’re DT_FLOAT32 and DT_INT32: https://github.com/tensorflow/tensorflow/blob/master/tensorflow/core/kernels/cwise_ops_common.h#L413

Unfortunately the code for registering the “Mul” kernels passes in a float, then a half as the first two arguments to REGISTER5: https://github.com/tensorflow/tensorflow/blob/master/tensorflow/core/kernels/cwise_op_mul_1.cc

This means that only the float kernel gets registered. A simple workaround for now would be to change the line to be:

REGISTER5(BinaryOp, CPU, "Mul", functor::mul, float, int32, double, uint8, Eigen::half);

I haven’t tested this myself, and it doesn’t fix other occurrences of this same problem, but could you give it a try @peterkfm ?

I have figured out what you mean. So both cwise_op_mul_1.cc and REGISTER5 macro need change, and leave __ANDROID_TYPES_FULL__ not modified. Thanks.

Thanks a lot Pete, that was indeed what was causing the problem. I ended up working around it by defining __ANDROID_TYPES_FULL__ (instead of __ANDROID_TYPES_SLIM__) in the Makefile. After that, to fix other missing ops, I extended tf_op_files.txt to contain practically everything that compiles on iOS, and changed register_types.h to make sure bool ops get defined as well.

Thanks again for your help, much appreciated!