<commit_before>/* Copyright 2015 The TensorFlow Authors. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/

#ifndef TENSORFLOW_CORE_UTIL_SPARSE_SPARSE_TENSOR_H_
#define TENSORFLOW_CORE_UTIL_SPARSE_SPARSE_TENSOR_H_

#include <limits>
#include <numeric>
#include <vector>

#include "absl/base/macros.h"
#include "third_party/eigen3/unsupported/Eigen/CXX11/Tensor"
#include "tensorflow/core/framework/bounds_check.h"
#include "tensorflow/core/framework/tensor.h"
#include "tensorflow/core/framework/tensor_types.h"
#include "tensorflow/core/framework/types.h"
#include "tensorflow/core/framework/types.pb.h"
#include "tensorflow/core/lib/core/errors.h"
#include "tensorflow/core/lib/core/status.h"
#include "tensorflow/core/lib/strings/str_util.h"
#include "tensorflow/core/lib/strings/strcat.h"
#include "tensorflow/core/platform/logging.h"
#include "tensorflow/core/platform/types.h"
#include "tensorflow/core/util/sparse/dim_comparator.h"
#include "tensorflow/core/util/sparse/group_iterator.h"

namespace tensorflow {
namespace sparse {

class SparseTensor {
 public:
  typedef typename gtl::ArraySlice<int64> VarDimArray;
  typedef typename gtl::InlinedVector<int64, 8> ShapeArray;

  static Status Create(Tensor ix, Tensor vals, const VarDimArray shape,
                       const VarDimArray order, SparseTensor* result) {
    if (ix.dtype() != DT_INT64) {
      return Status(
          error::INVALID_ARGUMENT,
          strings::StrCat("indices must be type int64 but got: ", ix.dtype()));
    }
    if (!TensorShapeUtils::IsVector(vals.shape())) {
      return Status(error::INVALID_ARGUMENT,
                    strings::StrCat("vals must be a vec, but got: ",
                                    vals.shape().DebugString()));
    }
    if (ix.shape().dim_size(0) != vals.shape().dim_size(0)) {
      return Status(error::INVALID_ARGUMENT,
                    strings::StrCat("indices and values rows (indexing "
                                    "dimension) must match. (indices = ",
                                    ix.shape().dim_size(0), ", values = ",
                                    vals.shape().dim_size(0), ")"));
    }
    int dims = 0;
    TF_RETURN_IF_ERROR(GetDimsFromIx(ix, &dims));
    if (order.size() != dims) {
      return Status(error::INVALID_ARGUMENT,
                    "Order length must be SparseTensor rank.");
    }
    if (shape.size() != dims) {
      return Status(error::INVALID_ARGUMENT,
                    "Shape rank must be SparseTensor rank.");
    }

    *result = SparseTensor(std::move(ix), std::move(vals), shape, order);
    return Status();
  }

  static Status Create(Tensor ix, Tensor vals, const TensorShape& shape,
                       SparseTensor* result) {
    return Create(std::move(ix), std::move(vals), TensorShapeToVector(shape),
                  UndefinedOrder(TensorShapeToVector(shape)), result);
  }

  static Status Create(Tensor ix, Tensor vals, const VarDimArray shape,
                       SparseTensor* result) {
    return Create(std::move(ix), std::move(vals), shape, UndefinedOrder(shape),
                  result);
  }

  static Status Create(Tensor ix, Tensor vals, const TensorShape& shape,
                       const VarDimArray order, SparseTensor* result) {
    return Create(std::move(ix), std::move(vals), TensorShapeToVector(shape),
                  order, result);
  }

  SparseTensor() : dims_(0) {}

  ABSL_DEPRECATED("Use Create() functions instead of constructors directly.")
  SparseTensor(Tensor ix, Tensor vals, const TensorShape& shape)
      : SparseTensor(std::move(ix), std::move(vals), TensorShapeToVector(shape),
                     UndefinedOrder(TensorShapeToVector(shape))) {}

  ABSL_DEPRECATED("Use Create() functions instead of constructors directly.")
  SparseTensor(Tensor ix, Tensor vals, const VarDimArray shape)
      : SparseTensor(std::move(ix), std::move(vals), shape,
                     UndefinedOrder(shape)) {}

  ABSL_DEPRECATED("use Create() functions instead of constructors directly.")
  SparseTensor(Tensor ix, Tensor vals, const TensorShape& shape,
               const VarDimArray order)
      : SparseTensor(std::move(ix), std::move(vals), TensorShapeToVector(shape),
                     order) {}

  ABSL_DEPRECATED("Use Create() functions instead of constructors directly.")
  SparseTensor(Tensor ix, Tensor vals, const VarDimArray shape,
               const VarDimArray order)
      : ix_(std::move(ix)),
        vals_(std::move(vals)),
        shape_(shape.begin(), shape.end()),
        order_(order.begin(), order.end()),
        dims_(UnsafeGetDimsFromIx(ix)) {
    DCHECK_EQ(ix.dtype(), DT_INT64)
        << "indices must be type int64 but got: " << ix.dtype();
    DCHECK(TensorShapeUtils::IsVector(vals.shape()))
        << "vals must be a vec, but got: " << vals.shape().DebugString();
    DCHECK_EQ(ix.shape().dim_size(0), vals.shape().dim_size(0))
        << "indices and values rows (indexing dimension) must match.";
    DCHECK_EQ(order.size(), dims_) << "Order length must be SparseTensor rank.";
    DCHECK_EQ(shape.size(), dims_) << "Shape rank must be SparseTensor rank.";
  }

  SparseTensor(const SparseTensor& other)
      : SparseTensor(other.ix_, other.vals_, other.shape_, other.order_) {}

  SparseTensor(SparseTensor&& other)
      : SparseTensor(std::move(other.ix_), std::move(other.vals_),
                     std::move(other.shape_), std::move(other.order_)) {}

  SparseTensor& operator=(const SparseTensor& other) {
    ix_ = other.ix_;
    vals_ = other.vals_;
    shape_ = other.shape_;
    order_ = other.order_;
    dims_ = other.dims_;
    return *this;
  }<commit_msg>In SparseTensor::Create and constructor, forward Tensor arguments using std::move.<commit_after>/* Copyright 2015 The TensorFlow Authors. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/

#ifndef TENSORFLOW_CORE_UTIL_SPARSE_SPARSE_TENSOR_H_
#define TENSORFLOW_CORE_UTIL_SPARSE_SPARSE_TENSOR_H_

#include <limits>
#include <numeric>
#include <vector>

#include "absl/base/macros.h"
#include "third_party/eigen3/unsupported/Eigen/CXX11/Tensor"
#include "tensorflow/core/framework/bounds_check.h"
#include "tensorflow/core/framework/tensor.h"
#include "tensorflow/core/framework/tensor_types.h"
#include "tensorflow/core/framework/types.h"
#include "tensorflow/core/framework/types.pb.h"
#include "tensorflow/core/lib/core/errors.h"
#include "tensorflow/core/lib/core/status.h"
#include "tensorflow/core/lib/strings/str_util.h"
#include "tensorflow/core/lib/strings/strcat.h"
#include "tensorflow/core/platform/logging.h"
#include "tensorflow/core/platform/types.h"
#include "tensorflow/core/util/sparse/dim_comparator.h"
#include "tensorflow/core/util/sparse/group_iterator.h"

namespace tensorflow {
namespace sparse {

class SparseTensor {
 public:
  typedef typename gtl::ArraySlice<int64> VarDimArray;
  typedef typename gtl::InlinedVector<int64, 8> ShapeArray;

  static Status Create(Tensor ix, Tensor vals, const VarDimArray shape,
                       const VarDimArray order, SparseTensor* result) {
    if (ix.dtype() != DT_INT64) {
      return Status(
          error::INVALID_ARGUMENT,
          strings::StrCat("indices must be type int64 but got: ", ix.dtype()));
    }
    if (!TensorShapeUtils::IsVector(vals.shape())) {
      return Status(error::INVALID_ARGUMENT,
                    strings::StrCat("vals must be a vec, but got: ",
                                    vals.shape().DebugString()));
    }
    if (ix.shape().dim_size(0) != vals.shape().dim_size(0)) {
      return Status(error::INVALID_ARGUMENT,
                    strings::StrCat("indices and values rows (indexing "
                                    "dimension) must match. (indices = ",
                                    ix.shape().dim_size(0), ", values = ",
                                    vals.shape().dim_size(0), ")"));
    }
    int dims = 0;
    TF_RETURN_IF_ERROR(GetDimsFromIx(ix, &dims));
    if (order.size() != dims) {
      return Status(error::INVALID_ARGUMENT,
                    "Order length must be SparseTensor rank.");
    }
    if (shape.size() != dims) {
      return Status(error::INVALID_ARGUMENT,
                    "Shape rank must be SparseTensor rank.");
    }

    *result = SparseTensor(ix, vals, shape, order);
    return Status();
  }

  static Status Create(Tensor ix, Tensor vals, const TensorShape& shape,
                       SparseTensor* result) {
    return Create(ix, vals, TensorShapeToVector(shape),
                  UndefinedOrder(TensorShapeToVector(shape)), result);
  }

  static Status Create(Tensor ix, Tensor vals, const VarDimArray shape,
                       SparseTensor* result) {
    return Create(ix, vals, shape, UndefinedOrder(shape), result);
  }

  static Status Create(Tensor ix, Tensor vals, const TensorShape& shape,
                       const VarDimArray order, SparseTensor* result) {
    return Create(ix, vals, TensorShapeToVector(shape), order, result);
  }

  SparseTensor() : dims_(0) {}

  ABSL_DEPRECATED("Use Create() functions instead of constructors directly.")
  SparseTensor(Tensor ix, Tensor vals, const TensorShape& shape)
      : SparseTensor(ix, vals, TensorShapeToVector(shape),
                     UndefinedOrder(TensorShapeToVector(shape))) {}

  ABSL_DEPRECATED("Use Create() functions instead of constructors directly.")
  SparseTensor(Tensor ix, Tensor vals, const VarDimArray shape)
      : SparseTensor(ix, vals, shape, UndefinedOrder(shape)) {}

  ABSL_DEPRECATED("use Create() functions instead of constructors directly.")
  SparseTensor(Tensor ix, Tensor vals, const TensorShape& shape,
               const VarDimArray order)
      : SparseTensor(ix, vals, TensorShapeToVector(shape), order) {}

  ABSL_DEPRECATED("Use Create() functions instead of constructors directly.")
  SparseTensor(Tensor ix, Tensor vals, const VarDimArray shape,
               const VarDimArray order)
      : ix_(ix),
        vals_(vals),
        shape_(shape.begin(), shape.end()),
        order_(order.begin(), order.end()),
        dims_(UnsafeGetDimsFromIx(ix)) {
    DCHECK_EQ(ix.dtype(), DT_INT64)
        << "indices must be type int64 but got: " << ix.dtype();
    DCHECK(TensorShapeUtils::IsVector(vals.shape()))
        << "vals must be a vec, but got: " << vals.shape().DebugString();
    DCHECK_EQ(ix.shape().dim_size(0), vals.shape().dim_size(0))
        << "indices and values rows (indexing dimension) must match.";
    DCHECK_EQ(order.size(), dims_) << "Order length must be SparseTensor rank.";
    DCHECK_EQ(shape.size(), dims_) << "Shape rank must be SparseTensor rank.";
  }

  SparseTensor(const SparseTensor& other)
      : SparseTensor(other.ix_, other.vals_, other.shape_, other.order_) {}

  SparseTensor(SparseTensor&& other)
      : SparseTensor(std::move(other.ix_), std::move(other.vals_),
                     std::move(other.shape_), std::move(other.order_)) {}

  SparseTensor& operator=(const SparseTensor& other) {
    ix_ = other.ix_;
    vals_ = other.vals_;
    shape_ = other.shape_;
    order_ = other.order_;
    dims_ = other.dims_;
    return *this;
  }
{'fraction_non_alphanumeric': 0.13140112350402997, 'fraction_numerical': 0.005210453472278759, 'mean_word_length': 3.3071528751753156, 'pattern_counts': {'":': 0, '<': 41, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7239106', 'n_tokens_mistral': 3713, 'n_tokens_neox': 3583, 'n_words': 898}