MCPcopy Create free account
hub / github.com/Oneflow-Inc/oneflow / InitializeMemory

Method InitializeMemory

oneflow/core/auto_parallel/sbp_node.cpp:739–791  ·  view source on GitHub ↗

Assemble memory cost

Source from the content-addressed store, hash-verified

737
738// Assemble memory cost
739void SbpNode::InitializeMemory(bool is_reusable, const HashMap<LogicalBlobId, int32_t>& lbi2id,
740 const std::vector<int32_t>& id2count, bool nccl_use_compute_stream) {
741 const auto& curr_operator = op_node_->op();
742 // An edge should not be initialized twice
743 // During each initialization, we are computing sum(memory of consumer) - sum(memory of producer)
744 // This is why we need to pre-store memory of producer
745 HashMap<SbpEdge*, std::vector<int64_t>> sbp_edge2nd_sbp_sig2memory;
746 for (const auto& obn : curr_operator.output_bns()) {
747 const LogicalBlobId& lbi = curr_operator.BnInOp2Lbi(obn);
748 // Fixed memory or in the support of the reusable memory
749 if (!is_reusable || id2count.at(lbi2id.at(lbi)) > 0) {
750 // If not in support, memory_ would be empty.
751 in_memory_support_ = true;
752 memory_.resize(sbp_sig_list_.size(), 0);
753 const auto& logical_blob_desc = op_node_->LogicalBlobDesc4Lbi(lbi);
754 const auto& hierarchy = *CHECK_JUST(curr_operator.GetParallelDesc4BnInOp(obn))->hierarchy();
755 // There are some operators with a fixed sbp for some blobs, such as conv.
756 // {in: S0, kernel: B, out: S0}
757 // {in: B, kernel: B, out: B}
758 // The blob kernel have the same sbp for different signatures.
759 // We pre-store the results for the same sbp while accessing the same blobs.
760 HashMap<NdSbp, int64_t> nd_sbp2memory;
761 SbpEdge* edge_contain_lbi = nullptr;
762 for (const auto& edge_out : edges_out_) {
763 if (edge_out->SearchLbi(lbi)) { edge_contain_lbi = edge_out; }
764 }
765 // There exist some lbi which does not have a consumer
766 // At this moment edge_contain_lbi == nullptr
767 auto& nd_sbp_sig2memory = sbp_edge2nd_sbp_sig2memory[edge_contain_lbi];
768 nd_sbp_sig2memory.resize(sbp_sig_list_.size(), 0);
769 for (int32_t sbp_sig_id = 0; sbp_sig_id < sbp_sig_list_.size(); sbp_sig_id++) {
770 const NdSbp& nd_sbp = sbp_sig_list_[sbp_sig_id].bn_in_op2nd_sbp().at(obn);
771 auto it = nd_sbp2memory.find(nd_sbp);
772 if (it == nd_sbp2memory.end()) {
773 // This compute the memory at rank 0, the largest one.
774 // We could be faster if we just compute the average memory.
775 it = nd_sbp2memory
776 .insert({nd_sbp, MaxByteSize4BlobDescSbp(logical_blob_desc, nd_sbp, hierarchy)})
777 .first;
778 }
779 memory_[sbp_sig_id] += it->second;
780 nd_sbp_sig2memory[sbp_sig_id] += it->second;
781 }
782 }
783 }
784 // Even after the correction in the memory of edges, the relative error still have 0.73%.
785 if (nccl_use_compute_stream && in_memory_support_ && is_reusable) {
786 for (const auto& pair : sbp_edge2nd_sbp_sig2memory) {
787 // Init memory for each out-going edge
788 pair.first->InitializeMemory(lbi2id, id2count, pair.second);
789 }
790 }
791}
792
793// Reduce and set the wait time for op in the trunk
794void SbpNode::SetTrunkWaitTime(double trunk_wait_time) {

Callers 1

InitMemoryFunction · 0.45

Calls 11

MaxByteSize4BlobDescSbpFunction · 0.85
hierarchyMethod · 0.80
SearchLbiMethod · 0.80
findMethod · 0.80
insertMethod · 0.80
opMethod · 0.45
atMethod · 0.45
resizeMethod · 0.45
sizeMethod · 0.45
endMethod · 0.45

Tested by

no test coverage detected