LCOV - code coverage report
Current view: top level - variable - subspan_view.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 43 46 93.5 %
Date: 2024-11-17 01:47:58 Functions: 66 74 89.2 %

          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/variable/subspan_view.h"
       6             : #include "scipp/core/eigen.h"
       7             : #include "scipp/core/except.h"
       8             : #include "scipp/variable/cumulative.h"
       9             : #include "scipp/variable/shape.h"
      10             : #include "scipp/variable/transform.h"
      11             : #include "scipp/variable/util.h"
      12             : 
      13             : namespace scipp::variable {
      14             : 
      15             : namespace {
      16             : 
      17             : template <class T>
      18      320241 : auto make_subspans(T *base, const Variable &indices,
      19             :                    const scipp::index stride) {
      20      320241 :   if (stride != 1)
      21           0 :     throw std::logic_error(
      22             :         "span only supports stride=1, this should be "
      23             :         "unreachable due to an earlier check, may want to generalize this "
      24             :         "later to support in particular stride=0 for broadcasted buffers");
      25             :   return variable::transform<scipp::index_pair>(
      26             :       indices,
      27             :       overloaded{core::transform_flags::expect_no_variance_arg<0>,
      28      320241 :                  [](const units::Unit &) { return units::one; },
      29     1229166 :                  [base, stride](const auto &offset) {
      30     2458332 :                    return scipp::span(base + stride * offset.first,
      31     1229166 :                                       base + stride * offset.second);
      32             :                  }},
      33      320241 :       "make_subspans");
      34             : }
      35             : 
      36             : /// Return Variable containing spans with extents given by indices over given
      37             : /// dimension as elements.
      38             : template <class T, class Var>
      39      316763 : Variable subspan_view(Var &var, const Dim dim, const Variable &indices) {
      40      316763 :   auto subspans =
      41             :       make_subspans(var.template values<T>().data(), indices, var.stride(dim));
      42      316762 :   if (var.has_variances())
      43        3479 :     subspans.setVariances(make_subspans(var.template variances<T>().data(),
      44             :                                         indices, var.stride(dim)));
      45      316762 :   subspans.setUnit(var.unit());
      46      316762 :   return subspans;
      47           0 : }
      48             : 
      49             : template <class... Ts, class... Args>
      50      316763 : auto invoke_subspan_view(const DType dtype, Args &&...args) {
      51      316763 :   Variable ret;
      52      633525 :   if (!((scipp::dtype<Ts> == dtype
      53      633533 :              ? (ret = subspan_view<Ts>(std::forward<Args>(args)...), true)
      54             :              : false) ||
      55             :         ...))
      56           0 :     throw except::TypeError("Unsupported dtype.");
      57      316762 :   return ret;
      58           1 : }
      59             : 
      60             : template <class Var, class... Args>
      61      316764 : Variable subspan_view_impl(Var &var, const Dim dim, Args &&...args) {
      62      316764 :   if (var.stride(dim) != 1)
      63           1 :     throw except::DimensionError(
      64             :         "View over subspan can only be created for contiguous "
      65             :         "range of data.");
      66             :   return invoke_subspan_view<double, float, int64_t, int32_t, bool,
      67             :                              core::time_point, std::string, Eigen::Vector3d>(
      68      316763 :       var.dtype(), var, dim, args...);
      69             : }
      70             : 
      71         399 : auto make_range(const scipp::index num, const scipp::index stride,
      72             :                 const Dim dim) {
      73         798 :   return cumsum(broadcast(stride * units::one, {dim, num}), dim,
      74         798 :                 CumSumMode::Exclusive);
      75             : }
      76             : 
      77      215732 : Variable make_indices(const Variable &var, const Dim dim) {
      78      215732 :   auto dims = var.dims();
      79      215732 :   dims.erase(dim);
      80      215732 :   auto start = scipp::index(0) * units::one;
      81      216131 :   for (const auto &label : dims) {
      82         399 :     const auto stride = var.stride(label);
      83         399 :     start = start + make_range(dims[label], stride, label);
      84             :   }
      85      647196 :   return zip(start, start + var.dims()[dim] * units::one);
      86      215732 : }
      87             : 
      88             : } // namespace
      89             : 
      90             : /// Return Variable containing mutable spans over given dimension as elements.
      91       47665 : Variable subspan_view(Variable &var, const Dim dim) {
      92       95328 :   return subspan_view(var, dim, make_indices(var, dim));
      93             : }
      94             : /// Return Variable containing const spans over given dimension as elements.
      95      168067 : Variable subspan_view(const Variable &var, const Dim dim) {
      96      336134 :   return subspan_view(var, dim, make_indices(var, dim));
      97             : }
      98             : 
      99       78191 : Variable subspan_view(Variable &var, const Dim dim, const Variable &indices) {
     100       78191 :   return subspan_view_impl(var, dim, indices);
     101             : }
     102      238573 : Variable subspan_view(const Variable &var, const Dim dim,
     103             :                       const Variable &indices) {
     104      238573 :   return subspan_view_impl(var, dim, indices);
     105             : }
     106             : 
     107             : } // namespace scipp::variable

Generated by: LCOV version 1.14