<commit_before>/*
 * Copyright 2016 Hewlett Packard Enterprise Development LP
 *
 * Licensed under the Apache License, Version 2.0 (the 'License');
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include "network/hierarchicalhyperx/ProgressiveAdaptiveRandomRoutingAlgorithm.h"

#include <strop/strop.h>

#include <cassert>
#include <unordered_set>
#include <unordered_map>
#include <set>

#include "types/Message.h"
#include "types/Packet.h"
#include "network/hierarchicalhyperx/util.h"

namespace HierarchicalHyperX {
  u32 ProgressiveAdaptiveRandomRoutingAlgorithm::numMinimalRoutes_;
  u32 ProgressiveAdaptiveRandomRoutingAlgorithm::numNonMinimalRoutes_;
ProgressiveAdaptiveRandomRoutingAlgorithm::
  ProgressiveAdaptiveRandomRoutingAlgorithm(
    const std::string& _name, const Component* _parent, Router* _router,
    u64 _latency, u32 _baseVc, u32 _numVcs,
    const std::vector<u32>& _globalDimensionWidths,
    const std::vector<u32>& _globalDimensionWeights,
    const std::vector<u32>& _localDimensionWidths,
    const std::vector<u32>& _localDimensionWeights,
    u32 _concentration, u32 _globalLinksPerRouter,
    bool _randomGroup, f64 _bias, f64 _threshold)
    : ValiantRoutingAlgorithm
      (_name, _parent,  _router, _latency, _baseVc, _numVcs,
       _globalDimensionWidths,
       _globalDimensionWeights, _localDimensionWidths, _localDimensionWeights,
       _concentration, _globalLinksPerRouter, _randomGroup),
      bias_(_bias), threshold_(_threshold) {
  assert(numVcs_ >= 2 * globalDimWidths_.size() + 3);
  ProgressiveAdaptiveRandomRoutingAlgorithm::numMinimalRoutes_ = 0;
  ProgressiveAdaptiveRandomRoutingAlgorithm::numNonMinimalRoutes_ = 0;
}

ProgressiveAdaptiveRandomRoutingAlgorithm::
  ~ProgressiveAdaptiveRandomRoutingAlgorithm() {
  printf("number of Minimal routes %u \n",
         ProgressiveAdaptiveRandomRoutingAlgorithm::numMinimalRoutes_);
  printf("number of Non Minimal routes %u \n",
         ProgressiveAdaptiveRandomRoutingAlgorithm::numNonMinimalRoutes_);
}

void ProgressiveAdaptiveRandomRoutingAlgorithm::processRequest(
    Flit* _flit, RoutingAlgorithm::Response* _response) {
  // ex: [c,1,...,m,1,...,n]
  const std::vector<u32>* destinationAddress =
      _flit->packet()->message()->getDestinationAddress();
  Packet* packet = _flit->packet();

  if (packet->getRoutingExtension() == nullptr) {
    RoutingInfo* ri = new RoutingInfo();
    ri->intermediateAddress = nullptr;
    ri->localDst = nullptr;
    ri->localDstPort = nullptr;
    ri->localDerouteCount = 0;
    ri->globalHopCount = 0;
    ri->intermediateDone = false;
    ri->valiantMode = false;
    packet->setRoutingExtension(ri);
  }
  RoutingInfo* ri = reinterpret_cast<RoutingInfo*>(
      packet->getRoutingExtension());

  std::unordered_set<u32> outputPorts;
  // routing depends on mode
  if (ri->valiantMode == false) {
    outputPorts = ProgressiveAdaptiveRandomRoutingAlgorithm::routing
      (_flit, *destinationAddress);
    assert(outputPorts.size() >= 1);
  } else {
    // use Valiant routing
    assert(ri->intermediateAddress != nullptr);

    outputPorts = ValiantRoutingAlgorithm::routing(
                    _flit, *destinationAddress, randomGroup_);
    assert(outputPorts.size() >= 1);
  }

  // reset localDst once in a new group
  if (*outputPorts.begin() >= getPortBase(concentration_, localDimWidths_,
                                          localDimWeights_)) {
    ri->globalHopCount++;
    // delete local router
    if (ri->localDst != nullptr) {
      delete reinterpret_cast<const std::vector<u32>*>(ri->localDst);
    }
    ri->localDst = nullptr;
    if (ri->localDstPort != nullptr) {
      delete reinterpret_cast<const std::vector<u32>*>(ri->localDstPort);
    }
    ri->localDstPort = nullptr;
    packet->setRoutingExtension(ri);
    /* if (router_->address() == hardAdd) {
      for (u32 vc=0; vc < numVcs_; vc++) {
        printf("vc = %u, uitlization = %f\n", vc,
             router_->congestionStatus(*outputPorts.begin(), vc));
      }
      }*/
  }

  // figure out which VC set to use
  u32 vcSet;
  if (ri->globalHopCount == 0) {
    if (ri->valiantMode == false) {
      vcSet = 0;
    } else {
      vcSet = 1;
    }
  } else {
    if (ri->valiantMode == true) {
      if (ri->intermediateDone == false) {
        vcSet = 1 + ri->globalHopCount;
      } else {
        vcSet = 2 + ri->globalHopCount;
      }
    } else {
      vcSet = 1 + ri->globalHopCount;
    }
  }


  // format the response
  for (auto it = outputPorts.cbegin(); it != outputPorts.cend(); ++it) {
    u32 outputPort = *it;
    if (outputPort < concentration_) {
      for (u32 vc = baseVc_; vc < baseVc_ + numVcs_; vc++) {
        _response->add(outputPort, vc);
      }
      assert(_response->size() > 0);
      // delete the routing extension
      delete reinterpret_cast<const std::vector<u32>*>(ri->localDst);
      delete reinterpret_cast<const std::vector<u32>*>(ri->localDstPort);
      delete reinterpret_cast<const std::vector<u32>*>(ri->intermediateAddress);
      delete ri;
      packet->setRoutingExtension(nullptr);
    } else {
      for (u32 vc = baseVc_ + vcSet; vc < baseVc_ + numVcs_;
           vc += 2 * globalDimWidths_.size() + 3) {
        _response->add(outputPort, vc);
   /* if (packet->message()->getTransaction() == 1500) {
       printf("Message %u at router %s, using vc %u\n", packet->message()->id(),
                strop::vecString<u32>(router_->address()).c_str(), vc);
     } */
      }
    }<commit_msg>correct VC assignment to reflect strict ordering in PAR<commit_after>/*
 * Copyright 2016 Hewlett Packard Enterprise Development LP
 *
 * Licensed under the Apache License, Version 2.0 (the 'License');
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include "network/hierarchicalhyperx/ProgressiveAdaptiveRandomRoutingAlgorithm.h"

#include <strop/strop.h>

#include <cassert>
#include <unordered_set>
#include <unordered_map>
#include <set>

#include "types/Message.h"
#include "types/Packet.h"
#include "network/hierarchicalhyperx/util.h"

namespace HierarchicalHyperX {
  u32 ProgressiveAdaptiveRandomRoutingAlgorithm::numMinimalRoutes_;
  u32 ProgressiveAdaptiveRandomRoutingAlgorithm::numNonMinimalRoutes_;
ProgressiveAdaptiveRandomRoutingAlgorithm::
  ProgressiveAdaptiveRandomRoutingAlgorithm(
    const std::string& _name, const Component* _parent, Router* _router,
    u64 _latency, u32 _baseVc, u32 _numVcs,
    const std::vector<u32>& _globalDimensionWidths,
    const std::vector<u32>& _globalDimensionWeights,
    const std::vector<u32>& _localDimensionWidths,
    const std::vector<u32>& _localDimensionWeights,
    u32 _concentration, u32 _globalLinksPerRouter,
    bool _randomGroup, f64 _bias, f64 _threshold)
    : ValiantRoutingAlgorithm
      (_name, _parent,  _router, _latency, _baseVc, _numVcs,
       _globalDimensionWidths,
       _globalDimensionWeights, _localDimensionWidths, _localDimensionWeights,
       _concentration, _globalLinksPerRouter, _randomGroup),
      bias_(_bias), threshold_(_threshold) {
  assert(numVcs_ >= 2 * globalDimWidths_.size() + 3);
  ProgressiveAdaptiveRandomRoutingAlgorithm::numMinimalRoutes_ = 0;
  ProgressiveAdaptiveRandomRoutingAlgorithm::numNonMinimalRoutes_ = 0;
}

ProgressiveAdaptiveRandomRoutingAlgorithm::
  ~ProgressiveAdaptiveRandomRoutingAlgorithm() {
  printf("number of Minimal routes %u \n",
         ProgressiveAdaptiveRandomRoutingAlgorithm::numMinimalRoutes_);
  printf("number of Non Minimal routes %u \n",
         ProgressiveAdaptiveRandomRoutingAlgorithm::numNonMinimalRoutes_);
}

void ProgressiveAdaptiveRandomRoutingAlgorithm::processRequest(
    Flit* _flit, RoutingAlgorithm::Response* _response) {
  // ex: [c,1,...,m,1,...,n]
  const std::vector<u32>* destinationAddress =
      _flit->packet()->message()->getDestinationAddress();
  Packet* packet = _flit->packet();

  if (packet->getRoutingExtension() == nullptr) {
    RoutingInfo* ri = new RoutingInfo();
    ri->intermediateAddress = nullptr;
    ri->localDst = nullptr;
    ri->localDstPort = nullptr;
    ri->localDerouteCount = 0;
    ri->globalHopCount = 0;
    ri->intermediateDone = false;
    ri->valiantMode = false;
    packet->setRoutingExtension(ri);
  }
  RoutingInfo* ri = reinterpret_cast<RoutingInfo*>(
      packet->getRoutingExtension());

  std::unordered_set<u32> outputPorts;
  // routing depends on mode
  if (ri->valiantMode == false) {
    outputPorts = ProgressiveAdaptiveRandomRoutingAlgorithm::routing
      (_flit, *destinationAddress);
    assert(outputPorts.size() >= 1);
  } else {
    // use Valiant routing
    assert(ri->intermediateAddress != nullptr);

    outputPorts = ValiantRoutingAlgorithm::routing(
                    _flit, *destinationAddress, randomGroup_);
    assert(outputPorts.size() >= 1);
  }

  // reset localDst once in a new group
  if (*outputPorts.begin() >= getPortBase(concentration_, localDimWidths_,
                                          localDimWeights_)) {
    ri->globalHopCount++;
    // delete local router
    if (ri->localDst != nullptr) {
      delete reinterpret_cast<const std::vector<u32>*>(ri->localDst);
    }
    ri->localDst = nullptr;
    if (ri->localDstPort != nullptr) {
      delete reinterpret_cast<const std::vector<u32>*>(ri->localDstPort);
    }
    ri->localDstPort = nullptr;
    packet->setRoutingExtension(ri);
    /* if (router_->address() == hardAdd) {
      for (u32 vc=0; vc < numVcs_; vc++) {
        printf("vc = %u, uitlization = %f\n", vc,
             router_->congestionStatus(*outputPorts.begin(), vc));
      }
      }*/
  }

  // figure out which VC set to use
  u32 vcSet;
  if (ri->globalHopCount == 0) {
    if (ri->valiantMode == false) {
      vcSet = 0;
    } else {
      vcSet = 1;
    }
  } else {
    if (ri->valiantMode == true) {
      if (ri->intermediateDone == false) {
        vcSet = 1 + ri->globalHopCount;
      } else {
        vcSet = 2 + ri->globalHopCount;
      }
    } else {
      vcSet = 2 + globalDimWidths_.size() + ri->globalHopCount;
    }
  }


  // format the response
  for (auto it = outputPorts.cbegin(); it != outputPorts.cend(); ++it) {
    u32 outputPort = *it;
    if (outputPort < concentration_) {
      for (u32 vc = baseVc_; vc < baseVc_ + numVcs_; vc++) {
        _response->add(outputPort, vc);
      }
      assert(_response->size() > 0);
      // delete the routing extension
      delete reinterpret_cast<const std::vector<u32>*>(ri->localDst);
      delete reinterpret_cast<const std::vector<u32>*>(ri->localDstPort);
      delete reinterpret_cast<const std::vector<u32>*>(ri->intermediateAddress);
      delete ri;
      packet->setRoutingExtension(nullptr);
    } else {
      for (u32 vc = baseVc_ + vcSet; vc < baseVc_ + numVcs_;
           vc += 2 * globalDimWidths_.size() + 3) {
        _response->add(outputPort, vc);
   /* if (packet->message()->getTransaction() == 1500) {
       printf("Message %u at router %s, using vc %u\n", packet->message()->id(),
                strop::vecString<u32>(router_->address()).c_str(), vc);
     } */
      }
    }
{'fraction_non_alphanumeric': 0.1225276567214214, 'fraction_numerical': 0.014079785450888367, 'mean_word_length': 3.6073359073359073, 'pattern_counts': {'":': 0, '<': 57, '<?xml version=': 0, '>': 149, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '984817', 'n_tokens_mistral': 3852, 'n_tokens_neox': 3703, 'n_words': 845}