Skip to content

Commit 9ceca35

Browse files
committed
add a backup path when host_staging_buffer_manager is not initialized
1 parent 4ebe7e6 commit 9ceca35

7 files changed

Lines changed: 230 additions & 83 deletions

cpp/include/cugraph/host_staging_buffer_manager.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@ class host_staging_buffer_manager {
2626
static constexpr size_t max_staging_buffer_size =
2727
size_t{1024} * size_t{1024} * size_t{1024}; // 1 GB
2828

29+
static bool initialized() {
30+
auto& s = state();
31+
return s.initialized;
32+
}
33+
2934
static void init(raft::handle_t const& handle,
3035
std::shared_ptr<rmm::mr::pinned_host_memory_resource> pinned_mr)
3136
{

cpp/include/cugraph/utilities/host_scalar_comm.hpp

Lines changed: 134 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,15 @@
99
#include <cugraph/utilities/thrust_tuple_utils.hpp>
1010

1111
#include <raft/core/handle.hpp>
12+
#include <raft/core/host_span.hpp>
1213

1314
#include <rmm/device_uvector.hpp>
1415

1516
#include <cuda/std/tuple>
1617

1718
#include <numeric>
1819
#include <type_traits>
20+
#include <variant>
1921

2022
namespace cugraph {
2123

@@ -117,9 +119,17 @@ template <typename T>
117119
std::enable_if_t<std::is_arithmetic<T>::value, T> host_scalar_allreduce(
118120
raft::comms::comms_t const& comm, T input, raft::comms::op_t op, cudaStream_t stream)
119121
{
120-
auto h_tmp_buffer = host_staging_buffer_manager::allocate_staging_buffer<T>(1, stream);
122+
std::variant<std::vector<T>, rmm::device_uvector<T>> h_tmp_buffer{};
123+
raft::host_span<T> h_tmp_buffer_view{};
124+
if (host_staging_buffer_manager::initialized()) {
125+
h_tmp_buffer = host_staging_buffer_manager::allocate_staging_buffer<T>(1, stream);
126+
} else {
127+
h_tmp_buffer = std::vector<T>(1);
128+
}
129+
h_tmp_buffer_view = std::visit(
130+
[](auto& buffer) { return raft::host_span<T>(buffer.data(), buffer.size()); }, h_tmp_buffer);
121131
rmm::device_uvector<T> d_tmp_buffer(1, stream);
122-
T* h_staging_buffer = h_tmp_buffer.data();
132+
T* h_staging_buffer = h_tmp_buffer_view.data();
123133
T* d_staging_buffer = d_tmp_buffer.data();
124134
h_staging_buffer[0] = input;
125135
raft::update_device(d_staging_buffer, h_staging_buffer, 1, stream);
@@ -138,10 +148,19 @@ std::enable_if_t<cugraph::is_thrust_tuple_of_arithmetic<T>::value, T> host_scala
138148
{
139149
size_t constexpr tuple_size = cuda::std::tuple_size<T>::value;
140150

141-
auto h_tmp_buffer =
142-
host_staging_buffer_manager::allocate_staging_buffer<int64_t>(tuple_size, stream);
151+
std::variant<std::vector<int64_t>, rmm::device_uvector<int64_t>> h_tmp_buffer{};
152+
raft::host_span<int64_t> h_tmp_buffer_view{};
153+
if (host_staging_buffer_manager::initialized()) {
154+
h_tmp_buffer =
155+
host_staging_buffer_manager::allocate_staging_buffer<int64_t>(tuple_size, stream);
156+
} else {
157+
h_tmp_buffer = std::vector<int64_t>(tuple_size);
158+
}
159+
h_tmp_buffer_view =
160+
std::visit([](auto& buffer) { return raft::host_span<int64_t>(buffer.data(), buffer.size()); },
161+
h_tmp_buffer);
143162
rmm::device_uvector<int64_t> d_tmp_buffer(tuple_size, stream);
144-
int64_t* h_staging_buffer = h_tmp_buffer.data();
163+
int64_t* h_staging_buffer = h_tmp_buffer_view.data();
145164
int64_t* d_staging_buffer = d_tmp_buffer.data();
146165
detail::update_array_of_tuple_scalar_elements_from_tuple_impl<T, size_t{0}, tuple_size>().update(
147166
h_staging_buffer, input);
@@ -163,9 +182,17 @@ template <typename T>
163182
std::enable_if_t<std::is_arithmetic<T>::value, T> host_scalar_reduce(
164183
raft::comms::comms_t const& comm, T input, raft::comms::op_t op, int root, cudaStream_t stream)
165184
{
166-
auto h_tmp_buffer = host_staging_buffer_manager::allocate_staging_buffer<T>(1, stream);
185+
std::variant<std::vector<T>, rmm::device_uvector<T>> h_tmp_buffer{};
186+
raft::host_span<T> h_tmp_buffer_view{};
187+
if (host_staging_buffer_manager::initialized()) {
188+
h_tmp_buffer = host_staging_buffer_manager::allocate_staging_buffer<T>(1, stream);
189+
} else {
190+
h_tmp_buffer = std::vector<T>(1);
191+
}
192+
h_tmp_buffer_view = std::visit(
193+
[](auto& buffer) { return raft::host_span<T>(buffer.data(), buffer.size()); }, h_tmp_buffer);
167194
rmm::device_uvector<T> d_tmp_buffer(1, stream);
168-
T* h_staging_buffer = h_tmp_buffer.data();
195+
T* h_staging_buffer = h_tmp_buffer_view.data();
169196
T* d_staging_buffer = d_tmp_buffer.data();
170197
h_staging_buffer[0] = input;
171198
raft::update_device(d_staging_buffer, h_staging_buffer, 1, stream);
@@ -186,10 +213,19 @@ std::enable_if_t<cugraph::is_thrust_tuple_of_arithmetic<T>::value, T> host_scala
186213
{
187214
size_t constexpr tuple_size = cuda::std::tuple_size<T>::value;
188215

189-
auto h_tmp_buffer =
190-
host_staging_buffer_manager::allocate_staging_buffer<int64_t>(tuple_size, stream);
216+
std::variant<std::vector<int64_t>, rmm::device_uvector<int64_t>> h_tmp_buffer{};
217+
raft::host_span<int64_t> h_tmp_buffer_view{};
218+
if (host_staging_buffer_manager::initialized()) {
219+
h_tmp_buffer =
220+
host_staging_buffer_manager::allocate_staging_buffer<int64_t>(tuple_size, stream);
221+
} else {
222+
h_tmp_buffer = std::vector<int64_t>(tuple_size);
223+
}
224+
h_tmp_buffer_view =
225+
std::visit([](auto& buffer) { return raft::host_span<int64_t>(buffer.data(), buffer.size()); },
226+
h_tmp_buffer);
191227
rmm::device_uvector<int64_t> d_tmp_buffer(tuple_size, stream);
192-
int64_t* h_staging_buffer = h_tmp_buffer.data();
228+
int64_t* h_staging_buffer = h_tmp_buffer_view.data();
193229
int64_t* d_staging_buffer = d_tmp_buffer.data();
194230
detail::update_array_of_tuple_scalar_elements_from_tuple_impl<T, size_t{0}, tuple_size>().update(
195231
h_staging_buffer, input);
@@ -214,9 +250,17 @@ template <typename T>
214250
std::enable_if_t<std::is_arithmetic<T>::value, T> host_scalar_bcast(
215251
raft::comms::comms_t const& comm, T input, int root, cudaStream_t stream)
216252
{
217-
auto h_tmp_buffer = host_staging_buffer_manager::allocate_staging_buffer<T>(1, stream);
253+
std::variant<std::vector<T>, rmm::device_uvector<T>> h_tmp_buffer{};
254+
raft::host_span<T> h_tmp_buffer_view{};
255+
if (host_staging_buffer_manager::initialized()) {
256+
h_tmp_buffer = host_staging_buffer_manager::allocate_staging_buffer<T>(1, stream);
257+
} else {
258+
h_tmp_buffer = std::vector<T>(1);
259+
}
260+
h_tmp_buffer_view = std::visit(
261+
[](auto& buffer) { return raft::host_span<T>(buffer.data(), buffer.size()); }, h_tmp_buffer);
218262
rmm::device_uvector<T> d_tmp_buffer(1, stream);
219-
T* h_staging_buffer = h_tmp_buffer.data();
263+
T* h_staging_buffer = h_tmp_buffer_view.data();
220264
T* d_staging_buffer = d_tmp_buffer.data();
221265
if (comm.get_rank() == root) {
222266
h_staging_buffer[0] = input;
@@ -237,10 +281,19 @@ std::enable_if_t<cugraph::is_thrust_tuple_of_arithmetic<T>::value, T> host_scala
237281
{
238282
size_t constexpr tuple_size = cuda::std::tuple_size<T>::value;
239283

240-
auto h_tmp_buffer =
241-
host_staging_buffer_manager::allocate_staging_buffer<int64_t>(tuple_size, stream);
284+
std::variant<std::vector<int64_t>, rmm::device_uvector<int64_t>> h_tmp_buffer{};
285+
raft::host_span<int64_t> h_tmp_buffer_view{};
286+
if (host_staging_buffer_manager::initialized()) {
287+
h_tmp_buffer =
288+
host_staging_buffer_manager::allocate_staging_buffer<int64_t>(tuple_size, stream);
289+
} else {
290+
h_tmp_buffer = std::vector<int64_t>(tuple_size);
291+
}
292+
h_tmp_buffer_view =
293+
std::visit([](auto& buffer) { return raft::host_span<int64_t>(buffer.data(), buffer.size()); },
294+
h_tmp_buffer);
242295
rmm::device_uvector<int64_t> d_tmp_buffer(tuple_size, stream);
243-
int64_t* h_staging_buffer = h_tmp_buffer.data();
296+
int64_t* h_staging_buffer = h_tmp_buffer_view.data();
244297
int64_t* d_staging_buffer = d_tmp_buffer.data();
245298
if (comm.get_rank() == root) {
246299
detail::update_array_of_tuple_scalar_elements_from_tuple_impl<T, size_t{0}, tuple_size>()
@@ -264,10 +317,17 @@ template <typename T>
264317
std::enable_if_t<std::is_arithmetic<T>::value, std::vector<T>> host_scalar_allgather(
265318
raft::comms::comms_t const& comm, T input, cudaStream_t stream)
266319
{
267-
auto h_tmp_buffer =
268-
host_staging_buffer_manager::allocate_staging_buffer<T>(comm.get_size(), stream);
320+
std::variant<std::vector<T>, rmm::device_uvector<T>> h_tmp_buffer{};
321+
raft::host_span<T> h_tmp_buffer_view{};
322+
if (host_staging_buffer_manager::initialized()) {
323+
h_tmp_buffer = host_staging_buffer_manager::allocate_staging_buffer<T>(comm.get_size(), stream);
324+
} else {
325+
h_tmp_buffer = std::vector<T>(comm.get_size());
326+
}
327+
h_tmp_buffer_view = std::visit(
328+
[](auto& buffer) { return raft::host_span<T>(buffer.data(), buffer.size()); }, h_tmp_buffer);
269329
rmm::device_uvector<T> d_tmp_buffer(comm.get_size(), stream);
270-
T* h_staging_buffer = h_tmp_buffer.data();
330+
T* h_staging_buffer = h_tmp_buffer_view.data();
271331
T* d_staging_buffer = d_tmp_buffer.data();
272332
h_staging_buffer[comm.get_rank()] = input;
273333
raft::update_device(
@@ -287,10 +347,19 @@ host_scalar_allgather(raft::comms::comms_t const& comm, T input, cudaStream_t st
287347
{
288348
size_t constexpr tuple_size = cuda::std::tuple_size<T>::value;
289349

290-
auto h_tmp_buffer = host_staging_buffer_manager::allocate_staging_buffer<int64_t>(
291-
comm.get_size() * tuple_size, stream);
350+
std::variant<std::vector<int64_t>, rmm::device_uvector<int64_t>> h_tmp_buffer{};
351+
raft::host_span<int64_t> h_tmp_buffer_view{};
352+
if (host_staging_buffer_manager::initialized()) {
353+
h_tmp_buffer = host_staging_buffer_manager::allocate_staging_buffer<int64_t>(
354+
comm.get_size() * tuple_size, stream);
355+
} else {
356+
h_tmp_buffer = std::vector<int64_t>(comm.get_size() * tuple_size);
357+
}
358+
h_tmp_buffer_view =
359+
std::visit([](auto& buffer) { return raft::host_span<int64_t>(buffer.data(), buffer.size()); },
360+
h_tmp_buffer);
292361
rmm::device_uvector<int64_t> d_tmp_buffer(comm.get_size() * tuple_size, stream);
293-
int64_t* h_staging_buffer = h_tmp_buffer.data();
362+
int64_t* h_staging_buffer = h_tmp_buffer_view.data();
294363
int64_t* d_staging_buffer = d_tmp_buffer.data();
295364
detail::update_array_of_tuple_scalar_elements_from_tuple_impl<T, size_t{0}, tuple_size>().update(
296365
h_staging_buffer + comm.get_rank() * tuple_size, input);
@@ -324,10 +393,17 @@ std::enable_if_t<std::is_arithmetic<T>::value, T> host_scalar_scatter(
324393
((comm.get_rank() != root) && (inputs.size() == 0)),
325394
"inputs.size() should match with comm.get_size() in root and should be 0 otherwise.");
326395

327-
auto h_tmp_buffer =
328-
host_staging_buffer_manager::allocate_staging_buffer<T>(comm.get_size(), stream);
396+
std::variant<std::vector<T>, rmm::device_uvector<T>> h_tmp_buffer{};
397+
raft::host_span<T> h_tmp_buffer_view{};
398+
if (host_staging_buffer_manager::initialized()) {
399+
h_tmp_buffer = host_staging_buffer_manager::allocate_staging_buffer<T>(comm.get_size(), stream);
400+
} else {
401+
h_tmp_buffer = std::vector<T>(comm.get_size());
402+
}
403+
h_tmp_buffer_view = std::visit(
404+
[](auto& buffer) { return raft::host_span<T>(buffer.data(), buffer.size()); }, h_tmp_buffer);
329405
rmm::device_uvector<T> d_tmp_buffer(comm.get_size(), stream);
330-
T* h_staging_buffer = h_tmp_buffer.data();
406+
T* h_staging_buffer = h_tmp_buffer_view.data();
331407
T* d_staging_buffer = d_tmp_buffer.data();
332408
if (comm.get_rank() == root) {
333409
std::copy(inputs.begin(), inputs.end(), h_staging_buffer);
@@ -358,10 +434,19 @@ std::enable_if_t<cugraph::is_thrust_tuple_of_arithmetic<T>::value, T> host_scala
358434
((comm.get_rank() != root) && (inputs.size() == 0)),
359435
"inputs.size() should match with comm.get_size() in root and should be 0 otherwise.");
360436

361-
auto h_tmp_buffer = host_staging_buffer_manager::allocate_staging_buffer<int64_t>(
362-
comm.get_size() * tuple_size, stream);
437+
std::variant<std::vector<int64_t>, rmm::device_uvector<int64_t>> h_tmp_buffer{};
438+
raft::host_span<int64_t> h_tmp_buffer_view{};
439+
if (host_staging_buffer_manager::initialized()) {
440+
h_tmp_buffer = host_staging_buffer_manager::allocate_staging_buffer<int64_t>(
441+
comm.get_size() * tuple_size, stream);
442+
} else {
443+
h_tmp_buffer = std::vector<int64_t>(comm.get_size() * tuple_size);
444+
}
445+
h_tmp_buffer_view =
446+
std::visit([](auto& buffer) { return raft::host_span<int64_t>(buffer.data(), buffer.size()); },
447+
h_tmp_buffer);
363448
rmm::device_uvector<int64_t> d_tmp_buffer(comm.get_size() * tuple_size, stream);
364-
int64_t* h_staging_buffer = h_tmp_buffer.data();
449+
int64_t* h_staging_buffer = h_tmp_buffer_view.data();
365450
int64_t* d_staging_buffer = d_tmp_buffer.data();
366451
if (comm.get_rank() == root) {
367452
for (int i = 0; i < comm.get_size(); ++i) {
@@ -392,10 +477,17 @@ template <typename T>
392477
std::enable_if_t<std::is_arithmetic<T>::value, std::vector<T>> host_scalar_gather(
393478
raft::comms::comms_t const& comm, T input, int root, cudaStream_t stream)
394479
{
395-
auto h_tmp_buffer =
396-
host_staging_buffer_manager::allocate_staging_buffer<T>(comm.get_size(), stream);
480+
std::variant<std::vector<T>, rmm::device_uvector<T>> h_tmp_buffer{};
481+
raft::host_span<T> h_tmp_buffer_view{};
482+
if (host_staging_buffer_manager::initialized()) {
483+
h_tmp_buffer = host_staging_buffer_manager::allocate_staging_buffer<T>(comm.get_size(), stream);
484+
} else {
485+
h_tmp_buffer = std::vector<T>(comm.get_size());
486+
}
487+
h_tmp_buffer_view = std::visit(
488+
[](auto& buffer) { return raft::host_span<T>(buffer.data(), buffer.size()); }, h_tmp_buffer);
397489
rmm::device_uvector<T> d_tmp_buffer(comm.get_size(), stream);
398-
T* h_staging_buffer = h_tmp_buffer.data();
490+
T* h_staging_buffer = h_tmp_buffer_view.data();
399491
T* d_staging_buffer = d_tmp_buffer.data();
400492
h_staging_buffer[comm.get_rank()] = input;
401493
raft::update_device(
@@ -421,10 +513,19 @@ host_scalar_gather(raft::comms::comms_t const& comm, T input, int root, cudaStre
421513
{
422514
size_t constexpr tuple_size = cuda::std::tuple_size<T>::value;
423515

424-
auto h_tmp_buffer = host_staging_buffer_manager::allocate_staging_buffer<int64_t>(
425-
comm.get_size() * tuple_size, stream);
516+
std::variant<std::vector<int64_t>, rmm::device_uvector<int64_t>> h_tmp_buffer{};
517+
raft::host_span<int64_t> h_tmp_buffer_view{};
518+
if (host_staging_buffer_manager::initialized()) {
519+
h_tmp_buffer = host_staging_buffer_manager::allocate_staging_buffer<int64_t>(
520+
comm.get_size() * tuple_size, stream);
521+
} else {
522+
h_tmp_buffer = std::vector<int64_t>(comm.get_size() * tuple_size);
523+
}
524+
h_tmp_buffer_view =
525+
std::visit([](auto& buffer) { return raft::host_span<int64_t>(buffer.data(), buffer.size()); },
526+
h_tmp_buffer);
426527
rmm::device_uvector<int64_t> d_tmp_buffer(comm.get_size() * tuple_size, stream);
427-
int64_t* h_staging_buffer = h_tmp_buffer.data();
528+
int64_t* h_staging_buffer = h_tmp_buffer_view.data();
428529
int64_t* d_staging_buffer = d_tmp_buffer.data();
429530
detail::update_array_of_tuple_scalar_elements_from_tuple_impl<T, size_t{0}, tuple_size>().update(
430531
h_staging_buffer + comm.get_rank() * tuple_size, input);

cpp/src/prims/detail/extract_transform_if_v_frontier_e.cuh

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -810,7 +810,8 @@ extract_transform_if_v_frontier_e(raft::handle_t const& handle,
810810
// we should consider reducing the life-time of this variable
811811
// once rmm::rm::pool_memory_resource<rmm::mr::pinned_memory_resource> is updated to honor stream
812812
// semantics (github.com/rapidsai/rmm/issues/2053)
813-
rmm::device_uvector<int64_t> h_staging_buffer(0, handle.get_stream());
813+
std::variant<std::vector<int64_t>, rmm::device_uvector<int64_t>> h_staging_buffer{};
814+
raft::host_span<int64_t> h_staging_buffer_view{};
814815
{
815816
size_t staging_buffer_size{}; // should be large enough to cover all update_host &
816817
// update_device calls in this primitive
@@ -821,8 +822,15 @@ extract_transform_if_v_frontier_e(raft::handle_t const& handle,
821822
} else {
822823
staging_buffer_size = size_t{16};
823824
}
824-
h_staging_buffer = host_staging_buffer_manager::allocate_staging_buffer<int64_t>(
825-
staging_buffer_size, handle.get_stream());
825+
if (host_staging_buffer_manager::initialized()) {
826+
h_staging_buffer = host_staging_buffer_manager::allocate_staging_buffer<int64_t>(
827+
staging_buffer_size, handle.get_stream());
828+
} else {
829+
h_staging_buffer = std::vector<int64_t>(staging_buffer_size);
830+
}
831+
h_staging_buffer_view = std::visit(
832+
[](auto& buffer) { return raft::host_span<int64_t>(buffer.data(), buffer.size()); },
833+
h_staging_buffer);
826834
}
827835

828836
// 1. pre-process frontier data
@@ -947,8 +955,8 @@ extract_transform_if_v_frontier_e(raft::handle_t const& handle,
947955
vertex_t range_first = graph_view.local_vertex_partition_range_first();
948956
auto range_last = range_first;
949957
if (key_list_size > 0) {
950-
auto h_staging_buffer_ptr = reinterpret_cast<vertex_t*>(h_staging_buffer.data());
951-
assert(h_staging_buffer.size() >= size_t{2});
958+
auto h_staging_buffer_ptr = reinterpret_cast<vertex_t*>(h_staging_buffer_view.data());
959+
assert(h_staging_buffer_view.size() >= size_t{2});
952960
if constexpr (std::is_pointer_v<std::decay<decltype(frontier_key_first)>>) {
953961
raft::update_host(
954962
h_staging_buffer_ptr, frontier_key_first, size_t{1}, handle.get_stream());
@@ -1473,8 +1481,8 @@ extract_transform_if_v_frontier_e(raft::handle_t const& handle,
14731481
}
14741482
}
14751483
if (loop_stream_pool_indices) { RAFT_CUDA_TRY(cudaDeviceSynchronize()); }
1476-
auto h_staging_buffer_ptr = reinterpret_cast<size_t*>(h_staging_buffer.data());
1477-
assert(h_staging_buffer.size() >= loop_count);
1484+
auto h_staging_buffer_ptr = reinterpret_cast<size_t*>(h_staging_buffer_view.data());
1485+
assert(h_staging_buffer_view.size() >= loop_count);
14781486
raft::update_host(h_staging_buffer_ptr, counters.data(), loop_count, handle.get_stream());
14791487
handle.sync_stream();
14801488
for (size_t j = 0; j < loop_count; ++j) {
@@ -1590,8 +1598,8 @@ extract_transform_if_v_frontier_e(raft::handle_t const& handle,
15901598

15911599
if (loop_stream_pool_indices) { RAFT_CUDA_TRY(cudaDeviceSynchronize()); }
15921600
if (std::count(copy_counters.begin(), copy_counters.end(), true) > 0) {
1593-
auto h_staging_buffer_ptr = reinterpret_cast<size_t*>(h_staging_buffer.data());
1594-
assert(h_staging_buffer.size() >= loop_count);
1601+
auto h_staging_buffer_ptr = reinterpret_cast<size_t*>(h_staging_buffer_view.data());
1602+
assert(h_staging_buffer_view.size() >= loop_count);
15951603
raft::update_host(h_staging_buffer_ptr, counters.data(), loop_count, handle.get_stream());
15961604
handle.sync_stream();
15971605
for (size_t j = 0; j < loop_count; ++j) {
@@ -1730,8 +1738,8 @@ extract_transform_if_v_frontier_e(raft::handle_t const& handle,
17301738

17311739
std::vector<size_t> h_counts(loop_count);
17321740
{
1733-
auto h_staging_buffer_ptr = reinterpret_cast<size_t*>(h_staging_buffer.data());
1734-
assert(h_staging_buffer.size() >= loop_count);
1741+
auto h_staging_buffer_ptr = reinterpret_cast<size_t*>(h_staging_buffer_view.data());
1742+
assert(h_staging_buffer_view.size() >= loop_count);
17351743
raft::update_host(h_staging_buffer_ptr, counters.data(), loop_count, handle.get_stream());
17361744
handle.sync_stream();
17371745
std::copy(h_staging_buffer_ptr, h_staging_buffer_ptr + loop_count, h_counts.data());

0 commit comments

Comments
 (0)