File: array.h

package info (click to toggle)
fenics-dolfinx 1%3A0.10.0.post4-1exp1
  • links: PTS, VCS
  • area: main
  • in suites: experimental
  • size: 6,028 kB
  • sloc: cpp: 36,535; python: 25,391; makefile: 226; sh: 171; xml: 55
file content (92 lines) | stat: -rw-r--r-- 2,916 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
// Copyright (C) 2021-2025 Garth N. Wells
//
// This file is part of DOLFINx (https://www.fenicsproject.org)
//
// SPDX-License-Identifier:    LGPL-3.0-or-later

#pragma once

#include <concepts>
#include <initializer_list>
#include <nanobind/nanobind.h>
#include <nanobind/ndarray.h>
#include <utility>

namespace nb = nanobind;

namespace dolfinx_wrappers
{
/// @brief Create a multi-dimensional `nb::ndarray` that shares data
/// with a `std::vector`.
///
/// The `std::vector` owns the data, and the `nb::ndarray` object keeps
/// the `std::vector` alive. Layout is row-major.
///
/// @tparam V `std::vector` type.
/// @param x `std::vector` to move into the `nb::ndarray`.
/// @param ndim Number of array dimensions (rank).
/// @param shape Shape of the array.
/// @return An n-dimensional array that shares data with `x`.
template <typename V>
  requires std::movable<V>
auto as_nbarray(V&& x, std::size_t ndim, const std::size_t* shape)
{
  using _V = std::decay_t<V>;
  _V* ptr = new _V(std::forward<V>(x));
  return nb::ndarray<typename _V::value_type, nb::numpy>(
      ptr->data(), ndim, shape,
      nb::capsule(ptr, [](void* p) noexcept { delete (_V*)p; }));
}

/// @brief Create a multi-dimensional `nb::ndarray` that shares data
/// with a `std::vector`.
///
/// The `std::vector` owns the data, and the `nb::ndarray` object keeps
/// the `std::vector` alive. Layout is row-major.
///
/// @tparam V `std::vector` type.
/// @param x `std::vector` to move into the `nb::ndarray`.
/// @param shape Shape of the array.
/// @return An n-dimensional array that shares data with `x`.
template <typename V>
  requires std::movable<V>
auto as_nbarray(V&& x, std::initializer_list<std::size_t> shape)
{
  return as_nbarray(std::forward<V>(x), shape.size(), shape.begin());
}

/// @brief Create a multi-dimensional `nb::ndarray` that shares data
/// with a `std::vector`.
///
/// The `std::vector` owns the data, and the `nb::ndarray` object keeps
/// the `std::vector` alive. Layout is row-major.
///
/// @tparam V `std::vector` type.
/// @tparam W Shape container type.
/// @param x `std::vector` to move into the `nb::ndarray`.
/// @param shape Container that hold the shape of the array.
/// @return An n-dimensional array that shares data with `x`.
template <typename V, typename W>
  requires std::movable<V>
auto as_nbarray(V&& x, W&& shape)
{
  return as_nbarray(std::forward<V>(x), shape.size(), shape.data());
}

/// @brief Create a 1D `nb::ndarray` that shares data with a
/// `std::vector`.
///
/// The std::vector owns the data, and the nb::ndarray object keeps the
/// std::vector alive.
///
/// @tparam V `std::vector` type.
/// @param x `std::vector` to move into the `nb::ndarray`.
/// @return An 1D array that shares data with `x`.
template <typename V>
  requires std::movable<V>
auto as_nbarray(V&& x)
{
  return as_nbarray(std::forward<V>(x), {x.size()});
}

} // namespace dolfinx_wrappers