Skip to content

Commit 90ea1aa

Browse files
authored
Merge pull request #1373 from LLNL/feature/yang39/misc-array-fixups
Miscellaneous Array fixups
2 parents 209cad4 + 655bd1e commit 90ea1aa

File tree

10 files changed

+130
-40
lines changed

10 files changed

+130
-40
lines changed

src/axom/core/Array.hpp

+67-13
Original file line numberDiff line numberDiff line change
@@ -625,13 +625,34 @@ class Array : public ArrayBase<T, DIM, Array<T, DIM, SPACE>>
625625
* \param [in] value the value to be added to the back.
626626
*
627627
* \note Reallocation is done if the new size will exceed the capacity.
628-
* \note If used in a device kernel, the number of push_backs must not exceed
629-
* the capacity, since device-side reallocations aren't supported.
630-
* \note Array must be allocated in unified memory if calling on the device.
631-
*
628+
*
629+
* \pre DIM == 1
630+
*/
631+
void push_back(const T& value);
632+
633+
/*!
634+
* \brief Push a value to the back of the array.
635+
*
636+
* \param [in] value the value to move to the back.
637+
*
638+
* \note Reallocation is done if the new size will exceed the capacity.
639+
*
640+
* \pre DIM == 1
641+
*/
642+
void push_back(T&& value);
643+
644+
/*!
645+
* \brief Inserts new element at the end of the Array.
646+
*
647+
* \param [in] args the arguments to forward to constructor of the element.
648+
*
649+
* \note Reallocation is done if the new size will exceed the capacity.
650+
* \note The size increases by 1.
651+
*
632652
* \pre DIM == 1
633653
*/
634-
AXOM_HOST_DEVICE void push_back(const T& value);
654+
template <typename... Args>
655+
void emplace_back(Args&&... args);
635656

636657
/*!
637658
* \brief Push a value to the back of the array.
@@ -642,10 +663,13 @@ class Array : public ArrayBase<T, DIM, Array<T, DIM, SPACE>>
642663
* \note If used in a device kernel, the number of push_backs must not exceed
643664
* the capacity, since device-side reallocations aren't supported.
644665
* \note Array must be allocated in unified memory if calling on the device.
645-
*
666+
*
646667
* \pre DIM == 1
647668
*/
648-
AXOM_HOST_DEVICE void push_back(T&& value);
669+
/// @{
670+
AXOM_HOST_DEVICE void push_back_device(const T& value);
671+
AXOM_HOST_DEVICE void push_back_device(T&& value);
672+
/// @}
649673

650674
/*!
651675
* \brief Inserts new element at the end of the Array.
@@ -657,11 +681,11 @@ class Array : public ArrayBase<T, DIM, Array<T, DIM, SPACE>>
657681
* \note If used in a device kernel, the number of push_backs must not exceed
658682
* the capacity, since device-side reallocations aren't supported.
659683
* \note Array must be allocated in unified memory if calling on the device.
660-
*
684+
*
661685
* \pre DIM == 1
662686
*/
663687
template <typename... Args>
664-
AXOM_HOST_DEVICE void emplace_back(Args&&... args);
688+
AXOM_HOST_DEVICE void emplace_back_device(Args&&... args);
665689

666690
/// @}
667691

@@ -1425,15 +1449,15 @@ inline typename Array<T, DIM, SPACE>::ArrayIterator Array<T, DIM, SPACE>::emplac
14251449

14261450
//------------------------------------------------------------------------------
14271451
template <typename T, int DIM, MemorySpace SPACE>
1428-
AXOM_HOST_DEVICE inline void Array<T, DIM, SPACE>::push_back(const T& value)
1452+
inline void Array<T, DIM, SPACE>::push_back(const T& value)
14291453
{
14301454
static_assert(DIM == 1, "push_back is only supported for 1D arrays");
14311455
emplace_back(value);
14321456
}
14331457

