Program Listing for File LegacyRefine.h¶
↰ Return to documentation for file (src/partition/refine/strategy/LegacyRefine.h)
#ifndef PARTITION_REFINE_STRATEGY_LEGACYREFINE_H_
#define PARTITION_REFINE_STRATEGY_LEGACYREFINE_H_
#include "refine/bucket/MoveBucket.h"
#include "refine/engine/GainEvaluator.h"
#include "refine/engine/MoveApplier.h"
#include "refine/strategy/IRefineStrategy.h"
class Refine {
protected:
int max_hop;
int large_net_threshold;
double penalty;
vector<vector<int>> &cut_weights;
const fpga &fpgas;
TimingRefineConfig timing_cfg;
GainEvaluatorContext makeGainEvalContext() const
{
return GainEvaluatorContext{
max_hop, large_net_threshold, penalty, cut_weights, fpgas, timing_cfg};
}
MoveApplierContext makeMoveApplierContext()
{
return MoveApplierContext{large_net_threshold, cut_weights, fpgas,
timing_cfg};
}
Gain pickMove(PerPartBucketSet &buckets, const graph &finest,
const vector<VectorXi> &occupied_resources);
template <typename PickFn, typename AcceptFn, typename UpdateFn,
typename ClearFn>
double runFMLoop(int max_move, int max_neg_move, const graph &finest,
vector<int> &parts, vector<VectorXi> &occupied_resources,
vector<bool> &visited_vertices_flag,
vector<NetPartition> &partition, PickFn pickFn,
AcceptFn acceptFn, UpdateFn updateFn, ClearFn clearFn)
{
vector<Gain> moves_trace;
double total_delta_gain = 0.0;
double best_gain = 0.0;
int best_vertex_id = -1;
int neg_move_count = 0;
for (int i = 0; i < max_move; i++) {
const Gain candidate = pickFn();
const int vertex = candidate.get_id();
if (vertex < 0)
break;
if (candidate.get_gain() < 0) {
if (++neg_move_count > max_neg_move)
break;
} else {
neg_move_count = 0;
}
acceptFn(candidate, moves_trace, total_delta_gain);
updateFn(vertex);
if (total_delta_gain >= best_gain) {
best_gain = total_delta_gain;
best_vertex_id = vertex;
}
}
// 回滚最优位置之后的所有移动。
auto ctx = makeMoveApplierContext();
for (auto it = moves_trace.rbegin(); it != moves_trace.rend(); ++it) {
if (it->get_id() == best_vertex_id)
break;
MoveStateApplierCore::cancelMove(ctx, *it, finest, visited_vertices_flag,
parts, occupied_resources, partition);
}
moves_trace.clear();
clearFn();
return best_gain;
}
public:
Refine(int max_hop, int large_net_threshold, double penalty,
vector<vector<int>> &cut_weights, const fpga &fpgas,
const TimingRefineConfig &timing_cfg)
: max_hop(max_hop),
large_net_threshold(large_net_threshold),
penalty(penalty),
cut_weights(cut_weights),
fpgas(fpgas),
timing_cfg(timing_cfg)
{
}
};
class PMRefine : public Refine, public IRefineStrategy {
private:
int max_move;
int max_neg_move;
public:
PMRefine(int max_hop, int large_net_threshold, double penalty,
vector<vector<int>> &cut_weights, const fpga &fpgas,
const TimingRefineConfig &timing_cfg, int max_move, int max_neg_move)
: Refine(max_hop, large_net_threshold, penalty, cut_weights, fpgas,
timing_cfg),
max_move(max_move),
max_neg_move(max_neg_move)
{
}
const char *name() const override;
double run(RefinePassContext &context) override;
double refinement(const graph &finest, vector<int> &parts,
vector<VectorXi> &occupied_resources,
vector<bool> &visited_vertices_flag,
vector<NetPartition> &partition);
private:
double pairFM(const graph &finest, vector<int> &parts,
vector<VectorXi> &occupied_resources,
vector<bool> &visited_vertices_flag,
vector<NetPartition> &partition, PerPartBucketSet &buckets,
const pair<int, int> &match);
};
class DSFM_M_Refine : public Refine, public IRefineStrategy {
private:
int max_move;
int max_neg_move;
public:
DSFM_M_Refine(int max_hop, int large_net_threshold, double penalty,
vector<vector<int>> &cut_weights, const fpga &fpgas,
const TimingRefineConfig &timing_cfg, int max_move,
int max_neg_move)
: Refine(max_hop, large_net_threshold, penalty, cut_weights, fpgas,
timing_cfg),
max_move(max_move),
max_neg_move(max_neg_move)
{
}
const char *name() const override;
double run(RefinePassContext &context) override;
double refinement(const graph &finest, vector<int> &parts,
vector<VectorXi> &occupied_resources,
vector<bool> &visited_vertices_flag,
vector<NetPartition> &partition);
Gain pickMove_DSFM(PerPartBucketSet &buckets, const graph &finest,
const vector<VectorXi> &occupied_resources,
vector<vector<Gain>> &violating);
void acceptMove_DSFM(const Gain &gain_cell, PerPartBucketSet &buckets,
vector<Gain> &moves_trace, double &total_delta_gain,
vector<bool> &visited_vertices_flag, const graph &finest,
vector<int> &parts, vector<VectorXi> &occupied_resources,
vector<NetPartition> &partition,
vector<vector<Gain>> &violating);
};
class DSFM_S_Refine : public Refine, public IRefineStrategy {
private:
int max_move;
int max_neg_move;
public:
DSFM_S_Refine(int max_hop, int large_net_threshold, double penalty,
vector<vector<int>> &cut_weights, const fpga &fpgas,
const TimingRefineConfig &timing_cfg, int max_move,
int max_neg_move)
: Refine(max_hop, large_net_threshold, penalty, cut_weights, fpgas,
timing_cfg),
max_move(max_move),
max_neg_move(max_neg_move)
{
}
const char *name() const override;
double run(RefinePassContext &context) override;
double refinement(const graph &finest, vector<int> &parts,
vector<VectorXi> &occupied_resources,
vector<bool> &visited_vertices_flag,
vector<NetPartition> &partition);
Gain pickMove_DSFM(GlobalMoveBucket &buckets, const graph &finest,
const vector<VectorXi> &occupied_resources,
vector<Gain> &violating);
void acceptMove_DSFM(const Gain &gain_cell, GlobalMoveBucket &buckets,
vector<Gain> &moves_trace, double &total_delta_gain,
vector<bool> &visited_vertices_flag, const graph &finest,
vector<int> &parts, vector<VectorXi> &occupied_resources,
vector<NetPartition> &partition,
vector<Gain> &violating);
};
class FMRefine : public Refine, public IRefineStrategy {
private:
int max_move;
int max_neg_move;
public:
FMRefine(int max_hop, int large_net_threshold, double penalty,
vector<vector<int>> &cut_weights, const fpga &fpgas,
const TimingRefineConfig &timing_cfg, int max_move, int max_neg_move)
: Refine(max_hop, large_net_threshold, penalty, cut_weights, fpgas,
timing_cfg),
max_move(max_move),
max_neg_move(max_neg_move)
{
}
const char *name() const override;
double run(RefinePassContext &context) override;
double refinement(const graph &finest, vector<int> &parts,
vector<VectorXi> &occupied_resources,
vector<bool> &visited_vertices_flag,
vector<NetPartition> &partition);
};
class OldRefine : public Refine, public IRefineStrategy {
private:
bool has_fix;
bool enable_parallel_refine_;
std::mt19937 gen_;
public:
OldRefine(int max_hop, int large_net_threshold, double penalty,
vector<vector<int>> &cut_weights, const fpga &fpgas,
const TimingRefineConfig &timing_cfg, bool has_fix,
bool has_timing = false, bool enable_parallel_refine = false,
int thread_order = 0, int current_level = 0, int multilevel_id = 0)
: Refine(max_hop, large_net_threshold, penalty, cut_weights, fpgas,
timing_cfg),
has_fix(has_fix),
enable_parallel_refine_(enable_parallel_refine)
{
if (has_timing) {
const unsigned int seed_base =
static_cast<unsigned int>(thread_order + 1) ^
static_cast<unsigned int>(current_level + 1) * 0x9e3779b9u ^
static_cast<unsigned int>(multilevel_id + 1) * 0x85ebca6bu;
gen_.seed(seed_base);
}
}
const char *name() const override;
double run(RefinePassContext &context) override;
double refinement(const graph &finest, vector<int> &parts,
vector<VectorXi> &occupied_resources,
vector<NetPartition> &partition, int seed);
double parallelRefinement(const graph &finest, vector<int> &parts,
vector<VectorXi> &occupied_resources,
vector<NetPartition> &partition, int seed);
void updateFullTimingByCut(const graph &finest, vector<int> &parts);
};
class GreedyRefine : public Refine, public IRefineStrategy {
private:
bool has_fix;
bool checkBalanceHyper(const vector<VectorXi> &occupied_resources,
const graph &finest, const int &edge,
vector<int> &parts, int to);
public:
GreedyRefine(int max_hop, int large_net_threshold, double penalty,
vector<vector<int>> &cut_weights, const fpga &fpgas,
const TimingRefineConfig &timing_cfg, bool has_fix)
: Refine(max_hop, large_net_threshold, penalty, cut_weights, fpgas,
timing_cfg),
has_fix(has_fix)
{
}
const char *name() const override;
double run(RefinePassContext &context) override;
double refinement(const graph &finest, vector<int> &parts,
vector<VectorXi> &occupied_resources,
vector<NetPartition> &partition);
};
#endif