| 39 | } |
| 40 | |
| 41 | void Compute(OpKernelContext* context) override { |
| 42 | const auto& input = context->input(0); |
| 43 | int64 str_size = -1; |
| 44 | auto flat_in = input.flat<tstring>(); |
| 45 | for (int64 i = 0; i < flat_in.size(); ++i) { |
| 46 | const string& in_str = flat_in(i); |
| 47 | if (str_size == -1) { |
| 48 | str_size = in_str.size(); |
| 49 | } else { |
| 50 | OP_REQUIRES(context, str_size == in_str.size(), |
| 51 | errors::InvalidArgument( |
| 52 | "DecodeRaw requires input strings to all be the same " |
| 53 | "size, but element ", |
| 54 | i, " has size ", str_size, " != ", in_str.size())); |
| 55 | } |
| 56 | } |
| 57 | TensorShape out_shape = input.shape(); |
| 58 | if (str_size == -1 || str_size == 0) { // Empty input |
| 59 | out_shape.AddDim(0); |
| 60 | Tensor* output_tensor = nullptr; |
| 61 | OP_REQUIRES_OK(context, context->allocate_output("output", out_shape, |
| 62 | &output_tensor)); |
| 63 | return; |
| 64 | } |
| 65 | OP_REQUIRES( |
| 66 | context, str_size % sizeof(T) == 0, |
| 67 | errors::InvalidArgument("Input to DecodeRaw has length ", str_size, |
| 68 | " that is not a multiple of ", sizeof(T), |
| 69 | ", the size of ", DataTypeString(out_type_))); |
| 70 | const int64 added_dim = str_size / sizeof(T); |
| 71 | out_shape.AddDim(added_dim); |
| 72 | Tensor* output_tensor = nullptr; |
| 73 | OP_REQUIRES_OK( |
| 74 | context, context->allocate_output("output", out_shape, &output_tensor)); |
| 75 | auto out = output_tensor->flat_inner_dims<T>(); |
| 76 | DCHECK_EQ(flat_in.size(), out.dimensions()[0]); |
| 77 | T* out_data = out.data(); |
| 78 | |
| 79 | // If the data is already in the host's byte order, or if the width of the |
| 80 | // output type is a single byte, we can copy the memory directly. |
| 81 | if (!convert_data_endianness_ || sizeof(T) == 1) { |
| 82 | for (int64 i = 0; i < flat_in.size(); ++i) { |
| 83 | const T* in_data = reinterpret_cast<const T*>(flat_in(i).data()); |
| 84 | memcpy(out_data, in_data, str_size); |
| 85 | out_data += added_dim; |
| 86 | } |
| 87 | } else { |
| 88 | // Otherwise, the data is not in the host's byte order, and rather than a |
| 89 | // direct copy, we need to reverse the byte ordering of each element. |
| 90 | for (int64 i = 0; i < flat_in.size(); ++i) { |
| 91 | const char* in_data_bytes = |
| 92 | reinterpret_cast<const char*>(flat_in(i).data()); |
| 93 | char* out_data_bytes = reinterpret_cast<char*>(out_data); |
| 94 | const char* p = in_data_bytes; |
| 95 | char* q = out_data_bytes; |
| 96 | for (; p < in_data_bytes + str_size; p += sizeof(T), q += sizeof(T)) { |
| 97 | std::reverse_copy(p, p + sizeof(T), q); |
| 98 | } |
nothing calls this directly
no test coverage detected