diff --git a/configs/fat-tree/network.yml b/configs/fat-tree/network.yml index b3c4feaec2..438a1acab4 100644 --- a/configs/fat-tree/network.yml +++ b/configs/fat-tree/network.yml @@ -32,31 +32,16 @@ presets: type: tcp preset-name: default-flow - flow-2: - type: tcp - preset-name: default-flow + # flow-2: + # type: tcp + # preset-name: default-flow - flow-3: - type: tcp - preset-name: default-flow + # flow-3: + # type: tcp + # preset-name: default-flow connections: - connection-pod1_host1--pod2_host1: - preset-name: default-connection - sender_id: pod-1_edge-1_host-1 - receiver_id: pod-2_edge-1_host-1 - - connection-pod1_host1--pod2_host2: - preset-name: default-connection - sender_id: pod-1_edge-1_host-1 - receiver_id: pod-2_edge-1_host-2 - - connection-pod1_host1--pod2_host3: - preset-name: default-connection - sender_id: pod-1_edge-1_host-1 - receiver_id: pod-2_edge-2_host-1 - - connection-pod1_host1--pod2_host4: + connection-pod1_edge-1_host1--edge-2_host1: preset-name: default-connection sender_id: pod-1_edge-1_host-1 - receiver_id: pod-2_edge-2_host-2 + receiver_id: pod-1_edge-2_host-1 diff --git a/configs/fat-tree/topology.yml b/configs/fat-tree/topology.yml index 45f35c4d3d..fd65f02ec6 100644 --- a/configs/fat-tree/topology.yml +++ b/configs/fat-tree/topology.yml @@ -25,7 +25,7 @@ switches: min: 0.2 max: 0.3 probability: 0.7 - + edge: ecn: min: 0.2 @@ -41,4 +41,5 @@ links: aggr-edge: preset-name: link edge-host: - preset-name: link \ No newline at end of file + preset-name: link + throughput: 20Gbps diff --git a/configs/leaf-spine-sw_based_rdma/network.yml b/configs/leaf-spine-sw_based_rdma/network.yml new file mode 100644 index 0000000000..349e722fc3 --- /dev/null +++ b/configs/leaf-spine-sw_based_rdma/network.yml @@ -0,0 +1,76 @@ +type: custom +topology_config_path: topology.yml + +connections: + host-1--host-6: + type: rdma + sender_id: host-1 + receiver_id: host-6 + ports: + sender: 1 + receiver: 1 + dcqcn: + initial_alpha_value: 200 + start_target_rate: 10Gbps + rpg_time_reset: 10000ns + rate_reduce_monitor_period: 500ns + rpg_min_rate: 1Gbps + rpg_ai_rate: 1Mbps + rpg_hai_rate: 2Gbps + host-2--host-6: + type: rdma + sender_id: host-2 + receiver_id: host-6 + ports: + sender: 1 + receiver: 2 + dcqcn: + start_target_rate: 10Gbps + rpg_time_reset: 10000ns + rate_reduce_monitor_period: 500ns + rpg_min_rate: 1Gbps + rpg_ai_rate: 1Mbps + rpg_hai_rate: 2Gbps + host-3--host-6: + type: rdma + sender_id: host-3 + receiver_id: host-6 + ports: + sender: 1 + receiver: 3 + dcqcn: + start_target_rate: 10Gbps + rpg_time_reset: 10000ns + rate_reduce_monitor_period: 500ns + rpg_min_rate: 1Gbps + rpg_ai_rate: 1Mbps + rpg_hai_rate: 2Gbps + host-4--host-6: + type: rdma + sender_id: host-4 + receiver_id: host-6 + ports: + sender: 11 + receiver: 4 + dcqcn: + start_target_rate: 10Gbps + rpg_time_reset: 10000ns + rate_reduce_monitor_period: 500ns + rpg_min_rate: 1Gbps + rpg_ai_rate: 1Mbps + rpg_hai_rate: 2Gbps + host-5--host-6: + type: rdma + sender_id: host-5 + receiver_id: host-6 + ports: + sender: 1 + receiver: 5 + dcqcn: + start_target_rate: 10Gbps + rpg_time_reset: 10000ns + rate_reduce_monitor_period: 500ns + rpg_min_rate: 1Gbps + rpg_ai_rate: 1Mbps + rpg_hai_rate: 2Gbps + \ No newline at end of file diff --git a/configs/leaf-spine-sw_based_rdma/scenario.yml b/configs/leaf-spine-sw_based_rdma/scenario.yml new file mode 100644 index 0000000000..72b7bed3e6 --- /dev/null +++ b/configs/leaf-spine-sw_based_rdma/scenario.yml @@ -0,0 +1,28 @@ +network_config_path: network.yml + +scenario: +- action: send_data + id: huge-send_1--6 + when: 0ns + size: 10MB + connections: host-1--host-6 +- action: send_data + id: small_2--6 + when: 100000ns + size: 256KB + connections: host-2--host-6 +- action: send_data + id: small_3--6 + when: 100000ns + size: 256KB + connections: host-3--host-6 +- action: send_data + id: small_4--6 + when: 100000ns + size: 256KB + connections: host-4--host-6 +# - action: send_data +# id: small_5--6 +# when: 100000ns +# size: 256KB +# connections: host-5--host-6 \ No newline at end of file diff --git a/configs/leaf-spine-sw_based_rdma/topology.yml b/configs/leaf-spine-sw_based_rdma/topology.yml new file mode 100644 index 0000000000..3296ffdad9 --- /dev/null +++ b/configs/leaf-spine-sw_based_rdma/topology.yml @@ -0,0 +1,39 @@ +type: leaf-spine + +presets: + link: + latency: 1000ns + throughput: 10Gbps + ingress_buffer_size: 1MB + egress_buffer_size: 1MB + metrics_filters: + queue_sizes: false + +packet-spraying: + # type: ecmp + # type: random + type: flowlet + threshold: 9000ns + +switches: + spine: + count: 4 + ecn: + min: 0.3 + max: 0.5 + probability: 0.2 + leaf: + ecn: + min: 0.3 + max: 0.5 + probability: 0.2 + count: 6 + +hosts: + +links: + leaf-spine: + preset-name: link + host-leaf: + preset-name: link + throughput: 50Gbps diff --git a/configs/leaf-spine-sw_based_tcp/network.yml b/configs/leaf-spine-sw_based_tcp/network.yml new file mode 100644 index 0000000000..9f1e8dbc42 --- /dev/null +++ b/configs/leaf-spine-sw_based_tcp/network.yml @@ -0,0 +1,90 @@ +type: custom +topology_config_path: topology.yml + +connections: + host-1--host-6: + type: mplb-connection + sender_id: host-1 + receiver_id: host-6 + mplb: + type: single-cc + packet-size: 1500B + cc: + type: tahoe + path-chooser: + type: round-robin + flows: + flow: + type: tcp + ports: + sender: 1 + receiver: 1 + host-2--host-6: + type: mplb-connection + sender_id: host-2 + receiver_id: host-6 + mplb: + type: single-cc + packet-size: 1500B + cc: + type: tahoe + path-chooser: + type: round-robin + flows: + flow: + type: tcp + ports: + sender: 1 + receiver: 2 + host-3--host-6: + type: mplb-connection + sender_id: host-3 + receiver_id: host-6 + mplb: + type: single-cc + packet-size: 1500B + cc: + type: tahoe + path-chooser: + type: round-robin + flows: + flow: + type: tcp + ports: + sender: 1 + receiver: 3 + host-4--host-6: + type: mplb-connection + sender_id: host-4 + receiver_id: host-6 + mplb: + type: single-cc + packet-size: 1500B + cc: + type: tahoe + path-chooser: + type: round-robin + flows: + flow: + type: tcp + ports: + sender: 1 + receiver: 4 + host-5--host-6: + type: mplb-connection + sender_id: host-5 + receiver_id: host-6 + mplb: + type: single-cc + packet-size: 1500B + cc: + type: tahoe + path-chooser: + type: round-robin + flows: + flow: + type: tcp + ports: + sender: 1 + receiver: 5 + \ No newline at end of file diff --git a/configs/leaf-spine-sw_based_tcp/scenario.yml b/configs/leaf-spine-sw_based_tcp/scenario.yml new file mode 100644 index 0000000000..7e96a824a2 --- /dev/null +++ b/configs/leaf-spine-sw_based_tcp/scenario.yml @@ -0,0 +1,28 @@ +network_config_path: network.yml + +scenario: +- action: send_data + id: huge-send_1--10 + when: 0ns + size: 10MB + connections: host-1--host-6 +- action: send_data + id: small_2--10 + when: 100000ns + size: 256KB + connections: host-2--host-6 +- action: send_data + id: small_3--10 + when: 100000ns + size: 256KB + connections: host-3--host-6 +- action: send_data + id: small_4--10 + when: 100000ns + size: 256KB + connections: host-4--host-6 +- action: send_data + id: small_5--10 + when: 100000ns + size: 256KB + connections: host-5--host-6 \ No newline at end of file diff --git a/configs/leaf-spine-sw_based_tcp/topology.yml b/configs/leaf-spine-sw_based_tcp/topology.yml new file mode 100644 index 0000000000..4c3c1890e3 --- /dev/null +++ b/configs/leaf-spine-sw_based_tcp/topology.yml @@ -0,0 +1,39 @@ +type: leaf-spine + +presets: + link: + latency: 1000ns + throughput: 10Gbps + ingress_buffer_size: 1MB + egress_buffer_size: 1MB + metrics_filters: + queue_sizes: false + +packet-spraying: + # type: ecmp + type: random + # type: flowlet + # threshold: 500ns + +switches: + spine: + count: 4 + ecn: + min: 0.3 + max: 0.5 + probability: 0.2 + leaf: + ecn: + min: 0.3 + max: 0.5 + probability: 0.2 + count: 6 + +hosts: + +links: + leaf-spine: + preset-name: link + host-leaf: + preset-name: link + throughput: 50Gbps diff --git a/configs/leaf-spine/network.yml b/configs/leaf-spine/network.yml index 6a1b97ba56..fe4aec2520 100644 --- a/configs/leaf-spine/network.yml +++ b/configs/leaf-spine/network.yml @@ -8,59 +8,24 @@ presets: type: single-cc packet-size: 1500B cc: - type: tahoe + type: swift + base_target: 12500ns path-chooser: type: round-robin flows: - flow: + flow-1: + type: tcp + flow-2: + type: tcp + flow-3: + type: tcp + flow-4: + type: tcp + flow-5: type: tcp connections: - conn_1--2: - sender_id: host-1 - receiver_id: host-2 + conn: preset-name: default-connection - conn_1--3: - sender_id: host-1 - receiver_id: host-3 - preset-name: default-connection - conn_1--4: sender_id: host-1 receiver_id: host-4 - preset-name: default-connection - conn_2--1: - sender_id: host-2 - receiver_id: host-1 - preset-name: default-connection - conn_2--3: - sender_id: host-2 - receiver_id: host-3 - preset-name: default-connection - conn_2--4: - sender_id: host-2 - receiver_id: host-4 - preset-name: default-connection - conn_3--1: - sender_id: host-3 - receiver_id: host-1 - preset-name: default-connection - conn_3--2: - sender_id: host-3 - receiver_id: host-2 - preset-name: default-connection - conn_3--4: - sender_id: host-3 - receiver_id: host-4 - preset-name: default-connection - conn_4--1: - sender_id: host-4 - receiver_id: host-1 - preset-name: default-connection - conn_4--2: - sender_id: host-4 - receiver_id: host-2 - preset-name: default-connection - conn_4--3: - sender_id: host-4 - receiver_id: host-3 - preset-name: default-connection diff --git a/configs/leaf-spine/network_sw_based.yml b/configs/leaf-spine/network_sw_based.yml new file mode 100644 index 0000000000..bf87245f6e --- /dev/null +++ b/configs/leaf-spine/network_sw_based.yml @@ -0,0 +1,56 @@ +type: custom +topology_config_path: topology.yml + +presets: + default-connection: + type: mplb-connection + mplb: + type: single-cc + packet-size: 1500B + cc: + type: swift + base_target: 12500ns + path-chooser: + type: round-robin + flows: + flow: + type: tcp + +connections: + conn-1: + preset-name: default-connection + sender_id: host-1 + receiver_id: host-4 + conn-2: + preset-name: default-connection + sender_id: host-2 + receiver_id: host-4 + conn-3: + preset-name: default-connection + sender_id: host-3 + receiver_id: host-4 + conn-rdma: + type: rdma + sender_id: host-1 + receiver_id: host-4 + dcqcn: + start_target_rate: 10Gbps + rpg_time_reset: 10000ns + rate_reduce_monitor_period: 500ns + rpg_min_rate: 1Gbps + rpg_ai_rate: 1Mbps + rpg_hai_rate: 2Gbps + conn-tahoe: + type: mplb-connection + sender_id: host-2 + receiver_id: host-4 + mplb: + type: single-cc + packet-size: 1500B + cc: + type: tahoe + path-chooser: + type: round-robin + flows: + flow: + type: tcp diff --git a/configs/leaf-spine/scenario.yml b/configs/leaf-spine/scenario.yml index 6aebfbeb5d..d9490425c0 100644 --- a/configs/leaf-spine/scenario.yml +++ b/configs/leaf-spine/scenario.yml @@ -4,7 +4,5 @@ scenario: - action: send_data id: send-1 when: 0ns - size: 256KB - repeat_count: 1 + size: 1MB connections: ^conn.* - repeat_interval: 500000ns diff --git a/configs/leaf-spine/scenario_sw_based.yml b/configs/leaf-spine/scenario_sw_based.yml new file mode 100644 index 0000000000..c0ac27f863 --- /dev/null +++ b/configs/leaf-spine/scenario_sw_based.yml @@ -0,0 +1,28 @@ +network_config_path: network_sw_based.yml + +scenario: +# - action: send_data +# id: send-1 +# when: 0ns +# size: 1MB +# connections: conn-1 +- action: send_data + id: send-rdma + when: 0ns + size: 10MB + connections: conn-rdma +- action: send_data + id: send-tahoe + when: 0ns + size: 10MB + connections: conn-tahoe +# - action: send_data +# id: send-2 +# when: 0ns +# size: 1MB +# connections: conn-2 +# - action: send_data +# id: send-3 +# when: 0ns +# size: 1MB +# connections: conn-3 diff --git a/configs/leaf-spine/topology.yml b/configs/leaf-spine/topology.yml index 396b1d6be3..34a24e70cb 100644 --- a/configs/leaf-spine/topology.yml +++ b/configs/leaf-spine/topology.yml @@ -2,20 +2,31 @@ type: leaf-spine presets: link: - latency: 0ns - throughput: 100Gbps - ingress_buffer_size: 64KB - egress_buffer_size: 64KB + latency: 1000ns + throughput: 10Gbps + ingress_buffer_size: 1MB + egress_buffer_size: 1MB metrics_filters: queue_sizes: false packet-spraying: + # type: ecmp type: random + # type: flowlet + # threshold: 200000ns switches: spine: count: 2 + ecn: + min: 0.3 + max: 0.5 + probability: 0.2 leaf: + ecn: + min: 0.3 + max: 0.5 + probability: 0.2 count: 4 hosts: @@ -24,4 +35,5 @@ links: leaf-spine: preset-name: link host-leaf: - preset-name: link \ No newline at end of file + preset-name: link + throughput: 20Gbps diff --git a/configs/rdma_test/network.yml b/configs/rdma_test/network.yml new file mode 100644 index 0000000000..382a756beb --- /dev/null +++ b/configs/rdma_test/network.yml @@ -0,0 +1,13 @@ +topology_config_path: topology.yml +type: custom + +connections: + connection: + type: rdma + sender_id: sender + receiver_id: receiver + dcqcn: + start_target_rate: 10Gbps + rpg_time_reset: 1000ns + rate_reduce_monitor_period: 10000ns + rpg_min_rate: 1Gbps diff --git a/configs/rdma_test/scenario.yml b/configs/rdma_test/scenario.yml new file mode 100644 index 0000000000..2501cc1346 --- /dev/null +++ b/configs/rdma_test/scenario.yml @@ -0,0 +1,8 @@ +network_config_path: network.yml + +scenario: +- action: send_data + id: send + when: 0ns + size: 1MB + connections: connection diff --git a/configs/rdma_test/topology.yml b/configs/rdma_test/topology.yml new file mode 100644 index 0000000000..981a8dc4f5 --- /dev/null +++ b/configs/rdma_test/topology.yml @@ -0,0 +1,83 @@ +type: custom +presets: + default-switch: + ecn: + min: 0.3 + max: 0.5 + probability: 0.2 + default-link: + latency: 1000ns + throughput: 10Gbps + ingress_buffer_size: 1MB + egress_buffer_size: 1MB + +packet-spraying: + type: ecmp + threshold: 1000ns + +hosts: + sender: + receiver: + +switches: + switch-sender: + preset-name: default-switch + switch-1: + preset-name: default-switch + switch-2: + preset-name: default-switch + switch-receiver: + preset-name: default-switch +links: + link-0: + from: sender + to: switch-sender + preset-name: default-link + throughput: 20Gbps + back-0: + from: switch-sender + to: sender + preset-name: default-link + throughput: 20Gbps + link-1: + from: switch-sender + to: switch-1 + preset-name: default-link + link-2: + from: switch-1 + to: switch-sender + preset-name: default-link + link-3: + from: switch-sender + to: switch-2 + preset-name: default-link + link-4: + from: switch-2 + to: switch-sender + preset-name: default-link + link-5: + from: switch-receiver + to: switch-1 + preset-name: default-link + link-6: + from: switch-1 + to: switch-receiver + preset-name: default-link + link-7: + from: switch-receiver + to: switch-2 + preset-name: default-link + link-8: + from: switch-2 + to: switch-receiver + preset-name: default-link + link-9: + from: receiver + to: switch-receiver + preset-name: default-link + throughput: 20Gbps + back-9: + from: switch-receiver + to: receiver + preset-name: default-link + throughput: 20Gbps diff --git a/configs/scenario-configs.txt b/configs/scenario-configs.txt index e3cdef51aa..cfc963a97a 100644 --- a/configs/scenario-configs.txt +++ b/configs/scenario-configs.txt @@ -2,4 +2,7 @@ fat-tree/scenario.yml incast/scenario.yml leaf-spine/scenario.yml simple/scenario.yml +simple/rdma_scenario.yml single-rack/scenario.yml +leaf-spine-sw_based_tcp/scenario.yml +leaf-spine-sw_based_rdma/scenario.yml diff --git a/configs/simple/rdma_network.yml b/configs/simple/rdma_network.yml new file mode 100644 index 0000000000..aac951938a --- /dev/null +++ b/configs/simple/rdma_network.yml @@ -0,0 +1,10 @@ +topology_config_path: topology.yml +type: custom + +connections: + connection: + type: rdma + sender_id: sender + receiver_id: receiver + dcqcn: + start_target_rate: 10Gbps diff --git a/configs/simple/rdma_scenario.yml b/configs/simple/rdma_scenario.yml new file mode 100644 index 0000000000..a22ab650d4 --- /dev/null +++ b/configs/simple/rdma_scenario.yml @@ -0,0 +1,8 @@ +network_config_path: rdma_network.yml + +scenario: +- action: send_data + id: send + when: 0ns + size: 50KB + connections: connection diff --git a/source/metrics/packet_reordering/simple_packet_reordering.cpp b/source/metrics/packet_reordering/simple_packet_reordering.cpp index d206a9c951..1d15f22ed6 100644 --- a/source/metrics/packet_reordering/simple_packet_reordering.cpp +++ b/source/metrics/packet_reordering/simple_packet_reordering.cpp @@ -8,11 +8,17 @@ SimplePacketReordering::SimplePacketReordering() void SimplePacketReordering::add_record(PacketNum packet_num) { if (packet_num == m_next_packet_num) { m_next_packet_num++; + while (!m_packet_num_set.empty() && + *m_packet_num_set.begin() == m_next_packet_num) { + m_packet_num_set.erase(m_packet_num_set.begin()); + m_next_packet_num++; + } } else { + m_packet_num_set.insert(packet_num); m_reordering++; } } PacketReordering SimplePacketReordering::value() const { return m_reordering; } -}; // namespace sim \ No newline at end of file +}; // namespace sim diff --git a/source/metrics/packet_reordering/simple_packet_reordering.hpp b/source/metrics/packet_reordering/simple_packet_reordering.hpp index 2fa097f8cd..a933fcc089 100644 --- a/source/metrics/packet_reordering/simple_packet_reordering.hpp +++ b/source/metrics/packet_reordering/simple_packet_reordering.hpp @@ -1,4 +1,6 @@ #pragma once +#include + #include "i_packet_reordering.hpp" #include "utils/statistics.hpp" @@ -17,5 +19,6 @@ class SimplePacketReordering : public IPacketReordering { // When m_packet_num_set.size() growth up it, the smallest element deletes std::size_t m_next_packet_num; PacketReordering m_reordering; + std::set m_packet_num_set; }; -} // namespace sim \ No newline at end of file +} // namespace sim diff --git a/source/network/connection/mplb/rdma/dcqcn.cpp b/source/network/connection/rdma/dcqcn/dcqcn.cpp similarity index 94% rename from source/network/connection/mplb/rdma/dcqcn.cpp rename to source/network/connection/rdma/dcqcn/dcqcn.cpp index 56c24818ba..c1d5875dcf 100644 --- a/source/network/connection/mplb/rdma/dcqcn.cpp +++ b/source/network/connection/rdma/dcqcn/dcqcn.cpp @@ -5,7 +5,8 @@ namespace sim { DCQCN::DCQCN(const ParamsDQCCN& a_params) : m_params(a_params), - m_current_rate(a_params.rpg_min_rate), + m_current_rate(std::max(SpeedMbps(m_params.start_target_rate), + m_params.rpg_min_rate)), m_target_rate(m_current_rate), m_alpha(m_params.initial_alpha_value) {} @@ -81,9 +82,8 @@ void DCQCN::on_rate_reduce_monitor_period() { m_time_counter = 0; } - sched.add(now + m_params.rpg_time_reset, [this, last_cnp = m_last_cnp]() { - on_rate_increase_timer(last_cnp); - }); + sched.add(now + m_params.rate_reduce_monitor_period, + [this]() { on_rate_reduce_monitor_period(); }); } void DCQCN::on_alpha_timer() { @@ -145,4 +145,4 @@ void DCQCN::on_rate_increase_event() { m_current_rate = (m_current_rate + m_target_rate) / 2.0; } -} // namespace sim \ No newline at end of file +} // namespace sim diff --git a/source/network/connection/mplb/rdma/dcqcn.hpp b/source/network/connection/rdma/dcqcn/dcqcn.hpp similarity index 98% rename from source/network/connection/mplb/rdma/dcqcn.hpp rename to source/network/connection/rdma/dcqcn/dcqcn.hpp index dd5cf62f13..a4e5289d17 100644 --- a/source/network/connection/mplb/rdma/dcqcn.hpp +++ b/source/network/connection/rdma/dcqcn/dcqcn.hpp @@ -11,6 +11,7 @@ namespace sim { // https://enterprise-support.nvidia.com/s/article/dcqcn-parameters struct ParamsDQCCN { + SpeedGbps start_target_rate; // -------------Rate increment------------- // The time period between rate increase events. @@ -108,4 +109,4 @@ class DCQCN { bool m_stop_request = false; }; -} // namespace sim \ No newline at end of file +} // namespace sim diff --git a/source/network/connection/rdma/rdma_connection.cpp b/source/network/connection/rdma/rdma_connection.cpp new file mode 100644 index 0000000000..ca143fbcf7 --- /dev/null +++ b/source/network/connection/rdma/rdma_connection.cpp @@ -0,0 +1,404 @@ +#include "rdma_connectrion.hpp" +#include "scheduler/scheduler.hpp" +#include "utils/defer.hpp" + +namespace sim { + +RdmaConnectionPtr RdmaConnection::create_shared(const RdmaParams& a_params) { + return RdmaConnectionPtr(new RdmaConnection(a_params)); +} + +[[nodiscard]] utils::StrExpected RdmaConnection::send_data( + Data data, OnDeliveryCallback callback) { + DataId data_id = data.id; + if (m_data_context_table.contains(data_id)) { + return std::unexpected( + fmt::format("Connection {}: could not add data {}: data with given " + "id already sent", + m_id, data.to_string())); + } + if (m_ctx.first_send_data_time == std::nullopt) { + m_ctx.first_send_data_time = + Scheduler::get_instance().get_current_time(); + } + m_data_context_table[data_id] = + DataContext{data.size, SizeByte(0ul), SizeByte(0ul), callback}; + m_ctx.total_data_added += data.size; + + SizeByte total_size(0ul); + if (data.size == SizeByte(0ul)) { + return std::unexpected(fmt::format( + "Rdma connection {}: could not send data with zero size", m_id)); + } + bool was_sending_queue_empty = m_send_queue.empty(); + while (total_size < data.size) { + m_send_queue.emplace_back(create_data_packet(data)); + total_size += m_packet_size; + } + if (was_sending_queue_empty) { + start_data_sending(); + } + return {}; +} + +ConnectionContext RdmaConnection::get_context() const { return m_ctx; } + +MetricsTable RdmaConnection::get_metrics_table() const { + return MetricsTable(); +} + +void RdmaConnection::write_inner_metrics( + [[maybe_unused]] std::filesystem::path output_dir) const {} + +const Id& RdmaConnection::get_id() const { return m_id; } + +RdmaConnection::RdmaConnection(const RdmaParams& a_params) + : m_id(a_params.id), + m_dcqcn(a_params.dcqcn), + m_sender(a_params.ft.sender), + m_sender_port(a_params.ft.sender_port), + m_packet_size(a_params.packet_size), + m_receiver(a_params.ft.receiver), + m_receiver_port(a_params.ft.receiver_port), + m_ack_threshold(a_params.ack_threshold) {} + +void RdmaConnection::schedule_ack_timer() { + Scheduler& sched = Scheduler::get_instance(); + TimeNs now = sched.get_current_time(); + auto conn = shared_from_this(); + sched.add(now + m_ack_receiver_timout, [conn]() { conn->on_ack_timer(); }); +} + +void RdmaConnection::on_ack_timer() { + Scheduler& sched = Scheduler::get_instance(); + TimeNs now = sched.get_current_time(); + // TODO: replacse with flag (send <> packet by sender) + if (m_send_queue.empty()) { + return; + } + + if (m_last_ack_send + m_ack_receiver_timout < now) { + LOG_ERROR(fmt::format("RDMA connection {}: ack timer; send ack", m_id)); + send_ack(); + } + + schedule_ack_timer(); +} + +void RdmaConnection::on_retry_timout() { + Scheduler& sched = Scheduler::get_instance(); + TimeNs now = sched.get_current_time(); + + if (m_send_queue.empty()) { + LOG_INFO( + fmt::format("RMDA connection {}: all packets confirmed; stop retry " + "events scheduling", + m_id)); + return; + } + + if (m_ctx.last_data_delivery_time.value_or(TimeNs(0)) + m_retry_timout < + now) { + LOG_ERROR(fmt::format( + "RDMA connection {}: retry timout expired; retrandsmit packets", + m_id)); + retransmit_packets(); + } + schedule_retry_timout(); +} + +void RdmaConnection::schedule_retry_timout() { + Scheduler& sched = Scheduler::get_instance(); + TimeNs now = sched.get_current_time(); + auto conn = shared_from_this(); + sched.add(now + m_retry_timout, [conn]() { conn->on_retry_timout(); }); +} + +void RdmaConnection::retransmit_packets() { + uint32_t i = m_pcn - m_last_acked_pcn - 1; + bool sending_stopped = (i >= m_send_queue.size()); + m_pcn = m_last_acked_pcn + 1; + if (sending_stopped) { + send_next_data_packet(); + } +} + +void RdmaConnection::start_data_sending() { + m_dcqcn.start(); + send_next_data_packet(); + schedule_retry_timout(); +} + +void RdmaConnection::schedule_data_send() { + Scheduler& sched = Scheduler::get_instance(); + TimeNs now = sched.get_current_time(); + + SpeedGbps rate = m_dcqcn.get_rate(); + TimeNs delay = m_packet_size / rate; + RdmaConnectionPtr conn = shared_from_this(); + sched.add(now + delay, [conn]() { conn->send_next_data_packet(); }); +} + +void RdmaConnection::send_next_data_packet() { + uint32_t i = m_pcn - m_last_acked_pcn - 1; + if (i >= m_send_queue.size()) { + LOG_INFO( + fmt::format("RDMA connection {}: send all packet from sending " + "queue; send ack request packet", + m_id)); + send_ack_request(); + return; + } + m_pcn++; + const Packet& data = m_send_queue[i]; + m_sender->enqueue_packet(data); + schedule_data_send(); +} + +Packet RdmaConnection::create_data_packet(const Data& data) { + Packet packet; + packet.packet_num = m_next_packet_num++; + + packet.data_id = std::move(data.id); + packet.sender_id = m_sender->get_id(); + packet.sender_port = m_sender_port; + packet.receiver_port = m_receiver_port; + packet.receiver_id = m_receiver->get_id(); + packet.size = m_packet_size; + + RdmaConnectionPtr conn = shared_from_this(); + + packet.callback = [conn](const Packet& delivered_packet) { + conn->process_data_packet(delivered_packet); + }; + TimeNs now = Scheduler::get_instance().get_current_time(); + packet.generated_time = now; + + packet.ecn_capable_transport = true; + packet.congestion_experienced = false; + return packet; +} + +void RdmaConnection::process_data_packet(const Packet& packet) { + if (!m_receiver_started) { + m_receiver_started = true; + schedule_ack_timer(); + } + if (packet.packet_num < m_next_expected_packet_num) { + LOG_ERROR(fmt::format( + "RDMA {}: receiver got data packet {} with number smaller " + "than expected {}; ignored", + m_id, packet.to_string(), m_next_expected_packet_num)); + } else if (packet.packet_num == m_next_expected_packet_num) { + process_expected_data_packet(); + } else { + LOG_ERROR(fmt::format( + "RDMA {}: receiver got data packet {} with number greater " + "than expected {}; could not put it to reorder buffer; ignored", + m_id, packet.to_string(), m_next_expected_packet_num)); + send_nak(); + return; + } + if (packet.congestion_experienced) { + send_cnp(); + } +} + +void RdmaConnection::process_expected_data_packet() { + m_next_expected_packet_num++; + if (++m_data_packets_on_receiver >= m_ack_threshold) { + m_data_packets_on_receiver = 0; + send_ack(); + } +} + +void RdmaConnection::send_nak() { + Packet nak; + if (m_next_expected_packet_num == 0) { + LOG_ERROR( + fmt::format("RDMA connection {}: cold not send nak: next expected " + "packet num = 0", + m_id)); + return; + } + nak.packet_num = m_next_expected_packet_num - 1; + + nak.sender_id = m_receiver->get_id(); + nak.sender_port = m_receiver_port; + nak.receiver_port = m_sender_port; + nak.receiver_id = m_sender->get_id(); + nak.size = M_ACK_SIZE; + + RdmaConnectionPtr conn = shared_from_this(); + + nak.callback = [conn](const Packet& nak) { conn->process_nak(nak); }; + TimeNs now = Scheduler::get_instance().get_current_time(); + nak.generated_time = now; + nak.sent_time = now; + + nak.ecn_capable_transport = true; + nak.congestion_experienced = false; + + m_receiver->enqueue_packet(nak); +} + +void RdmaConnection::process_nak(const Packet& nak) { + while (m_last_acked_pcn < nak.packet_num) { + m_last_acked_pcn++; + confirm_first_unconfirmed_packet(); + } + retransmit_packets(); +} + +void RdmaConnection::send_ack() { + m_last_ack_send = Scheduler::get_instance().get_current_time(); + Packet ack; + if (m_next_expected_packet_num == 0) { + LOG_ERROR( + fmt::format("RDMA connection {}: cold not send ack: next expected " + "packet num = 0", + m_id)); + return; + } + ack.packet_num = m_next_expected_packet_num - 1; + + ack.sender_id = m_receiver->get_id(); + ack.sender_port = m_receiver_port; + ack.receiver_port = m_sender_port; + ack.receiver_id = m_sender->get_id(); + ack.size = M_ACK_SIZE; + + RdmaConnectionPtr conn = shared_from_this(); + + ack.callback = [conn](const Packet& delivered_packet) { + conn->process_ack(delivered_packet); + }; + TimeNs now = Scheduler::get_instance().get_current_time(); + ack.generated_time = now; + ack.sent_time = now; + + ack.ecn_capable_transport = true; + ack.congestion_experienced = false; + + m_receiver->enqueue_packet(ack); +} + +void RdmaConnection::process_ack(const Packet& ack) { + PacketNum ack_num = ack.packet_num; + if (ack_num < m_last_acked_pcn) { + LOG_ERROR( + fmt::format("RDMA connection {}: sender got ack with number " + "smaller than last acked PCN", + m_id)); + return; + } + SizeByte total_data_confirmed = + (ack_num - m_last_acked_pcn) * m_packet_size; + TimeNs now = Scheduler::get_instance().get_current_time(); + + if (m_ctx.last_data_delivery_time.has_value()) { + TimeNs time_from_last_delivery = + now - m_ctx.last_data_delivery_time.value(); + SpeedGbps delivery_rate = + total_data_confirmed / time_from_last_delivery; + m_ctx.delivery_rate_statistics.add_record(delivery_rate); + } + + m_ctx.last_data_delivery_time = now; + while (m_last_acked_pcn < ack_num) { + m_last_acked_pcn++; + confirm_first_unconfirmed_packet(); + } +} + +void RdmaConnection::send_cnp() { + Packet cnp; + cnp.packet_num = m_next_expected_packet_num - 1; + + cnp.sender_id = m_receiver->get_id(); + cnp.sender_port = m_receiver_port; + cnp.receiver_port = m_sender_port; + cnp.receiver_id = m_sender->get_id(); + cnp.size = M_ACK_SIZE; + + RdmaConnectionPtr conn = shared_from_this(); + + cnp.callback = [conn](const Packet& cnp) { conn->process_cnp(cnp); }; + TimeNs now = Scheduler::get_instance().get_current_time(); + cnp.generated_time = now; + cnp.sent_time = now; + + cnp.ecn_capable_transport = true; + cnp.congestion_experienced = true; + + m_receiver->enqueue_packet(cnp); +} + +void RdmaConnection::process_cnp([[maybe_unused]] const Packet& cnp) { + m_dcqcn.on_cnp(); +} + +void RdmaConnection::confirm_first_unconfirmed_packet() { + m_ctx.total_data_delivered += m_packet_size; + if (m_send_queue.empty()) { + LOG_ERROR( + fmt::format("RDMA connection {}: could not confirm packet with " + "empty send queue", + m_id)); + return; + } + const Packet& confirmed = m_send_queue.front(); + utils::Defer defer([this]() { + m_send_queue.pop_front(); + if (m_send_queue.empty()) { + m_dcqcn.stop(); + } + }); + + const DataId& data_id = confirmed.data_id; + auto it = m_data_context_table.find(data_id); + if (it == m_data_context_table.end()) { + LOG_ERROR( + fmt::format("RDMA connection {}: could not find context that " + "connresponds to data {}", + m_id, data_id.to_string())); + return; + } + DataContext& data_ctx = it->second; + data_ctx.delivered += m_packet_size; + if (data_ctx.delivered >= data_ctx.total_size) { + LOG_INFO( + fmt::format("RDMA connection {} delivered data {}; call callback", + m_id, data_id.to_string())); + data_ctx.callback(); + } +} + +void RdmaConnection::send_ack_request() { + Packet ack_request; + ack_request.packet_num = m_next_packet_num++; + + ack_request.sender_id = m_sender->get_id(); + ack_request.sender_port = m_sender_port; + ack_request.receiver_port = m_receiver_port; + ack_request.receiver_id = m_receiver->get_id(); + ack_request.size = ACK_REQUEST_SIZE; + + RdmaConnectionPtr conn = shared_from_this(); + + ack_request.callback = + [conn]([[maybe_unused]] const Packet& delivered_packet) { + conn->process_ack_request(); + }; + TimeNs now = Scheduler::get_instance().get_current_time(); + ack_request.generated_time = now; + ack_request.sent_time = now; + + ack_request.ecn_capable_transport = true; + ack_request.congestion_experienced = false; + m_sender->enqueue_packet(ack_request); +} + +void RdmaConnection::process_ack_request() { send_ack(); } + +} // namespace sim diff --git a/source/network/connection/rdma/rdma_connectrion.hpp b/source/network/connection/rdma/rdma_connectrion.hpp new file mode 100644 index 0000000000..8f7718874d --- /dev/null +++ b/source/network/connection/rdma/rdma_connectrion.hpp @@ -0,0 +1,123 @@ +#pragma once +#include +#include + +#include "../i_connection.hpp" +#include "network/connection/flow/flow_four_tuple.hpp" +#include "network/connection/flow/packet.hpp" +#include "rdma_params.hpp" +#include "topology/device/host.hpp" + +namespace sim { + +class RdmaConnection; + +using RdmaConnectionPtr = std::shared_ptr; + +class RdmaConnection : public IConnection, + public std::enable_shared_from_this { +public: + static RdmaConnectionPtr create_shared(const RdmaParams& a_params); + + [[nodiscard]] virtual utils::StrExpected send_data( + Data data, OnDeliveryCallback callback) final; + + ConnectionContext get_context() const final; + + virtual MetricsTable get_metrics_table() const final; + + virtual void write_inner_metrics( + std::filesystem::path output_dir) const final; + + virtual const Id& get_id() const final; + +private: + RdmaConnection(const RdmaParams& a_params); + + void schedule_ack_timer(); + + void on_ack_timer(); + + void on_retry_timout(); + + void schedule_retry_timout(); + + void retransmit_packets(); + + void start_data_sending(); + + void schedule_data_send(); + + void send_next_data_packet(); + + Packet create_data_packet(const Data& data); + + void process_data_packet(const Packet& data); + + void process_expected_data_packet(); + + void send_nak(); + + void process_nak(const Packet& nak); + + void send_ack(); + + void process_ack(const Packet& ack); + + void send_cnp(); + + void process_cnp(const Packet& cnp); + + void confirm_first_unconfirmed_packet(); + + void send_ack_request(); + + void process_ack_request(); + + ConnectionContext m_ctx; + Id m_id; + DCQCN m_dcqcn; + + // --------------------sender part-------------------- + static constexpr SizeByte ACK_REQUEST_SIZE = SizeByte(1ul); + std::shared_ptr m_sender; + Port m_sender_port; + + SizeByte m_packet_size; + TimeNs m_retry_timout = TimeNs(500000); + + // Invariant: packet_num of first packet in this queue is equal to + // m_last_acked_pcn + std::deque m_send_queue; + + uint32_t m_send_window; + + // number of first packet that was not send + PacketNum m_pcn = 1; + PacketNum m_last_acked_pcn = 0; + PacketNum m_next_packet_num = 1; + + struct DataContext { + SizeByte total_size; + SizeByte sent; + SizeByte delivered; + OnDeliveryCallback callback; + }; + std::map m_data_context_table; + + // --------------------receiver part-------------------- + std::shared_ptr m_receiver; + Port m_receiver_port; + uint32_t m_data_packets_on_receiver = 0; + + uint32_t m_ack_threshold; + PacketNum m_next_expected_packet_num = 1; + static constexpr SizeByte M_ACK_SIZE = SizeByte(1ul); + static constexpr SizeByte M_NAK_SIZE = M_ACK_SIZE; + + TimeNs m_ack_receiver_timout = TimeNs(500000); + TimeNs m_last_ack_send = TimeNs(0); + bool m_receiver_started = false; +}; + +} // namespace sim diff --git a/source/network/connection/rdma/rdma_params.hpp b/source/network/connection/rdma/rdma_params.hpp new file mode 100644 index 0000000000..c8c8a972a0 --- /dev/null +++ b/source/network/connection/rdma/rdma_params.hpp @@ -0,0 +1,15 @@ +#pragma once +#include "dcqcn/dcqcn.hpp" +#include "network/connection/flow/flow_four_tuple.hpp" + +namespace sim { + +struct RdmaParams { + Id id; + DCQCN dcqcn; + FlowFourTuple ft; + SizeByte packet_size = SizeByte(1500ul); + uint32_t send_window = 256; + uint32_t ack_threshold = 32; +}; +} // namespace sim diff --git a/source/parser/network/connection/connection_parser.cpp b/source/parser/network/connection/connection_parser.cpp index 95bacf711d..5a39a2780d 100644 --- a/source/parser/network/connection/connection_parser.cpp +++ b/source/parser/network/connection/connection_parser.cpp @@ -2,6 +2,7 @@ #include "mplb/mplb_parser.hpp" #include "network/connection/connection.hpp" +#include "rdma_connection_parser.hpp" #include "utils/identifiable.hpp" namespace sim { @@ -25,6 +26,8 @@ std::shared_ptr parse_i_connection( params["type"].value_or_throw().as_or_throw(); if (type == "mplb-connection") { return parse_mplb_connection(sender, receiver, params, connection_id); + } else if (type == "rdma") { + return parse_rdma_connection(sender, receiver, params, connection_id); } throw params.create_parsing_error( fmt::format("Unsupported connection type: {}", type)); diff --git a/source/parser/network/connection/dcqcn_parser.cpp b/source/parser/network/connection/dcqcn_parser.cpp new file mode 100644 index 0000000000..a13e92fc87 --- /dev/null +++ b/source/parser/network/connection/dcqcn_parser.cpp @@ -0,0 +1,76 @@ +#include "dcqcn_parser.hpp" + +#include "parser/parse_utils.hpp" + +namespace sim { +DCQCN parse_dcqcn(const ConfigNodeWithPreset& node) { + ParamsDQCCN params; + + if (auto start_rate_node = node["start_target_rate"]) { + params.start_target_rate = parse_speed(start_rate_node->get_node()); + } + + // -------- Rate increment -------- + if (auto rpg_time_reset_node = node["rpg_time_reset"]) { + params.rpg_time_reset = parse_time(rpg_time_reset_node->get_node()); + } + + if (auto rpg_byte_reset_node = node["rpg_byte_reset"]) { + params.rpg_byte_reset = parse_size(rpg_byte_reset_node->get_node()); + } + + if (auto rpg_threshold_node = node["rpg_threshold"]) { + params.rpg_threshold = rpg_threshold_node->as_or_throw(); + } + + if (auto rpg_ai_rate_node = node["rpg_ai_rate"]) { + params.rpg_ai_rate = parse_speed(rpg_ai_rate_node->get_node()); + } + + if (auto rpg_hai_rate_node = node["rpg_hai_rate"]) { + params.rpg_hai_rate = parse_speed(rpg_hai_rate_node->get_node()); + } + + // -------- Alpha update -------- + if (auto initial_alpha_node = node["initial_alpha_value"]) { + params.initial_alpha_value = initial_alpha_node->as_or_throw(); + } + + if (auto dce_tcp_g_node = node["dce_tcp_g"]) { + params.dce_tcp_g = dce_tcp_g_node->as_or_throw(); + } + + if (auto dce_tcp_rtt_node = node["dce_tcp_rtt"]) { + params.dce_tcp_rtt = parse_time(dce_tcp_rtt_node->get_node()); + } + + // -------- Rate decrement -------- + if (auto rate_reduce_period_node = node["rate_reduce_monitor_period"]) { + params.rate_reduce_monitor_period = + parse_time(rate_reduce_period_node->get_node()); + } + + if (auto first_cnp_rate_node = node["rate_to_set_on_first_cnp"]) { + params.rate_to_set_on_first_cnp = + parse_speed(first_cnp_rate_node->get_node()); + } + + if (auto clamp_tgt_rate_node = node["clamp_tgt_rate"]) { + params.clamp_tgt_rate = clamp_tgt_rate_node->as_or_throw(); + } + + if (auto rpg_gd_node = node["rpg_gd"]) { + params.rpg_gd = rpg_gd_node->as_or_throw(); + } + + if (auto rpg_min_rate_node = node["rpg_min_rate"]) { + params.rpg_min_rate = parse_speed(rpg_min_rate_node->get_node()); + } + + if (auto rpg_min_dec_fac_node = node["rpg_min_dec_fac"]) { + params.rpg_min_dec_fac = rpg_min_dec_fac_node->as_or_throw(); + } + + return DCQCN(params); +} +} // namespace sim diff --git a/source/parser/network/connection/dcqcn_parser.hpp b/source/parser/network/connection/dcqcn_parser.hpp new file mode 100644 index 0000000000..5f75f668e1 --- /dev/null +++ b/source/parser/network/connection/dcqcn_parser.hpp @@ -0,0 +1,7 @@ +#pragma once +#include "network/connection/rdma/dcqcn/dcqcn.hpp" +#include "parser/config_reader/config_node_with_preset.hpp" + +namespace sim { +DCQCN parse_dcqcn(const ConfigNodeWithPreset& node); +} \ No newline at end of file diff --git a/source/parser/network/connection/mplb/path-chooser/flow/flow_parser.cpp b/source/parser/network/connection/mplb/path-chooser/flow/flow_parser.cpp index 3de667899e..513bd2b7eb 100644 --- a/source/parser/network/connection/mplb/path-chooser/flow/flow_parser.cpp +++ b/source/parser/network/connection/mplb/path-chooser/flow/flow_parser.cpp @@ -67,8 +67,15 @@ std::shared_ptr parse_tcp_flow(const ConfigNodeWithPreset& flow_node, TcpFlowMetricsFilters metrics_flags = (metrics_flags_node ? parse_metrics_flags(metrics_flags_node.value()) : TcpFlow::DEFAULT_METRICS_FLAGS); - - EndpointPorts ports = generate_ports(); + EndpointPorts ports; + if (auto exp_ports_nod = flow_node["ports"]) { + auto ports_node = exp_ports_nod.value(); + ports.sender_port = ports_node["sender"].as().value_or_throw(); + ports.receiver_port = + ports_node["receiver"].as().value_or_throw(); + } else { + ports = generate_ports(); + } return TcpFlow::create_shared(flow_node.get_name_or_throw(), FlowFourTuple(endpoints, ports), ecn_capable, diff --git a/source/parser/network/connection/rdma_connection_parser.cpp b/source/parser/network/connection/rdma_connection_parser.cpp new file mode 100644 index 0000000000..3267f1407a --- /dev/null +++ b/source/parser/network/connection/rdma_connection_parser.cpp @@ -0,0 +1,47 @@ +#include "rdma_connection_parser.hpp" + +#include + +#include "dcqcn_parser.hpp" +#include "parser/parse_utils.hpp" + +namespace sim { + +static EndpointPorts generate_ports() { + // static constexpr size_t RANDOM_SEED = 42; + // static std::mt19937 rnd(RANDOM_SEED); + + // static constexpr size_t MAX_PORT = 5000; + + // static std::uniform_int_distribution range(0, MAX_PORT); + // return EndpointPorts(range(rnd), range(rnd)); + return EndpointPorts{0, 1}; +} + +RdmaConnectionPtr parse_rdma_connection(std::shared_ptr sender, + std::shared_ptr receiver, + const ConfigNodeWithPreset& params, + const Id& connection_id) { + static const ConfigNodeWithPreset& dcqcn_node = + params["dcqcn"].value_or_throw(); + + DCQCN dcqcn = parse_dcqcn(dcqcn_node); + + EndpointPorts ports; + if (auto exp_ports_node = params["ports"]) { + auto ports_node = exp_ports_node.value(); + ports.sender_port = ports_node["sender"].as().value_or_throw(); + ports.receiver_port = + ports_node["receiver"].as().value_or_throw(); + } else { + ports = generate_ports(); + } + + FlowFourTuple ft(Endpoints(sender, receiver), ports); + + RdmaParams rdma_params{connection_id, dcqcn, ft}; + + return RdmaConnection::create_shared(rdma_params); +} + +} // namespace sim diff --git a/source/parser/network/connection/rdma_connection_parser.hpp b/source/parser/network/connection/rdma_connection_parser.hpp new file mode 100644 index 0000000000..e6b04223b7 --- /dev/null +++ b/source/parser/network/connection/rdma_connection_parser.hpp @@ -0,0 +1,12 @@ +#pragma once +#include "network/connection/rdma/rdma_connectrion.hpp" +#include "parser/config_reader/config_node_with_preset.hpp" + +namespace sim { + +RdmaConnectionPtr parse_rdma_connection(std::shared_ptr sender, + std::shared_ptr receiver, + const ConfigNodeWithPreset& params, + const Id& connection_id); + +} \ No newline at end of file diff --git a/source/parser/topology/leaf_spine_topology_parser.cpp b/source/parser/topology/leaf_spine_topology_parser.cpp index 6ce76569af..e848bc8178 100644 --- a/source/parser/topology/leaf_spine_topology_parser.cpp +++ b/source/parser/topology/leaf_spine_topology_parser.cpp @@ -47,7 +47,7 @@ LeafSpineTopologyContext parse_leaf_spine_topology_context( const ConfigNodeWithPreset& leaf_spine_links = links["leaf-spine"].value_or_throw(); const ConfigNodeWithPreset& host_leaf_links = - links["leaf-spine"].value_or_throw(); + links["host-leaf"].value_or_throw(); LeafSpineParams params{packet_spraying, spine_switches, leaf_switches, hosts, leaf_spine_links, host_leaf_links}; @@ -147,4 +147,4 @@ LeafSpineTopologyContext create_leaf_spine_topology_context( return ctx; } -} // namespace sim \ No newline at end of file +} // namespace sim diff --git a/source/topology/device/hashers/ecmp_hasher.cpp b/source/topology/device/hashers/ecmp_hasher.cpp index e491a726dc..03b56a5429 100644 --- a/source/topology/device/hashers/ecmp_hasher.cpp +++ b/source/topology/device/hashers/ecmp_hasher.cpp @@ -13,7 +13,9 @@ static inline std::size_t mix(std::size_t h) { } static inline void hash_combine(std::size_t& seed, std::size_t value) { - seed ^= mix(value) + 0x9e3779b97f4a7c15ULL + (seed << 6) + (seed >> 2); + static constexpr std::size_t BIT_MASK = 0x99999989; + seed ^= (mix(value) ^ BIT_MASK) + 0x9e3779b97f4a7c15ULL + (seed << 6) + + (seed >> 2); } std::uint32_t ECMPHasher::get_hash(const Packet& packet) { diff --git a/source/topology/device/host.cpp b/source/topology/device/host.cpp index 56a5e59731..af99b1b935 100644 --- a/source/topology/device/host.cpp +++ b/source/topology/device/host.cpp @@ -67,7 +67,7 @@ void Host::process() { if (packet.receiver_id == get_id()) { packet.callback(packet); } else { - LOG_WARN( + LOG_ERROR( "Host {}: arrived packet {} which destination differs from this " "host; use routing " "table to send it further"); @@ -88,8 +88,6 @@ void Host::process() { next_link->schedule_arrival(packet); } - - return; } void Host::send_packet() { @@ -115,7 +113,7 @@ void Host::send_packet() { auto next_link = get_link_to_destination(data_packet); if (next_link == nullptr) { - LOG_WARN("Link to send data packet does not exist"); + LOG_ERROR("Link to send data packet does not exist"); return; } diff --git a/source/topology/device/switch.cpp b/source/topology/device/switch.cpp index a27b5bb47c..5441cfad0f 100644 --- a/source/topology/device/switch.cpp +++ b/source/topology/device/switch.cpp @@ -26,7 +26,7 @@ void Switch::process() { std::shared_ptr link = next_inlink(); if (link == nullptr) { - LOG_WARN("No next inlink"); + LOG_ERROR("No next inlink"); return; } @@ -48,7 +48,7 @@ void Switch::process() { std::shared_ptr next_link = get_link_to_destination(packet); if (next_link == nullptr) { - LOG_WARN(fmt::format( + LOG_ERROR(fmt::format( "Switch {}: no link corresponds to destination device for packet " "{}", get_id(), packet.to_string())); @@ -84,8 +84,6 @@ void Switch::process() { // TODO: increase total_processing_time correctly next_link->schedule_arrival(packet); - - return; } } // namespace sim diff --git a/test/connection/rdma/dcqcn_test.cpp b/test/connection/rdma/dcqcn_test.cpp index 12b6421f72..4064b27f99 100644 --- a/test/connection/rdma/dcqcn_test.cpp +++ b/test/connection/rdma/dcqcn_test.cpp @@ -1,4 +1,4 @@ -#include "network/connection/mplb/rdma/dcqcn.hpp" +#include "network/connection/rdma/dcqcn/dcqcn.hpp" #include