Skip to content

Commit b785fb7

Browse files
authored
Merge pull request #348 from Fuad-HH/debug-stdarray-gpu
Fix std::array Bug for GPU kernels - For Conservative Transfer
2 parents be29bb8 + 784c9da commit b785fb7

5 files changed

Lines changed: 79 additions & 24 deletions

File tree

src/pcms/localization/point_search.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,8 @@ LO GetOwningElementId(Omega_h::Mesh& mesh, int mesh_dim, int entity_dim,
6565
KOKKOS_INLINE_FUNCTION
6666
AABBox<2> triangle_bbox(const Omega_h::Matrix<2, 3>& coords)
6767
{
68-
std::array<Real, 2> max{coords(0, 0), coords(1, 0)};
69-
std::array<Real, 2> min{coords(0, 0), coords(1, 0)};
68+
Kokkos::Array<Real, 2> max{coords(0, 0), coords(1, 0)};
69+
Kokkos::Array<Real, 2> min{coords(0, 0), coords(1, 0)};
7070
for (int i = 1; i < 3; ++i) {
7171
max[0] = std::fmax(max[0], coords(0, i));
7272
max[1] = std::fmax(max[1], coords(1, i));
@@ -185,7 +185,7 @@ template <int dim>
185185
// each dimension has a pair of opposing "walls"
186186
// 2D: { [left, right], [top, bottom] } -> { left, right, top, bottom }
187187
// 3D: { [left, right], [top, bottom], [front, back] } -> { left, ..., back }
188-
std::array<Real, dim * 2ul> bbox_walls{};
188+
Kokkos::Array<Real, dim * 2ul> bbox_walls{};
189189
for (int i = 0; i < dim; i++) {
190190
bbox_walls[i * 2] = bbox.center[i] - bbox.half_width[i];
191191
bbox_walls[i * 2 + 1] = bbox.center[i] + bbox.half_width[i];
@@ -751,8 +751,8 @@ GridPointSearch3D::GridPointSearch3D(Omega_h::Mesh& mesh, LO Nx, LO Ny, LO Nz,
751751
auto mesh_bbox = Omega_h::get_bounding_box<3>(&mesh);
752752
auto grid_h = Kokkos::create_mirror_view(grid_);
753753

754-
std::array<Real, DIM> edge_lengths{};
755-
std::array<Real, DIM> bot_left{};
754+
Kokkos::Array<Real, DIM> edge_lengths{};
755+
Kokkos::Array<Real, DIM> bot_left{};
756756

757757
for (int i = 0; i < DIM; ++i) {
758758
edge_lengths[i] = mesh_bbox.max[i] - mesh_bbox.min[i];

src/pcms/pythonapi/bind_uniform_grid_field_layout.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include <pybind11/pybind11.h>
22
#include <pybind11/stl.h>
33
#include <pybind11/numpy.h>
4+
#include "numpy_array_transform.h"
45
#include "pcms/field/layout/uniform_grid.h"
56
#include "pcms/utility/uniform_grid.h"
67

src/pcms/pythonapi/numpy_array_transform.h

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,48 @@
77

88
namespace py = pybind11;
99

10+
// Mirror pybind11's built-in std::array type caster for Kokkos::Array so that
11+
// def_readwrite / def_property members work with Python sequences.
12+
namespace pybind11::detail
13+
{
14+
template <typename Type, size_t Size>
15+
struct type_caster<Kokkos::Array<Type, Size>>
16+
{
17+
using ArrayType = Kokkos::Array<Type, Size>;
18+
using value_conv = make_caster<Type>;
19+
20+
bool load(handle src, bool convert)
21+
{
22+
if (!isinstance<sequence>(src))
23+
return false;
24+
auto seq = reinterpret_borrow<sequence>(src);
25+
if (seq.size() != Size)
26+
return false;
27+
size_t i = 0;
28+
for (auto it : seq) {
29+
value_conv conv;
30+
if (!conv.load(it, convert))
31+
return false;
32+
value[i++] = cast_op<Type>(conv);
33+
}
34+
return true;
35+
}
36+
37+
template <typename T>
38+
static handle cast(T&& src, return_value_policy policy, handle parent)
39+
{
40+
list l(Size);
41+
size_t i = 0;
42+
for (auto& v : src)
43+
l[i++] = make_caster<Type>::cast(v, policy, parent);
44+
return l.release();
45+
}
46+
47+
PYBIND11_TYPE_CASTER(ArrayType, const_name("List[") +
48+
make_caster<Type>::name + const_name("]"));
49+
};
50+
} // namespace pybind11::detail
51+
1052
namespace pcms
1153
{
1254

src/pcms/utility/arrays.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,12 @@ struct arr_trait<std::array<T, N>>
7070
using type = T;
7171
};
7272

73+
template <typename T, size_t N>
74+
struct arr_trait<Kokkos::Array<T, N>>
75+
{
76+
using type = T;
77+
};
78+
7379
template <typename T>
7480
using element_type_t = typename arr_trait<T, HasValueType<T>::value>::type;
7581

src/pcms/utility/uniform_grid.h

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,26 @@
44
#include "Omega_h_vector.hpp"
55
#include "Omega_h_bbox.hpp"
66
#include "Omega_h_mesh.hpp"
7-
#include <numeric>
7+
#include <Kokkos_Array.hpp>
8+
#include <array>
89
namespace pcms
910
{
1011

1112
template <unsigned dim>
1213
struct UniformGrid
1314
{
1415
// Make private?
15-
std::array<Real, dim> edge_length;
16-
std::array<Real, dim> bot_left;
17-
std::array<LO, dim> divisions;
16+
Kokkos::Array<Real, dim> edge_length;
17+
Kokkos::Array<Real, dim> bot_left;
18+
Kokkos::Array<LO, dim> divisions;
1819

1920
public:
2021
[[nodiscard]] LO GetNumCells() const
2122
{
22-
return std::accumulate(divisions.begin(), divisions.end(), 1,
23-
std::multiplies<LO>{});
23+
LO total = 1;
24+
for (std::size_t i = 0; i < dim; ++i)
25+
total *= divisions[i];
26+
return total;
2427
}
2528
/// return the grid cell ID that the input point is inside or closest to if
2629
/// the point lies outside
@@ -30,13 +33,13 @@ struct UniformGrid
3033
[[nodiscard]] KOKKOS_INLINE_FUNCTION LO
3134
ClosestCellID(const Omega_h::Vector<dim>& point) const
3235
{
33-
std::array<Real, dim> distance_within_grid;
36+
Kokkos::Array<Real, dim> distance_within_grid;
3437

3538
for (size_t i = 0; i < dim; ++i) {
3639
distance_within_grid[i] = point[i] - bot_left[i];
3740
}
3841

39-
std::array<LO, dim> indexes;
42+
Kokkos::Array<LO, dim> indexes;
4043

4144
for (auto& index : indexes) {
4245
index = -1;
@@ -86,14 +89,14 @@ struct UniformGrid
8689
return true;
8790
}
8891

89-
[[nodiscard]] KOKKOS_INLINE_FUNCTION std::array<LO, dim> GetDimensionedIndex(
90-
LO idx) const
92+
[[nodiscard]] KOKKOS_INLINE_FUNCTION Kokkos::Array<LO, dim>
93+
GetDimensionedIndex(LO idx) const
9194
{
9295
LO stride = 1;
93-
for (std::size_t i = 0; i < divisions.size() - 1; ++i) {
96+
for (std::size_t i = 0; i < dim - 1; ++i) {
9497
stride *= divisions[i];
9598
}
96-
std::array<LO, dim> result;
99+
Kokkos::Array<LO, dim> result;
97100

98101
for (size_t i = 0; i < dim; ++i) {
99102
result[i] = idx / stride;
@@ -105,7 +108,7 @@ struct UniformGrid
105108
}
106109

107110
[[nodiscard]] KOKKOS_INLINE_FUNCTION LO
108-
GetCellIndex(std::array<LO, dim> dimensionedIndex) const
111+
GetCellIndex(Kokkos::Array<LO, dim> dimensionedIndex) const
109112
{
110113
// note that the indexes refer to row/columns which have the opposite order
111114
// of the coordinates i.e. x,y
@@ -124,9 +127,9 @@ struct UniformGrid
124127

125128
private:
126129
template <typename T, std::size_t N>
127-
KOKKOS_INLINE_FUNCTION static void reverse(std::array<T, N>& arr)
130+
KOKKOS_INLINE_FUNCTION static void reverse(Kokkos::Array<T, N>& arr)
128131
{
129-
for (size_t i = 0, j = arr.size() - 1; i < j; ++i, --j) {
132+
for (size_t i = 0, j = N - 1; i < j; ++i, --j) {
130133
auto temp = arr[i];
131134
arr[i] = arr[j];
132135
arr[j] = temp;
@@ -158,16 +161,18 @@ UniformGrid<dim> CreateUniformGridFromMesh(Omega_h::Mesh& mesh,
158161
auto bbox = Omega_h::get_bounding_box<dim>(&mesh);
159162

160163
// Calculate edge lengths and bottom-left corner
161-
std::array<Real, dim> edge_length;
162-
std::array<Real, dim> bot_left;
164+
Kokkos::Array<Real, dim> edge_length;
165+
Kokkos::Array<Real, dim> bot_left;
166+
Kokkos::Array<LO, dim> divs;
163167

164168
for (unsigned i = 0; i < dim; ++i) {
165169
bot_left[i] = bbox.min[i];
166170
edge_length[i] = bbox.max[i] - bbox.min[i];
171+
divs[i] = divisions[i];
167172
}
168173

169174
return UniformGrid<dim>{
170-
.edge_length = edge_length, .bot_left = bot_left, .divisions = divisions};
175+
.edge_length = edge_length, .bot_left = bot_left, .divisions = divs};
171176
}
172177

173178
/**
@@ -187,7 +192,8 @@ UniformGrid<dim> CreateUniformGridFromMesh(Omega_h::Mesh& mesh,
187192
LO cells_per_dim)
188193
{
189194
std::array<LO, dim> divisions;
190-
divisions.fill(cells_per_dim);
195+
for (unsigned i = 0; i < dim; ++i)
196+
divisions[i] = cells_per_dim;
191197
return CreateUniformGridFromMesh<dim>(mesh, divisions);
192198
}
193199

0 commit comments

Comments
 (0)