6565#include < vector>
6666
6767#include " absl/container/flat_hash_map.h"
68+ #include " absl/container/flat_hash_set.h"
6869#include " absl/log/log.h"
6970#include " absl/status/status.h"
7071#include " absl/status/statusor.h"
@@ -379,8 +380,18 @@ static CopyPlan BuildLoadCopyPlan(
379380 plan.h2d_host_block_ids .reserve (local_order.size ());
380381 for (size_t i = 0 ; i < local_order.size (); ++i) {
381382 const size_t original_idx = local_order[i];
382- plan.h2d_local_block_ids .push_back (local_block_ids[original_idx]);
383- plan.h2d_host_block_ids .push_back (local_host_block_ids[original_idx]);
383+ int64_t local_bid = local_block_ids[original_idx];
384+ int64_t host_bid = local_host_block_ids[original_idx];
385+ if (plan.h2d_local_block_ids .empty () ||
386+ plan.h2d_local_block_ids .back () != local_bid) {
387+ plan.h2d_local_block_ids .push_back (local_bid);
388+ plan.h2d_host_block_ids .push_back (host_bid);
389+ } else {
390+ if (plan.h2d_host_block_ids .back () != host_bid) {
391+ throw std::invalid_argument (
392+ " Duplicate local block IDs must map to the same host block ID" );
393+ }
394+ }
384395 }
385396
386397 plan.h2d_copy =
@@ -633,19 +644,31 @@ absl::Status KVCacheManagerWithTransfer::RegisterActivePlan(
633644 recv_entry.req_id = req_id;
634645
635646 int64_t total_blocks = 0 ;
647+ absl::flat_hash_set<int > unique_dst_blocks;
636648 for (const auto & [src_replica_idx, schedule] :
637649 request.shard_push_schedules ()) {
638- std::set <int > unique_blocks_from_this_source ;
650+ absl::flat_hash_set< std::pair <int , int >> unique_transfers_from_this_source ;
639651 for (const auto & push_entry : schedule.entries ()) {
640652 recv_entry.host_to_chip [push_entry.dst_block_id ()] =
641653 push_entry.dst_block_id ();
642- unique_blocks_from_this_source.insert (push_entry.dst_block_id ());
654+ unique_transfers_from_this_source.insert (
655+ {push_entry.src_block_id (), push_entry.dst_block_id ()});
656+ unique_dst_blocks.insert (push_entry.dst_block_id ());
643657 }
644- total_blocks += unique_blocks_from_this_source .size ();
658+ total_blocks += unique_transfers_from_this_source .size ();
645659 }
646660 recv_entry.total_blocks = total_blocks;
647661 recv_entry.num_completed_blocks = 0 ;
648662 recv_entry.deadline = DeadlineFromNow ();
663+
664+ // Populate h2d_copy spec for unique destination blocks
665+ std::vector<int64_t > h2d_host_block_ids (unique_dst_blocks.begin (),
666+ unique_dst_blocks.end ());
667+ std::vector<int64_t > h2d_local_block_ids =
668+ h2d_host_block_ids; // 1-to-1 mapping
669+ recv_entry.h2d_copy =
670+ BuildCoalescedCopySpec (h2d_host_block_ids, h2d_local_block_ids);
671+
649672 if (total_blocks > 0 ) {
650673 active_recv_entries_[uuid] = std::move (recv_entry);
651674 LOG (INFO ) << " RegisterActivePlan (Receiver): Populated "
@@ -765,7 +788,9 @@ void KVCacheManagerWithTransfer::StartRead(
765788 host_block_ids = *local_host_block_ids;
766789 } else if (!local_block_ids.empty ()) {
767790 std::lock_guard<std::mutex> lock (mu_);
768- if (static_cast <int64_t >(local_block_ids.size ()) > max_blocks_ ||
791+ absl::flat_hash_set<int64_t > unique_local_bids (local_block_ids.begin (),
792+ local_block_ids.end ());
793+ if (static_cast <int64_t >(unique_local_bids.size ()) > max_blocks_ ||
769794 free_slots_.empty ()) {
770795 // Request larger than a slot, or staging pool exhausted: surface as a
771796 // recv failure (the connector can recompute) rather than throwing.
@@ -774,9 +799,19 @@ void KVCacheManagerWithTransfer::StartRead(
774799 }
775800 Slot slot = AcquireSlotLocked ();
776801 recv_slot = slot.slot_idx ;
802+ absl::flat_hash_map<int64_t , int64_t > local_to_host;
803+ size_t host_block_idx = 0 ;
777804 host_block_ids.reserve (local_block_ids.size ());
778805 for (size_t k = 0 ; k < local_block_ids.size (); ++k) {
779- host_block_ids.push_back (slot.block_ids [k]);
806+ int64_t local_bid = local_block_ids[k];
807+ auto it = local_to_host.find (local_bid);
808+ if (it == local_to_host.end ()) {
809+ int64_t host_bid = slot.block_ids [host_block_idx++];
810+ local_to_host[local_bid] = host_bid;
811+ host_block_ids.push_back (host_bid);
812+ } else {
813+ host_block_ids.push_back (it->second );
814+ }
780815 }
781816 }
782817 CopyPlan load_plan =
0 commit comments