@@ -646,25 +646,166 @@ copy_async(
646646}
647647#endif
648648
649+ struct ActiveDestination {};
650+ struct ActiveSource {};
651+
652+ /* *
653+ * Specialization of \c dash::copy as global-to-global blocking copy
654+ * operation.
655+ *
656+ * \ingroup DashAlgorithms
657+ */
658+ template <
659+ class GlobInputIt ,
660+ class GlobOutputIt ,
661+ bool UseHandles = false >
662+ GlobOutputIt copy (
663+ GlobInputIt in_first,
664+ GlobInputIt in_last,
665+ GlobOutputIt out_first,
666+ ActiveDestination /* unused*/ )
667+ {
668+ DASH_LOG_TRACE (" dash::copy()" , " blocking, global to global, active destination" );
669+
670+ using size_type = typename GlobInputIt::size_type;
671+ using input_value_type = typename GlobInputIt::value_type;
672+ using output_value_type = typename GlobOutputIt::value_type;
673+
674+ size_type num_elem_total = dash::distance (in_first, in_last);
675+ if (num_elem_total <= 0 ) {
676+ DASH_LOG_TRACE (" dash::copy" , " input range empty" );
677+ return out_first;
678+ }
679+
680+ auto g_out_first = out_first;
681+ auto g_out_last = g_out_first + num_elem_total;
682+
683+ internal::ContiguousRangeSet<GlobOutputIt> range_set{g_out_first, g_out_last};
684+
685+ const auto & out_team = out_first.team ();
686+ out_team.barrier ();
687+
688+ std::vector<dart_handle_t > handles;
689+ std::vector<dart_handle_t >* handles_arg = UseHandles ? &handles : nullptr ;
690+
691+ dash::internal::local_copy_chunks<input_value_type, output_value_type> local_chunks;
692+
693+ size_type num_elem_processed = 0 ;
694+
695+ for (auto range : range_set) {
696+
697+ auto cur_out_first = range.first ;
698+ auto num_copy_elem = range.second ;
699+
700+ DASH_ASSERT_GT (num_copy_elem, 0 ,
701+ " Number of elements to copy is 0" );
702+
703+ // handle local data only
704+ if (cur_out_first.is_local ()) {
705+ auto dest_ptr = cur_out_first.local ();
706+ auto src_ptr = in_first + num_elem_processed;
707+ internal::copy_impl (src_ptr,
708+ src_ptr + num_copy_elem,
709+ dest_ptr,
710+ handles_arg,
711+ local_chunks);
712+ }
713+ num_elem_processed += num_copy_elem;
714+ }
715+
716+ dash::internal::do_local_copies (local_chunks);
717+
718+ if (!handles.empty ()) {
719+ DASH_LOG_TRACE (" dash::copy" , " Waiting for remote transfers to complete," ,
720+ " num_handles: " , handles.size ());
721+ dart_waitall_local (handles.data (), handles.size ());
722+ } else if (!UseHandles) {
723+ dart_flush_local_all (in_first.dart_gptr ());
724+ }
725+ out_team.barrier ();
726+
727+ DASH_ASSERT_EQ (num_elem_processed, num_elem_total,
728+ " Failed to find all contiguous subranges in range" );
729+
730+ return g_out_last;
731+ }
732+
649733/* *
650734 * Specialization of \c dash::copy as global-to-global blocking copy
651735 * operation.
652736 *
653737 * \ingroup DashAlgorithms
654738 */
655- template <typename ValueType, class GlobInputIt , class GlobOutputIt >
739+ template <
740+ class GlobInputIt ,
741+ class GlobOutputIt ,
742+ bool UseHandles = false >
656743GlobOutputIt copy (
657- GlobInputIt /* in_first*/ ,
658- GlobInputIt /* in_last*/ ,
659- GlobOutputIt /* out_first*/ )
744+ GlobInputIt in_first,
745+ GlobInputIt in_last,
746+ GlobOutputIt out_first,
747+ ActiveSource /* unused*/ )
660748{
661749 DASH_LOG_TRACE (" dash::copy()" , " blocking, global to global" );
662750
663- // TODO:
664- // - Implement adapter for local-to-global dash::copy here
665- // - Return if global input range has no local sub-range
751+ using size_type = typename GlobInputIt::size_type;
752+ using input_value_type = typename GlobInputIt::value_type;
753+ using output_value_type = typename GlobOutputIt::value_type;
754+
755+ size_type num_elem_total = dash::distance (in_first, in_last);
756+ if (num_elem_total <= 0 ) {
757+ DASH_LOG_TRACE (" dash::copy" , " input range empty" );
758+ return out_first;
759+ }
760+
761+ internal::ContiguousRangeSet<GlobOutputIt> range_set{in_first, in_last};
762+
763+ const auto & in_team = in_first.team ();
764+ in_team.barrier ();
765+
766+ std::vector<dart_handle_t > handles;
767+ std::vector<dart_handle_t >* handles_arg = UseHandles ? &handles : nullptr ;
768+
769+ dash::internal::local_copy_chunks<input_value_type, output_value_type> local_chunks;
770+
771+ size_type num_elem_processed = 0 ;
772+
773+ for (auto range : range_set) {
774+
775+ auto cur_in_first = range.first ;
776+ auto num_copy_elem = range.second ;
777+
778+ DASH_ASSERT_GT (num_copy_elem, 0 ,
779+ " Number of elements to copy is 0" );
780+
781+ // handle local data only
782+ if (cur_in_first.is_local ()) {
783+ auto src_ptr = cur_in_first.local ();
784+ auto dest_ptr = out_first + num_elem_processed;
785+ internal::copy_impl (src_ptr,
786+ src_ptr + num_copy_elem,
787+ dest_ptr,
788+ handles_arg,
789+ local_chunks);
790+ }
791+ num_elem_processed += num_copy_elem;
792+ }
793+
794+ internal::do_local_copies (local_chunks);
795+
796+ if (!handles.empty ()) {
797+ DASH_LOG_TRACE (" dash::copy" , " Waiting for remote transfers to complete," ,
798+ " num_handles: " , handles.size ());
799+ dart_waitall (handles.data (), handles.size ());
800+ } else if (!UseHandles) {
801+ dart_flush_all (out_first.dart_gptr ());
802+ }
803+ in_team.barrier ();
804+
805+ DASH_ASSERT_EQ (num_elem_processed, num_elem_total,
806+ " Failed to find all contiguous subranges in range" );
666807
667- return GlobOutputIt () ;
808+ return out_first + num_elem_total ;
668809}
669810
670811#endif // DOXYGEN
0 commit comments