@@ -184,7 +184,7 @@ void reader_impl::decode_page_data(read_mode mode, size_t skip_rows, size_t num_
184184 if (has_strings) {
185185 // Host vector to initialize the initial string offsets
186186 auto host_offsets_vector =
187- cudf::detail::make_host_vector <size_t >(_input_columns.size (), _stream);
187+ cudf::detail::make_pinned_vector_async <size_t >(_input_columns.size (), _stream);
188188 std::fill (
189189 host_offsets_vector.begin (), host_offsets_vector.end (), std::numeric_limits<size_t >::max ());
190190 // Initialize the initial string offsets vector from the host vector
@@ -397,7 +397,12 @@ void reader_impl::decode_page_data(read_mode mode, size_t skip_rows, size_t num_
397397 update_output_nullmasks_for_pruned_pages (_subpass_page_mask, skip_rows, num_rows);
398398
399399 // Copy over initial string offsets from device
400- auto h_initial_str_offsets = cudf::detail::make_host_vector_async (initial_str_offsets, _stream);
400+ auto h_initial_str_offsets =
401+ cudf::detail::make_pinned_vector_async<size_t >(initial_str_offsets.size (), _stream);
402+ cudf::detail::cuda_memcpy_async (
403+ cudf::host_span<size_t >(h_initial_str_offsets.data (), initial_str_offsets.size ()),
404+ cudf::device_span<size_t const >(initial_str_offsets.data (), initial_str_offsets.size ()),
405+ _stream);
401406
402407 if (auto const error = error_code.value_sync (_stream); error != 0 ) {
403408 CUDF_FAIL (" Parquet data decode failed with code(s) " + kernel_error::to_string (error));
@@ -427,14 +432,14 @@ void reader_impl::decode_page_data(read_mode mode, size_t skip_rows, size_t num_
427432
428433 // the final offset for a list at level N is the size of it's child
429434 size_type const offset = child.type .id () == type_id::LIST ? child.size - 1 : child.size ;
430- out_buffers.emplace_back (static_cast <size_type*>(out_buf.data ()) + (out_buf.size - 1 ));
431- final_offsets.emplace_back (offset);
435+ out_buffers.push_back (static_cast <size_type*>(out_buf.data ()) + (out_buf.size - 1 ));
436+ final_offsets.push_back (offset);
432437 out_buf.user_data |= PARQUET_COLUMN_BUFFER_FLAG_LIST_TERMINATED ;
433438 } else if (out_buf.type .id () == type_id::STRING ) {
434439 // only if it is not a large strings column
435440 if (std::cmp_less_equal (col_string_sizes[idx], strings::detail::get_offset64_threshold ())) {
436- out_buffers.emplace_back (static_cast <size_type*>(out_buf.data ()) + out_buf.size );
437- final_offsets.emplace_back (static_cast <size_type>(col_string_sizes[idx]));
441+ out_buffers.push_back (static_cast <size_type*>(out_buf.data ()) + out_buf.size );
442+ final_offsets.push_back (static_cast <size_type>(col_string_sizes[idx]));
438443 }
439444 // Nested large strings column
440445 else if (input_col.nesting_depth () > 0 ) {
@@ -446,7 +451,13 @@ void reader_impl::decode_page_data(read_mode mode, size_t skip_rows, size_t num_
446451 }
447452 }
448453 // Write the final offsets for list and string columns in a batched manner
449- write_final_offsets (final_offsets, out_buffers, _stream);
454+ auto pinned_final_offsets =
455+ cudf::detail::make_pinned_vector_async<cudf::size_type>(final_offsets.size (), _stream);
456+ auto pinned_out_buffers =
457+ cudf::detail::make_pinned_vector_async<cudf::size_type*>(out_buffers.size (), _stream);
458+ std::move (final_offsets.begin (), final_offsets.end (), pinned_final_offsets.begin ());
459+ std::move (out_buffers.begin (), out_buffers.end (), pinned_out_buffers.begin ());
460+ write_final_offsets (pinned_final_offsets, pinned_out_buffers, _stream);
450461
451462 // update null counts in the final column buffers
452463 for (size_t idx = 0 ; idx < subpass.pages .size (); idx++) {
@@ -928,9 +939,9 @@ void reader_impl::update_output_nullmasks_for_pruned_pages(cudf::host_span<bool
928939 auto page_and_mask_begin =
929940 thrust::make_zip_iterator (cuda::std::make_tuple (pages.host_begin (), page_mask.begin ()));
930941
931- auto null_masks = std::vector<bitmask_type*>{};
932- auto begin_bits = std::vector<cudf::size_type>{};
933- auto end_bits = std::vector<cudf::size_type>{};
942+ auto host_null_masks = std::vector<bitmask_type*>{};
943+ auto host_begin_bits = std::vector<cudf::size_type>{};
944+ auto host_end_bits = std::vector<cudf::size_type>{};
934945
935946 std::for_each (
936947 page_and_mask_begin, page_and_mask_begin + pages.size (), [&](auto const & page_and_mask_pair) {
@@ -983,9 +994,9 @@ void reader_impl::update_output_nullmasks_for_pruned_pages(cudf::host_span<bool
983994 cols = &out_buf.children ;
984995 if (out_buf.user_data & PARQUET_COLUMN_BUFFER_FLAG_HAS_LIST_PARENT ) { continue ; }
985996 // Add the nullmask and bit bounds to corresponding lists
986- null_masks .emplace_back (out_buf.null_mask ());
987- begin_bits .emplace_back (start_row);
988- end_bits .emplace_back (end_row);
997+ host_null_masks .emplace_back (out_buf.null_mask ());
998+ host_begin_bits .emplace_back (start_row);
999+ host_end_bits .emplace_back (end_row);
9891000
9901001 // Increment the null count by the number of rows in this page
9911002 out_buf.null_count () += page.num_rows ;
@@ -995,9 +1006,20 @@ void reader_impl::update_output_nullmasks_for_pruned_pages(cudf::host_span<bool
9951006 // Min number of nullmasks to use bulk update optimally
9961007 constexpr auto min_nullmasks_for_bulk_update = 32 ;
9971008
1009+ // Use a bounce buffer to avoid pageable copies
1010+ auto null_masks =
1011+ cudf::detail::make_pinned_vector_async<bitmask_type*>(host_null_masks.size (), _stream);
1012+ auto begin_bits =
1013+ cudf::detail::make_pinned_vector_async<cudf::size_type>(host_begin_bits.size (), _stream);
1014+ auto end_bits =
1015+ cudf::detail::make_pinned_vector_async<cudf::size_type>(host_end_bits.size (), _stream);
1016+ std::move (host_null_masks.begin (), host_null_masks.end (), null_masks.begin ());
1017+ std::move (host_begin_bits.begin (), host_begin_bits.end (), begin_bits.begin ());
1018+ std::move (host_end_bits.begin (), host_end_bits.end (), end_bits.begin ());
1019+
9981020 // Bulk update the nullmasks if the number of pages is above the threshold
9991021 if (null_masks.size () >= min_nullmasks_for_bulk_update) {
1000- auto valids = cudf::detail::make_host_vector <bool >(null_masks.size (), _stream);
1022+ auto valids = cudf::detail::make_pinned_vector_async <bool >(null_masks.size (), _stream);
10011023 std::fill (valids.begin (), valids.end (), false );
10021024 cudf::set_null_masks_safe (null_masks, begin_bits, end_bits, valids, _stream);
10031025 }
0 commit comments