14341458
//------------------------------------------------------------------------------
14351459
template <typename T, int DIM, MemorySpace SPACE>
1436-
AXOM_HOST_DEVICE inline void Array<T, DIM, SPACE>::push_back(T&& value)
1460+
inline void Array<T, DIM, SPACE>::push_back(T&& value)
14371461
{
14381462
static_assert(DIM == 1, "push_back is only supported for 1D arrays");
14391463
emplace_back(std::move(value));
@@ -1442,8 +1466,33 @@ AXOM_HOST_DEVICE inline void Array<T, DIM, SPACE>::push_back(T&& value)
14421466
//------------------------------------------------------------------------------
14431467
AXOM_SUPPRESS_HD_WARN
14441468
template <typename T, int DIM, MemorySpace SPACE>
1469+
AXOM_HOST_DEVICE inline void Array<T, DIM, SPACE>::push_back_device(const T& value)
1470+
{
1471+
static_assert(DIM == 1, "push_back_device is only supported for 1D arrays");
1472+
emplace_back_device(value);
1473+
}
1474+
1475+
//------------------------------------------------------------------------------
1476+
template <typename T, int DIM, MemorySpace SPACE>
1477+
AXOM_HOST_DEVICE inline void Array<T, DIM, SPACE>::push_back_device(T&& value)
1478+
{
1479+
static_assert(DIM == 1, "push_back_device is only supported for 1D arrays");
1480+
emplace_back_device(std::move(value));
1481+
}
1482+
1483+
//------------------------------------------------------------------------------
1484+
template <typename T, int DIM, MemorySpace SPACE>
14451485
template <typename... Args>
1446-
AXOM_HOST_DEVICE inline void Array<T, DIM, SPACE>::emplace_back(Args&&... args)
1486+
inline void Array<T, DIM, SPACE>::emplace_back(Args&&... args)
1487+
{
1488+
static_assert(DIM == 1, "emplace_back is only supported for 1D arrays");
1489+
emplace(size(), std::forward<Args>(args)...);
1490+
}
1491+
1492+
//------------------------------------------------------------------------------
1493+
template <typename T, int DIM, MemorySpace SPACE>
1494+
template <typename... Args>
1495+
AXOM_HOST_DEVICE inline void Array<T, DIM, SPACE>::emplace_back_device(Args&&... args)
14471496
{
14481497
static_assert(DIM == 1, "emplace_back is only supported for 1D arrays");
14491498
#ifdef AXOM_DEVICE_CODE
@@ -1685,7 +1734,12 @@ template <typename T, int DIM, MemorySpace SPACE>
16851734
inline void Array<T, DIM, SPACE>::dynamicRealloc(IndexType new_num_elements)
16861735
{
16871736
assert(m_resize_ratio >= 1.0);
1688-
IndexType new_capacity = new_num_elements * m_resize_ratio + 0.5;
1737+
1738+
// Using resize strategy from LLVM libc++ (vector::__recommend()):
1739+
// new_capacity = max(capacity() * resize_ratio, new_num_elements)
1740+
IndexType new_capacity =
1741+
axom::utilities::max<IndexType>(this->capacity() * m_resize_ratio + 0.5,
1742+
new_num_elements);
16891743
const IndexType block_size = this->blockSize();
16901744
const IndexType remainder = new_capacity % block_size;
16911745
if(remainder != 0)

src/axom/core/MDMapping.hpp

+13-12
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,9 @@ class MDMapping
4949
@param [in] fastestStrideLength Stride in the
5050
fastest-changing direction.
5151
*/
52-
MDMapping(const axom::StackArray<T, DIM>& shape,
53-
axom::ArrayStrideOrder arrayStrideOrder,
54-
int fastestStrideLength = 1)
52+
AXOM_HOST_DEVICE MDMapping(const axom::StackArray<T, DIM>& shape,
53+
axom::ArrayStrideOrder arrayStrideOrder,
54+
int fastestStrideLength = 1)
5555
{
5656
initializeShape(shape, arrayStrideOrder, fastestStrideLength);
5757
}
@@ -66,9 +66,9 @@ class MDMapping
6666
fastest-changing direction.
6767
*/
6868
template <typename DirType>
69-
MDMapping(const axom::StackArray<T, DIM>& shape,
70-
const axom::StackArray<DirType, DIM>& slowestDirs,
71-
int fastestStrideLength = 1)
69+
AXOM_HOST_DEVICE MDMapping(const axom::StackArray<T, DIM>& shape,
70+
const axom::StackArray<DirType, DIM>& slowestDirs,
71+
int fastestStrideLength = 1)
7272
{
7373
initializeShape(shape, slowestDirs, fastestStrideLength);
7474
}
@@ -81,8 +81,8 @@ class MDMapping
8181
@param [in] orderSource ArrayIndex to copy stride order
8282
from.
8383
*/
84-
MDMapping(const axom::StackArray<T, DIM>& shape,
85-
const axom::MDMapping<DIM, T>& orderSource)
84+
AXOM_HOST_DEVICE MDMapping(const axom::StackArray<T, DIM>& shape,
85+
const axom::MDMapping<DIM, T>& orderSource)
8686
{
8787
initializeShape(shape, orderSource);
8888
}
@@ -98,7 +98,8 @@ class MDMapping
9898
clash with the more prevalent usage of constructing from the array's
9999
shape.
100100
*/
101-
MDMapping(const axom::StackArray<T, DIM>& strides) : m_strides(strides)
101+
AXOM_HOST_DEVICE MDMapping(const axom::StackArray<T, DIM>& strides)
102+
: m_strides(strides)
102103
{
103104
initializeStrides(strides);
104105
}
@@ -117,7 +118,7 @@ class MDMapping
117118
shape is to be determined. Initialize the mapping with its own
118119
slowestDirs() to preserve stride order as its shape changes.
119120
*/
120-
MDMapping(ArrayStrideOrder arrayStrideOrder)
121+
AXOM_HOST_DEVICE MDMapping(ArrayStrideOrder arrayStrideOrder)
121122
{
122123
axom::StackArray<T, DIM> shape;
123124
for(int d = 0; d < DIM; ++d)
@@ -238,8 +239,8 @@ class MDMapping
238239
<< "Likely, multi-dim array shape is 1 in some direction.\n"
239240
<< "Impossible to compute index ordering.\n"
240241
<< "Please use a different MDMapping initializer.\n";
241-
#endif
242242
utilities::processAbort();
243+
#endif
243244
}
244245

245246
// 2nd argument doesn't matter because strides are unique.
@@ -275,7 +276,7 @@ class MDMapping
275276
{
276277
if(m_strides[m_slowestDirs[s]] < m_strides[m_slowestDirs[d]])
277278
{
278-
std::swap(m_slowestDirs[s], m_slowestDirs[d]);
279+
axom::utilities::swap(m_slowestDirs[s], m_slowestDirs[d]);
279280
}
280281
}
281282
}

src/axom/core/tests/core_array.hpp

+3-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,9 @@ axom::IndexType calc_new_capacity(axom::Array<T>& v, axom::IndexType increase)
2525
axom::IndexType new_num_elements = v.size() + increase;
2626
if(new_num_elements > v.capacity())
2727
{
28-
return new_num_elements * v.getResizeRatio() + 0.5;
28+
axom::IndexType capacity_expanded = v.capacity() * v.getResizeRatio() + 0.5;
29+
return axom::utilities::max<axom::IndexType>(capacity_expanded,
30+
new_num_elements);
2931
}
3032

3133
return v.capacity();

src/axom/core/tests/core_array_for_all.hpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -1180,15 +1180,15 @@ AXOM_TYPED_TEST(core_array_for_all, device_insert)
11801180
{
11811181
#pragma omp critical
11821182
{
1183-
arr_v[0].emplace_back(3 * idx + 5);
1183+
arr_v[0].emplace_back_device(3 * idx + 5);
11841184
}
11851185
}
11861186
else
11871187
{
1188-
arr_v[0].emplace_back(3 * idx + 5);
1188+
arr_v[0].emplace_back_device(3 * idx + 5);
11891189
}
11901190
#else
1191-
arr_v[0].emplace_back(3 * idx + 5);
1191+
arr_v[0].emplace_back_device(3 * idx + 5);
11921192
#endif
11931193
});
11941194

