LCOV - code coverage report
Current view: top level - core - element_array_view.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 37 37 100.0 %
Date: 2024-11-17 01:47:58 Functions: 5 5 100.0 %

          Line data    Source code
       1             : // SPDX-License-Identifier: BSD-3-Clause
       2             : // Copyright (c) 2023 Scipp contributors (https://github.com/scipp)
       3             : /// @file
       4             : /// @author Simon Heybrock
       5             : #include "scipp/core/element_array_view.h"
       6             : #include "scipp/core/except.h"
       7             : 
       8             : namespace scipp::core {
       9             : 
      10             : namespace {
      11     3618994 : void expectCanBroadcastFromTo(const Dimensions &source,
      12             :                               const Dimensions &target) {
      13     3618994 :   if (source == target)
      14     3378268 :     return;
      15      538010 :   for (const auto &dim : target.labels())
      16      297285 :     if (source.contains(dim) && (source[dim] < target[dim]))
      17           1 :       throw except::DimensionError("Cannot broadcast/slice dimension since "
      18             :                                    "data has mismatching but smaller "
      19           2 :                                    "dimension extent.");
      20             : }
      21             : } // namespace
      22             : 
      23             : /// Construct ElementArrayViewParams.
      24             : ///
      25             : /// @param offset Start offset from beginning of array.
      26             : /// @param iter_dims Dimensions to use for iteration.
      27             : /// @param strides Strides in memory, order matches that of iterDims.
      28             : /// @param bucket_params Optional, in case of view onto bucket-variable this
      29             : /// holds parameters for accessing individual buckets.
      30     8462769 : ElementArrayViewParams::ElementArrayViewParams(
      31             :     const scipp::index offset, const Dimensions &iter_dims,
      32     8462769 :     const Strides &strides, const BucketParams &bucket_params)
      33     8462769 :     : m_offset(offset), m_iterDims(iter_dims), m_strides(strides),
      34     8462769 :       m_bucketParams(bucket_params) {}
      35             : 
      36             : /// Construct ElementArrayViewParams from another ElementArrayViewParams, with
      37             : /// different iteration dimensions.
      38             : ///
      39             : /// A good way to think of this is of a non-contiguous underlying data array,
      40             : /// e.g., since the other view may represent a slice. This also supports
      41             : /// broadcasting the slice.
      42     3618994 : ElementArrayViewParams::ElementArrayViewParams(
      43     3618994 :     const ElementArrayViewParams &other, const Dimensions &iterDims)
      44     3618994 :     : m_offset(other.m_offset), m_iterDims(iterDims),
      45     3618994 :       m_bucketParams(other.m_bucketParams) {
      46     3618994 :   expectCanBroadcastFromTo(other.m_iterDims, m_iterDims);
      47             : 
      48     3618993 :   m_strides.resize(iterDims.ndim());
      49     5686049 :   for (scipp::index dim = 0; dim < iterDims.ndim(); ++dim) {
      50     2067056 :     auto label = iterDims.label(dim);
      51     2067056 :     if (other.m_iterDims.contains(label)) {
      52     1792373 :       m_strides[dim] = other.m_strides[other.m_iterDims.index(label)];
      53             :     } else {
      54      274683 :       m_strides[dim] = 0;
      55             :     }
      56             :   }
      57     3618996 : }
      58             : 
      59       76332 : void ElementArrayViewParams::requireContiguous() const {
      60       76332 :   if (m_bucketParams || m_strides != Strides(m_iterDims))
      61          16 :     throw std::runtime_error("Data is not contiguous");
      62       76316 : }
      63             : 
      64             : [[nodiscard]] bool
      65         510 : ElementArrayViewParams::overlaps(const ElementArrayViewParams &other) const {
      66         838 :   if (m_offset == other.m_offset && m_iterDims == other.m_iterDims &&
      67         328 :       m_strides == other.m_strides) {
      68             :     // When both views are exactly the same, we should be fine without
      69             :     // making extra copies.
      70         328 :     return false;
      71             :   }
      72             :   // Otherwise check for partial overlap.
      73         546 :   const auto [this_begin, this_end] = memory_bounds(
      74         546 :       m_iterDims.shape().begin(), m_iterDims.shape().end(), m_strides.begin());
      75         182 :   const auto [other_begin, other_end] =
      76         182 :       memory_bounds(other.m_iterDims.shape().begin(),
      77         364 :                     other.m_iterDims.shape().end(), other.m_strides.begin());
      78         182 :   return ((this_begin < other_end) && (this_end > other_begin));
      79             : }
      80             : 
      81             : } // namespace scipp::core

Generated by: LCOV version 1.14