text: //*****************************************************************************
  // Copyright 2017-2020 Intel Corporation
  //
  // 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.
  //*****************************************************************************
  
  #include "ngraph/runtime/tensor.hpp"
  #include "ngraph/descriptor/layout/tensor_layout.hpp"
  #include "ngraph/log.hpp"
  #include "ngraph/runtime/aligned_buffer.hpp"
  #include "ngraph/type/element_type.hpp"
  
  using namespace ngraph;
  using namespace std;
  
  const Shape& runtime::Tensor::get_shape() const
  {
      return m_descriptor->get_shape();
  }
  
  const PartialShape& runtime::Tensor::get_partial_shape() const
  {
      return m_descriptor->get_partial_shape();
  }
  
  Strides runtime::Tensor::get_strides() const
  {
      return m_descriptor->get_tensor_layout()->get_strides();
  }
  
  const element::Type& runtime::Tensor::get_element_type() const
  {
      return m_descriptor->get_element_type();
  }
  
  shared_ptr<descriptor::layout::TensorLayout> runtime::Tensor::get_tensor_layout() const
  {
      return m_descriptor->get_tensor_layout();
  }
  
  void runtime::Tensor::set_tensor_layout(const shared_ptr<descriptor::layout::TensorLayout>& layout)
  {
      m_descriptor->set_tensor_layout(layout);
  }
  
  size_t runtime::Tensor::get_element_count() const
  {
      return get_tensor_layout()->get_size();
  }
  
  size_t runtime::Tensor::get_size_in_bytes() const
  {
      return get_tensor_layout()->get_size() * get_element_type().size();
  }
  
  const std::string& runtime::Tensor::get_name() const
  {
      return m_descriptor->get_name();
  }
  
  bool runtime::Tensor::get_stale() const
  {
      return m_stale;
  }
  
  void runtime::Tensor::set_stale(bool val)
  {
      m_stale = val;
  }
  
  void runtime::Tensor::copy_from(const ngraph::runtime::Tensor& source)
  {
      if (get_element_count() != source.get_element_count())
      {
          throw invalid_argument("runtime::Tensor::copy_from element count must match");
      }
      if (get_element_type() != source.get_element_type())
      {
          throw invalid_argument("runtime::Tensor::copy_from element types must match");
      }
      // This is potentially inefficient but is supplied only to get things going
      // This is be replaced with more optimial implementations in later PRs
      auto size = get_size_in_bytes();
      AlignedBuffer buffer{size, 64};
      source.read(buffer.get_ptr(), size);
      write(buffer.get_ptr(), size);
  }
  