src/axom/mint/execution/internal/for_all_faces.hpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -993,7 +993,7 @@ inline void for_all_faces_impl(xargs::coords,
993993
coords[3 * i + 2] = z[nodeID];
994994
}
995995

996-
numerics::Matrix<double> coordsMatrix(dimension, 4, coords, NO_COPY);
996+
numerics::Matrix<double> coordsMatrix(dimension, numNodes, coords, NO_COPY);
997997
kernel(faceID, coordsMatrix, nodeIDs);
998998
});
999999
}

src/axom/mint/tests/mint_mesh_connectivity_array.cpp

+9-4
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,9 @@ IndexType calc_ID_capacity(const ConnectivityArray<NO_INDIRECTION>& connec,
4141
if(new_n_IDs > connec.getIDCapacity())
4242
{
4343
IndexType stride = connec.getNumberOfValuesForID();
44-
IndexType newCapacity =
45-
static_cast<IndexType>(new_n_IDs * stride * connec.getResizeRatio() + 0.5);
44+
IndexType newCapacity = axom::utilities::max<IndexType>(
45+
connec.getValueCapacity() * connec.getResizeRatio() + 0.5,
46+
new_n_IDs * stride);
4647
IndexType remainder = newCapacity % stride;
4748
if(remainder != 0)
4849
{
@@ -67,7 +68,9 @@ IndexType calc_ID_capacity(const ConnectivityArray<TYPED_INDIRECTION>& connec,
6768
IndexType new_n_IDs = connec.getNumberOfIDs() + increase;
6869
if(new_n_IDs > connec.getIDCapacity())
6970
{
70-
return static_cast<IndexType>(new_n_IDs * connec.getResizeRatio() + 0.5);
71+
return axom::utilities::max<IndexType>(
72+
connec.getIDCapacity() * connec.getResizeRatio() + 0.5,
73+
new_n_IDs);
7174
}
7275

7376
return connec.getIDCapacity();
@@ -101,7 +104,9 @@ IndexType calc_value_capacity(const ConnectivityArray<TYPE>& connec,
101104
IndexType new_n_values = connec.getNumberOfValues() + increase;
102105
if(new_n_values > connec.getValueCapacity())
103106
{
104-
return static_cast<IndexType>(new_n_values * connec.getResizeRatio() + 0.5);
107+
return axom::utilities::max<IndexType>(
108+
connec.getValueCapacity() * connec.getResizeRatio() + 0.5,
109+
new_n_values);
105110
}
106111

107112
return connec.getValueCapacity();

src/axom/mint/tests/mint_mesh_unstructured_mesh.cpp

+4-2
Original file line numberDiff line numberDiff line change
@@ -2200,7 +2200,8 @@ void resize_cells(UnstructuredMesh<TOPO>* mesh)
22002200
/* Append one more, should trigger a resize. */
22012201
append_cell_single(mesh, 1);
22022202
n_cells++;
2203-
cell_capacity = static_cast<IndexType>(n_cells * resize_ratio + 0.5);
2203+
cell_capacity =
2204+
axom::utilities::max<IndexType>(cell_capacity * resize_ratio + 0.5, n_cells);
22042205
connec_capacity = mesh->getCellNodesCapacity();
22052206
ASSERT_EQ(n_cells, mesh->getNumberOfCells());
22062207
ASSERT_EQ(cell_capacity, mesh->getCellCapacity());
@@ -2217,7 +2218,8 @@ void resize_cells(UnstructuredMesh<TOPO>* mesh)
22172218
mesh->setCellResizeRatio(resize_ratio);
22182219
append_cell_multiple(mesh, 100);
22192220
n_cells += 100;
2220-
cell_capacity = static_cast<IndexType>(resize_ratio * n_cells + 0.5);
2221+
cell_capacity =
2222+
axom::utilities::max<IndexType>(cell_capacity * resize_ratio + 0.5, n_cells);
22212223
ASSERT_EQ(n_cells, mesh->getNumberOfCells());
22222224
ASSERT_EQ(cell_capacity, mesh->getCellCapacity());
22232225

src/axom/primal/geometry/Polygon.hpp

+19-2
Original file line numberDiff line numberDiff line change
@@ -193,8 +193,25 @@ class Polygon
193193
* \sa axom::StaticArray::push_back() for behavior when array type is static
194194
* and the list of vertices is full.
195195
*/
196-
AXOM_HOST_DEVICE
197-
void addVertex(const PointType& pt) { m_vertices.push_back(pt); }
196+
/// @{
197+
template <PolygonArray P_ARRAY_TYPE = ARRAY_TYPE,
198+
std::enable_if_t<P_ARRAY_TYPE == PolygonArray::Static, int> = 0>
199+
AXOM_HOST_DEVICE void addVertex(const PointType& pt)
200+
{
201+
m_vertices.push_back(pt);
202+
}
203+
204+
template <PolygonArray P_ARRAY_TYPE = ARRAY_TYPE,
205+
std::enable_if_t<P_ARRAY_TYPE == PolygonArray::Dynamic, int> = 0>
206+
AXOM_HOST_DEVICE void addVertex(const PointType& pt)
207+
{
208+
#ifdef AXOM_DEVICE_CODE
209+
m_vertices.push_back_device(pt);
210+
#else
211+
m_vertices.push_back(pt);
212+
#endif
213+
}
214+
/// @}
198215

199216
/// Clears the list of vertices (dynamic array specialization).
200217
/// Specializations are necessary to remove __host__ __device__ warning for

src/axom/sidre/core/Array.hpp

+3-1
Original file line numberDiff line numberDiff line change
@@ -571,7 +571,9 @@ inline void Array<T, DIM>::dynamicRealloc(axom::IndexType new_num_elements)
571571
"Resize ratio of " << this->m_resize_ratio
572572
<< " doesn't support dynamic resizing");
573573

574-
IndexType new_capacity = new_num_elements * this->m_resize_ratio + 0.5;
574+
IndexType new_capacity = axom::utilities::max<IndexType>(
575+
this->capacity() * this->getResizeRatio() + 0.5,
576+
new_num_elements);
575577
const IndexType block_size = this->blockSize();
576578
const IndexType remainder = new_capacity % block_size;
577579
if(remainder != 0)

src/axom/sidre/tests/sidre_mcarray.cpp

+8-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,14 @@ axom::IndexType calc_new_capacity(MCArray<T>& v, axom::IndexType increase)
3434
axom::IndexType new_num_tuples = (v.size() / num_components) + increase;
3535
if((new_num_tuples * num_components) > v.capacity())
3636
{
37-
return new_num_tuples * v.getResizeRatio() + 0.5;
37+
axom::IndexType new_capacity = v.capacity() * v.getResizeRatio() + 0.5;
38+
axom::IndexType remainder = new_capacity % num_components;
39+
if(remainder > 0)
40+
{
41+
new_capacity += num_components - remainder;
42+
}
43+
return axom::utilities::max<axom::IndexType>(new_capacity / num_components,
44+
new_num_tuples);
3845
}
3946

4047
return v.capacity() / num_components;

0 commit comments

Comments
 (0)