diff options
author | 2017-12-20 20:54:25 -0800 | |
---|---|---|
committer | 2017-12-20 20:57:54 -0800 | |
commit | 96f3023b6a8b154c3840776c5feff3e028860a36 (patch) | |
tree | 023052b527aaf486dc52aba70bbf4de84685527f /tensorflow/core/util/example_proto_helper.h | |
parent | 469e10274cb4e0c79cd314d3986917f322d4e0c1 (diff) |
[tf.data] Add `tf.contrib.data.parse_single_example()`.
The new op is a fused implementation of the existing
`tf.parse_single_example()`, which is more efficient when parsing a
single Example at a time.
PiperOrigin-RevId: 179768512
Diffstat (limited to 'tensorflow/core/util/example_proto_helper.h')
-rw-r--r-- | tensorflow/core/util/example_proto_helper.h | 70 |
1 files changed, 68 insertions, 2 deletions
diff --git a/tensorflow/core/util/example_proto_helper.h b/tensorflow/core/util/example_proto_helper.h index 7414d61e8b..8b3c6c5a3f 100644 --- a/tensorflow/core/util/example_proto_helper.h +++ b/tensorflow/core/util/example_proto_helper.h @@ -148,9 +148,9 @@ Tensor FeatureSparseCopy(const std::size_t batch, const string& key, int64 CopyIntoSparseTensor(const Tensor& in, const int batch, const int64 offset, Tensor* indices, Tensor* values); -// Parses the attributes passed to ParseSingleExample. +// Parses the attributes passed to ParseExample. // REQUIRES: Init must be called after construction. -class ParseSingleExampleAttrs { +class ParseExampleAttrs { public: template <typename ContextType> Status Init(ContextType* ctx) { @@ -205,6 +205,72 @@ class ParseSingleExampleAttrs { Status FinishInit(); // for context-independent parts of Init. }; +// Parses the attributes passed to ParseSingleExample. +// REQUIRES: Init must be called after construction. +class ParseSingleExampleAttrs { + public: + template <typename ContextType> + Status Init(ContextType* ctx) { + TF_RETURN_IF_ERROR(ctx->GetAttr("sparse_keys", &sparse_keys)); + TF_RETURN_IF_ERROR(ctx->GetAttr("sparse_types", &sparse_types)); + TF_RETURN_IF_ERROR(ctx->GetAttr("dense_keys", &dense_keys)); + TF_RETURN_IF_ERROR(ctx->GetAttr("Tdense", &dense_types)); + TF_RETURN_IF_ERROR(ctx->GetAttr("dense_shapes", &dense_shapes)); + + int num_sparse; + TF_RETURN_IF_ERROR(ctx->GetAttr("num_sparse", &num_sparse)); + if (num_sparse != sparse_keys.size() || num_sparse != sparse_types.size()) { + return errors::InvalidArgument( + "num_sparse (", num_sparse, ") must match the size of sparse_keys (", + sparse_keys.size(), ") and sparse_types (", sparse_types.size(), ")"); + } + + // Temporary check until we start allowing a variable length outer + // dimension. + for (int i = 0; i < dense_shapes.size(); ++i) { + bool shape_ok = true; + if (dense_shapes[i].dims() == -1) { + shape_ok = false; + } else { + for (int d = 1; d < dense_shapes[i].dims(); ++d) { + if (dense_shapes[i].dim_size(d) == -1) { + shape_ok = false; + } + } + } + if (!shape_ok) { + return errors::InvalidArgument( + "dense_shapes[", i, + "] has unknown rank or unknown inner dimensions: ", + dense_shapes[i].DebugString()); + } + TensorShape dense_shape; + if (dense_shapes[i].dims() > 0 && dense_shapes[i].dim_size(0) == -1) { + variable_length.push_back(true); + for (int d = 1; d < dense_shapes[i].dims(); ++d) { + dense_shape.AddDim(dense_shapes[i].dim_size(d)); + } + } else { + variable_length.push_back(false); + dense_shapes[i].AsTensorShape(&dense_shape); + } + elements_per_stride.push_back(dense_shape.num_elements()); + } + return FinishInit(); + } + + std::vector<string> sparse_keys; + std::vector<DataType> sparse_types; + std::vector<string> dense_keys; + std::vector<DataType> dense_types; + std::vector<PartialTensorShape> dense_shapes; + std::vector<bool> variable_length; + std::vector<std::size_t> elements_per_stride; + + private: + Status FinishInit(); // for context-independent parts of Init. +}; + // Parses the attributes passed to ParseSingleSequenceExample. // REQUIRES: Init must be called after construction. class ParseSingleSequenceExampleAttrs { |