def spaceToDepthUsingTranspose(self, tensor, block_size, data_format): block_size_sq = block_size * block_size dtype = tensor.dtype if dtype == dtypes.qint8: tensor = array_ops.bitcast(tensor, dtypes.int8) if data_format == "NHWC": b, ih, iw, ic = tensor.shape.as_list() assert ih % block_size == 0, (ih, block_size) assert iw % block_size == 0, (iw, block_size) ow, oh, oc = iw // block_size, ih // block_size, ic * block_size_sq tensor = array_ops.reshape(tensor, [b, oh, block_size, ow, block_size, ic]) tensor = array_ops.transpose(tensor, [0, 1, 3, 2, 4, 5]) tensor = array_ops.reshape(tensor, [b, oh, ow, oc]) elif data_format == "NCHW": b, ic, ih, iw = tensor.shape.as_list() assert ih % block_size == 0, (ih, block_size) assert iw % block_size == 0, (iw, block_size) ow, oh, oc = iw // block_size, ih // block_size, ic * block_size_sq tensor = array_ops.reshape(tensor, [b, ic, oh, block_size, ow, block_size]) tensor = array_ops.transpose(tensor, [0, 3, 5, 1, 2, 4]) tensor = array_ops.reshape(tensor, [b, oc, oh, ow]) if dtype == dtypes.qint8: tensor = array_ops.bitcast(tensor, dtype) return tensor
def _prepare_key_counter(self, shape): delta = math_ops.reduce_prod(shape) counter_key = self.skip(delta) counter_size = _get_counter_size(self.algorithm) counter = array_ops.bitcast(counter_key[:counter_size], dtypes.uint64) key = array_ops.bitcast(counter_key[counter_size:counter_size + 1], dtypes.uint64) return key, counter
def testBitcastInt8ToFloat(self): self._assertOpOutputMatchesExpected( lambda x: array_ops.bitcast(x, dtypes.float32), np.array([[1, 0, 0, 0], [0xd0, 0x0f, 0x49, 0x40]], np.int8), expected=np.array([1e-45, 3.14159], np.float32)) self._assertOpOutputMatchesExpected( lambda x: array_ops.bitcast(x, dtypes.np.int8), np.array([1e-45, 3.14159], np.float32), expected=np.array([[1, 0, 0, 0], [0xd0, 0x0f, 0x49, 0x40]], np.int8))
def testErrors(self): x = np.zeros([1, 1], np.int8) datatype = dtypes.int32 # When eager_op_as_function is enabled shape inference will raise # a different more informative error message. with self.assertRaisesRegex( (ValueError, errors.InvalidArgumentError), "Cannot bitcast from 6 to 3|convert from s8.* to S32"): array_ops.bitcast(x, datatype, None)
def lookup(self): """Returns cached_tree_ids, cached_node_ids, cached_logits.""" cached_tree_ids, cached_node_ids, cached_logits = array_ops.split( lookup_ops.lookup_table_find_v2( self._table_ref, self._example_ids, default_value=[0.0, 0.0, 0.0]), [1, 1, self._logits_dimension], axis=1) cached_tree_ids = array_ops.squeeze( array_ops.bitcast(cached_tree_ids, dtypes.int32)) cached_node_ids = array_ops.squeeze( array_ops.bitcast(cached_node_ids, dtypes.int32)) return (cached_tree_ids, cached_node_ids, cached_logits)
def testBitcast(self): self._assertOpOutputMatchesExpected( lambda x: array_ops.bitcast(x, dtypes.int32), np.array([1, 0x3f800000], np.int32), expected=np.array([1, 0x3f800000], np.int32)) self._assertOpOutputMatchesExpected( lambda x: array_ops.bitcast(x, dtypes.float32), np.array([1, 0x3f800000], np.int32), expected=np.array([1e-45, 1.0], np.float32)) self._assertOpOutputMatchesExpected( lambda x: array_ops.bitcast(x, dtypes.int32), np.array([1e-45, 1.0], np.float32), expected=np.array([1, 0x3f800000], np.int32))
def insert(self, tree_ids, node_ids, logits): """Inserts values and returns the op.""" insert_op = lookup_ops.lookup_table_insert_v2( self._table_ref, self._example_ids, array_ops.concat([ array_ops.expand_dims( array_ops.bitcast(tree_ids, dtypes.float32), 1), array_ops.expand_dims( array_ops.bitcast(node_ids, dtypes.float32), 1), logits, ], axis=1, name='value_concat_for_cache_insert')) return insert_op
def insert(self, tree_ids, node_ids, logits): """Inserts values and returns the op.""" insert_op = lookup_ops.lookup_table_insert_v2( self._table_ref, self._example_ids, array_ops.concat( [ array_ops.expand_dims( array_ops.bitcast(tree_ids, dtypes.float32), 1), array_ops.expand_dims( array_ops.bitcast(node_ids, dtypes.float32), 1), logits, ], axis=1, name='value_concat_for_cache_insert')) return insert_op
def lookup(self): """Returns cached_tree_ids, cached_node_ids, cached_logits.""" cached_tree_ids, cached_node_ids, cached_logits = array_ops.split( lookup_ops.lookup_table_find_v2( self._table_ref, self._example_ids, default_value=[0.0, _DUMMY_NODE_ID, 0.0]), [1, 1, self._logits_dimension], axis=1) cached_tree_ids = array_ops.squeeze( array_ops.bitcast(cached_tree_ids, dtypes.int32)) cached_node_ids = array_ops.squeeze( array_ops.bitcast(cached_node_ids, dtypes.int32)) if self._example_ids.shape.ndims is not None: cached_logits.set_shape( [self._example_ids.shape[0], self._logits_dimension]) return (cached_tree_ids, cached_node_ids, cached_logits)
def _testBitcast(self, x, datatype, shape): with self.test_session(): tf_ans = array_ops.bitcast(x, datatype) out = tf_ans.eval() buff_after = memoryview(out).tobytes() buff_before = memoryview(x).tobytes() self.assertEqual(buff_before, buff_after) self.assertEqual(tf_ans.get_shape(), shape) self.assertEqual(tf_ans.dtype, datatype)
def _testBitcast(self, x, datatype, shape): with test_util.use_gpu(): tf_ans = array_ops.bitcast(x, datatype) out = self.evaluate(tf_ans) buff_after = memoryview(out).tobytes() buff_before = memoryview(x).tobytes() self.assertEqual(buff_before, buff_after) self.assertEqual(tf_ans.get_shape(), shape) self.assertEqual(tf_ans.dtype, datatype)
def _testBitcast(self, x, datatype, shape): with self.test_session(use_gpu=True): tf_ans = array_ops.bitcast(x, datatype) out = tf_ans.eval() buff_after = memoryview(out).tobytes() buff_before = memoryview(x).tobytes() self.assertEqual(buff_before, buff_after) self.assertEqual(tf_ans.get_shape(), shape) self.assertEqual(tf_ans.dtype, datatype)
def __init__(self, shape, dtype=float, buffer=None): # pylint: disable=redefined-builtin """Initializes an ndarray. This is a low level interface for building ndarrays and should be avoided. Users should instead use methods in array_creation.py. This class provides a numpy.ndarray like interface for a TF Tensor with a fully-defined shape. Note that, unlike the backing buffer of np.ndarray, Tensors are immutable. So, operations like `__setitem__` are performed by replacing the Tensor. This restricts the ability to implement NumPy `view` semantics. Compared to numpy.ndarray, this does not support `offset`, `strides` and `order` arguments. Args: shape: The shape of the array. Must be a scalar, an iterable of integers or a `TensorShape` object. dtype: Optional. The dtype of the array. Must be a python type, a numpy type or a tensorflow `DType` object. buffer: Optional. The backing buffer of the array. Must have shape `shape`. Must be a `ndarray`, `np.ndarray` or a `Tensor`. Raises: ValueError: If `buffer` is specified and its shape does not match `shape`. """ if dtype and not isinstance(dtype, dtypes.DType): dtype = dtypes.as_dtype(np.dtype(dtype)) if buffer is None: buffer = array_ops.zeros(shape, dtype=dtype) else: if isinstance(buffer, ndarray): buffer = buffer.data elif isinstance(buffer, np.ndarray): # If `buffer` is a np.ndarray, the Tensor will share the underlying # storage of the array. buffer = convert_to_tensor(value=buffer, dtype=dtype) elif not isinstance(buffer, ops.Tensor): raise ValueError( 'Unexpected type for `buffer` {}. Must be an ndarray,' ' Tensor or np.ndarray.'.format(type(buffer))) if shape is not None and tuple(shape) != buffer._shape_tuple(): # pylint: disable=protected-access # TODO(srbs): NumPy allows this. Investigate if/how to support this. raise ValueError('shape arg must match buffer.shape.') assert isinstance(buffer, ops.Tensor) if dtype and dtype != buffer.dtype: buffer = array_ops.bitcast(buffer, dtype) self._data = buffer self.base = None
def compareToTranspose(self, batch_size, out_height, out_width, in_channels, block_size, data_format, data_type, use_gpu): in_height = out_height * block_size in_width = out_width * block_size nhwc_input_shape = [batch_size, in_height, in_width, in_channels] nchw_input_shape = [batch_size, in_channels, in_height, in_width] total_size = np.prod(nhwc_input_shape) # Construct the input tensor in data_type and NHWC. # force_cpu is needed because quantize_v2 runs on only CPU. with test_util.force_cpu(): if data_type == dtypes.qint8: # Initialize the input tensor with qint8 values that circle -127..127. x = [((f + 128) % 255) - 127 for f in range(total_size)] t = constant_op.constant(x, shape=nhwc_input_shape, dtype=dtypes.float32) t, _, _ = gen_array_ops.quantize_v2(t, -128.0, 127.0, dtypes.qint8) else: assert data_type == dtypes.float32 # Initialize the input tensor with ascending whole numbers as floats. x = [f * 1.0 for f in range(total_size)] shape = nchw_input_shape if data_format == "NCHW" else nhwc_input_shape t = constant_op.constant(x, shape=shape, dtype=dtypes.float32) with test_util.device(use_gpu): if data_format == "NCHW_VECT_C": assert data_type == dtypes.qint8 # Convert to int8, then NHWCToNCHW_VECT_C, and then back to qint8. actual = array_ops.bitcast(t, dtypes.int8) actual = test_util.NHWCToNCHW_VECT_C(actual) actual = array_ops.bitcast(actual, dtypes.qint8) actual = array_ops.space_to_depth(actual, block_size, data_format=data_format) actual = array_ops.bitcast(actual, dtypes.int8) actual = test_util.NCHW_VECT_CToNHWC(actual) actual = array_ops.bitcast(actual, dtypes.qint8) expected = array_ops.bitcast(t, dtypes.int8) expected = math_ops.cast(expected, dtypes.float32) expected = self.spaceToDepthUsingTranspose( expected, block_size, "NHWC") expected = math_ops.cast(expected, dtypes.int8) expected = array_ops.bitcast(expected, dtypes.qint8) else: # Initialize the input tensor with ascending whole numbers as floats. actual = array_ops.space_to_depth(t, block_size, data_format=data_format) expected = self.spaceToDepthUsingTranspose( t, block_size, data_format) actual_vals, expected_vals = self.evaluate([actual, expected]) self.assertTrue(np.array_equal(actual_vals, expected_vals))
def bitcast( input: ragged_tensor.RaggedOrDense, # pylint: disable=redefined-builtin type, # pylint: disable=redefined-builtin name=None) -> ragged_tensor.RaggedOrDense: """RaggedTensor dispatch override for tf.bitcast.""" type = dtypes.as_dtype(type) with ops.name_scope(name, 'Bitcast', [input]): input = ragged_tensor.convert_to_tensor_or_ragged_tensor( input, name='input') if (input.dtype.size < type.size and input.flat_values.shape.rank < 2): raise ValueError('`input.flat_values` is required to have rank >= 2 when ' 'input.dtype.size < type.size. Actual rank: ' f'{input.flat_values.shape.rank}') return input.with_flat_values(array_ops.bitcast(input.flat_values, type))
def testErrors(self): x = np.zeros([1, 1], np.int8) datatype = dtypes.int32 with self.assertRaisesRegex((ValueError, errors.InvalidArgumentError), "Cannot bitcast from 6 to 3"): array_ops.bitcast(x, datatype, None)
def runTest(self, test_param, apply_relu): """Runs tests for dimensions configured in test_param.""" batch_size = test_param["batch_size"] input_channels = test_param["input_channels"] output_channels = test_param["output_channels"] input_height = test_param["input_height"] input_width = test_param["input_width"] filter_height = test_param["filter_height"] filter_width = test_param["filter_width"] vertical_stride = test_param["vertical_stride"] horizontal_stride = test_param["horizontal_stride"] conv_input_scale = test_param["conv_input_scale"] side_input_scale = test_param["side_input_scale"] bias_scale = test_param["bias_scale"] padding_type = test_param["padding_type"] with self.session() as sess, self.test_scope(): conv_input, _, _ = gen_array_ops.quantize_v2( random_ops.random_uniform( [batch_size, input_height, input_width, input_channels], minval=-0.0, maxval=1.0, dtype=dtypes.float32), -1.0, 1.0, dtypes.qint8, mode="SCALED") self.assertTrue( sess.run( math_ops.reduce_all( math_ops.greater_equal( array_ops.bitcast(conv_input, dtypes.int8), 0)))) kernel, _, _ = gen_array_ops.quantize_v2( random_ops.random_uniform( [filter_height, filter_width, input_channels, output_channels], minval=-1.0, maxval=1.0, dtype=dtypes.float32), -1.0, 1.0, dtypes.qint8, mode="SCALED") output_height = _CalculateConvolvedOutputDim(input_height, filter_height, vertical_stride, padding_type) output_width = _CalculateConvolvedOutputDim(input_width, filter_width, horizontal_stride, padding_type) tf_logging.info("output_height=%s, output_width=%s", output_height, output_width) side_input, _, _ = gen_array_ops.quantize_v2( random_ops.random_uniform( [batch_size, output_height, output_width, output_channels], minval=0.0, maxval=1.0, dtype=dtypes.float32), -1.0, 1.0, dtypes.qint8, mode="SCALED") biases = random_ops.random_uniform([output_channels], minval=-10 * bias_scale, maxval=20 * bias_scale, dtype=dtypes.float32) strides = [1, vertical_stride, horizontal_stride, 1] actual = fused_conv2d_bias_activation_op.fused_conv2d_bias_activation( conv_input, kernel, biases, strides=strides, padding=padding_type, conv_input_scale=conv_input_scale, side_input_scale=side_input_scale, side_input=(None if side_input_scale == 0.0 else side_input), activation_mode="Relu" if apply_relu else "None", data_format="NHWC", filter_format="HWIO") expected = _SimulateFusedConv2dBiasActivationInt8OnCpu( conv_input_scale, conv_input, kernel, padding_type, strides, side_input_scale, side_input, biases, apply_relu) actual_y, expected_y = sess.run([actual, expected]) self.assertAllClose(actual_y, expected_y, rtol=0, atol=1)
def testErrors(self): x = np.zeros([1, 1], np.int8) datatype = dtypes.int32 with self.assertRaisesRegexp(ValueError, "Cannot bitcast due to shape"): array_ops.bitcast(x, datatype, None)
def testUnknown(self): x = array_ops.placeholder(dtypes.float32) datatype = dtypes.int8 array_ops.bitcast(x, datatype, None)
def f(x): t = array_ops.bitcast(x, dtypes.float32) return math_ops.reduce_sum(t, axis=1)
def runTest(self, test_param, apply_relu): """Runs tests for dimensions configured in test_param.""" batch_size = test_param["batch_size"] input_channels = test_param["input_channels"] output_channels = test_param["output_channels"] input_height = test_param["input_height"] input_width = test_param["input_width"] filter_height = test_param["filter_height"] filter_width = test_param["filter_width"] vertical_stride = test_param["vertical_stride"] horizontal_stride = test_param["horizontal_stride"] conv_input_scale = test_param["conv_input_scale"] side_input_scale = test_param["side_input_scale"] bias_scale = test_param["bias_scale"] padding_type = test_param["padding_type"] with self.session() as sess, self.test_scope(): conv_input, _, _ = gen_array_ops.quantize_v2( random_ops.random_uniform( [batch_size, input_channels // 4, input_height, input_width, 4], minval=0.0, maxval=1.0, dtype=dtypes.float32), -1.0, 1.0, dtypes.qint8, mode="SCALED") self.assertTrue( sess.run( math_ops.reduce_all( math_ops.greater_equal( array_ops.bitcast(conv_input, dtypes.int8), 0)))) kernel, _, _ = gen_array_ops.quantize_v2( random_ops.random_uniform([ output_channels, input_channels // 4, filter_height, filter_width, 4 ], minval=-128.0, maxval=127.0, dtype=dtypes.float32), -128.0, 127.0, dtypes.qint8, mode="SCALED") output_height = _CalculateConvolvedOutputDim(input_height, filter_height, vertical_stride, padding_type) output_width = _CalculateConvolvedOutputDim(input_width, filter_width, horizontal_stride, padding_type) tf_logging.info("output_height=%s, output_width=%s", output_height, output_width) side_input, _, _ = gen_array_ops.quantize_v2( random_ops.random_uniform([ batch_size, output_channels // 4, output_height, output_width, 4 ], minval=0.0, maxval=1.0, dtype=dtypes.float32), -1.0, 1.0, dtypes.qint8, mode="SCALED") biases = random_ops.random_uniform([output_channels], minval=-10 * bias_scale, maxval=20 * bias_scale, dtype=dtypes.float32) with ops.device("/cpu:0"): t = fused_conv2d_bias_activation_op.fused_conv2d_bias_activation( _Int8Roundtrip(_NchwVectCToNhwc, conv_input), _Int8Roundtrip(_OihwVectIToHwio, kernel), biases, strides=[1, vertical_stride, horizontal_stride, 1], padding=padding_type, conv_input_scale=conv_input_scale, side_input_scale=side_input_scale, side_input=(None if side_input_scale == 0.0 else _Int8Roundtrip( _NchwVectCToNhwc, side_input)), activation_mode="Relu" if apply_relu else "None", data_format="NHWC", filter_format="HWIO") cpu_result = _Int8Roundtrip(_NhwcToNchwVectC, t) with ops.device("/gpu:0"): t = fused_conv2d_bias_activation_op.fused_conv2d_bias_activation( conv_input, kernel, biases, strides=[1, 1, vertical_stride, horizontal_stride], padding=padding_type, conv_input_scale=conv_input_scale, side_input_scale=side_input_scale, side_input=(None if side_input_scale == 0.0 else side_input), activation_mode="Relu" if apply_relu else "None", data_format="NCHW_VECT_C", filter_format="OIHW_VECT_I") gpu_result = t cpu_y, gpu_y = sess.run([cpu_result, gpu_result]) self.assertAllClose(cpu_y, gpu_y, rtol=0, atol=0)
def _Int8Roundtrip(fn, tensor): return array_ops.bitcast(fn(array_ops.bitcast(tensor, dtypes.int8)), dtypes.qint8)
def testUnknownShape(self): # Need to use placeholder for unknown shape with ops.Graph().as_default(): x = array_ops.placeholder(dtypes.float32) datatype = dtypes.int8 array_ops.bitcast(x, datatype, None)