Skip to content

Memory clean up to placer #1096

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
5f83798
Move rr node storage behind an object.
litghost Jan 24, 2020
291f0ea
Convert t_rr_node to a fly-weight object.
litghost Jan 24, 2020
3b14cd9
Refactor edge storage.
litghost Jan 26, 2020
0b15b11
Add support for custom allocator to vtr::vector.
litghost Feb 3, 2020
359f142
Split node ptc data away from core storage.
litghost Feb 3, 2020
5c1b331
Rename t_rr_node_storage to t_rr_graph_storage.
litghost Feb 3, 2020
db9eed4
Add comment around state flags.
litghost Feb 3, 2020
eb13bd0
Add missing flag check.
litghost Feb 3, 2020
058192e
Add comments around edge sorting.
litghost Feb 3, 2020
98a6d3e
Used function form of size_t().
litghost Feb 3, 2020
e96a3ba
Integrate schema based reader with edge refactoring.
litghost Feb 5, 2020
9f407fc
Remove sources of garbage during initialization.
litghost Jan 28, 2020
7bbbda0
Assorted small fixes to avoid copies/allocations.
litghost Jan 28, 2020
a31d500
Changes to avoid allocations.
litghost Jan 28, 2020
0d79929
Use vtr::string_view instead of copying strings.
litghost Jan 28, 2020
c91a4f6
Use string view for formula data instead of std::string.
litghost Jan 29, 2020
5783450
Disable heap profiler.
litghost Jan 29, 2020
8c87d17
Refactor count_rr_switches to avoid allocations.
litghost Jan 29, 2020
a3ae48a
Hoist t_routing_cost_map out of inner loop to avoid repeated allocati…
litghost Jan 29, 2020
acf52a3
Refactor build_switchblocks to avoid thrashing heap.
litghost Jan 29, 2020
8fcbad5
Avoid reallocating the heap if not needed.
litghost Jan 29, 2020
a4ab60b
Refactor some routines inside deeply nested loops to avoid reallocation.
litghost Jan 29, 2020
1e128c5
Avoid repeatedly allocating modified_rr_node_inf array.
litghost Jan 29, 2020
c6e7861
Avoid repeatedly allocating structures in the map lookahead.
litghost Jan 29, 2020
2ea538d
Avoid copying equivalent_tiles in is_tile_compatible.
litghost Jan 30, 2020
8a0b7ca
Remove heap profiler logic.
litghost Jan 30, 2020
26eafd1
Run make format.
litghost Jan 30, 2020
9aa4137
Fix GCC 5/6 warning.
litghost Jan 30, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion libs/libarchfpga/src/arch_util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ InstPort::InstPort(std::string str) {
}
}

InstPort::name_index InstPort::parse_name_index(std::string str) {
InstPort::name_index InstPort::parse_name_index(const std::string& str) {
auto open_bracket_pos = str.find("[");
auto close_bracket_pos = str.find("]");
auto colon_pos = str.find(":");
Expand Down
2 changes: 1 addition & 1 deletion libs/libarchfpga/src/arch_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class InstPort {
int high_idx = UNSPECIFIED;
};

name_index parse_name_index(std::string str);
name_index parse_name_index(const std::string& str);

name_index instance_;
name_index port_;
Expand Down
114 changes: 18 additions & 96 deletions libs/libarchfpga/src/expr_eval.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,104 +2,18 @@
#include "arch_error.h"
#include "vtr_util.h"
#include "vtr_math.h"
#include <vector>
#include <stack>
#include <string>
#include <sstream>
#include <cstring> //memset

using std::stack;
using std::string;
using std::stringstream;
using std::vector;

/**** Enums ****/
/* Used to identify the type of symbolic formula object */
typedef enum e_formula_obj {
E_FML_UNDEFINED = 0,
E_FML_NUMBER,
E_FML_BRACKET,
E_FML_COMMA,
E_FML_OPERATOR,
E_FML_NUM_FORMULA_OBJS
} t_formula_obj;

/* Used to identify an operator in a formula */
typedef enum e_operator {
E_OP_UNDEFINED = 0,
E_OP_ADD,
E_OP_SUB,
E_OP_MULT,
E_OP_DIV,
E_OP_MIN,
E_OP_MAX,
E_OP_GCD,
E_OP_LCM,
E_OP_NUM_OPS
} t_operator;

/**** Class Definitions ****/
/* This class is used to represent an object in a formula, such as
* a number, a bracket, an operator, or a variable */
class Formula_Object {
public:
/* indicates the type of formula object this is */
t_formula_obj type;

/* object data, accessed based on what kind of object this is */
union u_Data {
int num; /*for number objects*/
t_operator op; /*for operator objects*/
bool left_bracket; /*for bracket objects -- specifies if this is a left bracket*/

u_Data() { memset(this, 0, sizeof(u_Data)); }
} data;

Formula_Object() {
this->type = E_FML_UNDEFINED;
}

std::string to_string() const {
if (type == E_FML_NUMBER) {
return std::to_string(data.num);
} else if (type == E_FML_BRACKET) {
if (data.left_bracket) {
return "(";
} else {
return ")";
}
} else if (type == E_FML_COMMA) {
return ",";
} else if (type == E_FML_OPERATOR) {
if (data.op == E_OP_ADD) {
return "+";
} else if (data.op == E_OP_SUB) {
return "-";
} else if (data.op == E_OP_MULT) {
return "*";
} else if (data.op == E_OP_DIV) {
return "/";
} else if (data.op == E_OP_MIN) {
return "min";
} else if (data.op == E_OP_MAX) {
return "max";
} else if (data.op == E_OP_GCD) {
return "gcd";
} else if (data.op == E_OP_LCM) {
return "lcm";
} else {
return "???"; //Unkown
}
} else {
return "???"; //Unkown
}
}
};

/*---- Functions for Parsing the Symbolic Formulas ----*/

/* converts specified formula to a vector in reverse-polish notation */
static void formula_to_rpn(const char* formula, const t_formula_data& mydata, vector<Formula_Object>& rpn_output);
static void formula_to_rpn(const char* formula, const t_formula_data& mydata, vector<Formula_Object>& rpn_output, stack<Formula_Object>& op_stack);

static void get_formula_object(const char* ch, int& ichar, const t_formula_data& mydata, Formula_Object* fobj);

Expand Down Expand Up @@ -142,14 +56,15 @@ static bool goto_next_char(int* str_ind, const string& pw_formula, char ch);

/**** Function Implementations ****/
/* returns integer result according to specified non-piece-wise formula and data */
int parse_formula(std::string formula, const t_formula_data& mydata) {
int FormulaParser::parse_formula(std::string formula, const t_formula_data& mydata) {
int result = -1;

/* output in reverse-polish notation */
vector<Formula_Object> rpn_output;
auto& rpn_output = rpn_output_;
rpn_output.clear();

/* now we have to run the shunting-yard algorithm to convert formula to reverse polish notation */
formula_to_rpn(formula.c_str(), mydata, rpn_output);
formula_to_rpn(formula.c_str(), mydata, rpn_output, op_stack_);

/* then we run an RPN parser to get the final result */
result = parse_rpn_vector(rpn_output);
Expand All @@ -171,7 +86,7 @@ int parse_formula(std::string formula, const t_formula_data& mydata) {
*
* {start_0:end_0} formula_0; ... {start_i;end_i} formula_i; ...
*/
int parse_piecewise_formula(const char* formula, const t_formula_data& mydata) {
int FormulaParser::parse_piecewise_formula(const char* formula, const t_formula_data& mydata) {
int result = -1;
int str_ind = 0;
int str_size = 0;
Expand Down Expand Up @@ -283,9 +198,13 @@ static bool goto_next_char(int* str_ind, const string& pw_formula, char ch) {

/* Parses the specified formula using a shunting yard algorithm (see wikipedia). The function's result
* is stored in the rpn_output vector in reverse-polish notation */
static void formula_to_rpn(const char* formula, const t_formula_data& mydata, vector<Formula_Object>& rpn_output) {
stack<Formula_Object> op_stack; /* stack for handling operators and brackets in formula */
Formula_Object fobj; /* for parsing formula objects */
static void formula_to_rpn(const char* formula, const t_formula_data& mydata, vector<Formula_Object>& rpn_output, stack<Formula_Object>& op_stack) {
// Empty op_stack.
while (!op_stack.empty()) {
op_stack.pop();
}

Formula_Object fobj; /* for parsing formula objects */

int ichar = 0;
const char* ch = nullptr;
Expand Down Expand Up @@ -372,7 +291,10 @@ static void get_formula_object(const char* ch, int& ichar, const t_formula_data&
} else {
//A variable
fobj->type = E_FML_NUMBER;
fobj->data.num = mydata.get_var_value(var_name);
fobj->data.num = mydata.get_var_value(
vtr::string_view(
var_name.data(),
var_name.size()));
}

ichar += (id_len - 1); //-1 since ichar is incremented at end of loop in formula_to_rpn()
Expand Down Expand Up @@ -764,7 +686,7 @@ static int identifier_length(const char* str) {
}

/* checks if the specified formula is piece-wise defined */
bool is_piecewise_formula(const char* formula) {
bool FormulaParser::is_piecewise_formula(const char* formula) {
bool result = false;
/* if formula is piecewise, we expect '{' to be the very first character */
if ('{' == formula[0]) {
Expand Down
131 changes: 121 additions & 10 deletions libs/libarchfpga/src/expr_eval.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,145 @@
#define EXPR_EVAL_H
#include <map>
#include <string>
#include <vector>
#include <stack>
#include "arch_error.h"
#include <cstring>

#include "vtr_string_view.h"
#include "vtr_flat_map.h"

/**** Structs ****/

class t_formula_data {
public:
void set_var_value(std::string var, int value) { vars_[var] = value; }
void clear() {
vars_.clear();
}

void set_var_value(vtr::string_view var, int value) { vars_[var] = value; }
void set_var_value(const char* var, int value) { vars_[vtr::string_view(var)] = value; }

int get_var_value(std::string var) const {
int get_var_value(const std::string& var) const {
return get_var_value(vtr::string_view(var.data(), var.size()));
}

int get_var_value(vtr::string_view var) const {
auto iter = vars_.find(var);
if (iter == vars_.end()) {
std::string copy(var.data(), var.size());
archfpga_throw(__FILE__, __LINE__,
"No value found for variable '%s' from expression\n", var.c_str());
"No value found for variable '%s' from expression\n", copy.c_str());
}

return iter->second;
}

private:
std::map<std::string, int> vars_;
vtr::flat_map<vtr::string_view, int> vars_;
};

/* returns integer result according to specified formula and data */
int parse_formula(std::string formula, const t_formula_data& mydata);
/**** Enums ****/
/* Used to identify the type of symbolic formula object */
typedef enum e_formula_obj {
E_FML_UNDEFINED = 0,
E_FML_NUMBER,
E_FML_BRACKET,
E_FML_COMMA,
E_FML_OPERATOR,
E_FML_NUM_FORMULA_OBJS
} t_formula_obj;

/* Used to identify an operator in a formula */
typedef enum e_operator {
E_OP_UNDEFINED = 0,
E_OP_ADD,
E_OP_SUB,
E_OP_MULT,
E_OP_DIV,
E_OP_MIN,
E_OP_MAX,
E_OP_GCD,
E_OP_LCM,
E_OP_NUM_OPS
} t_operator;

/**** Class Definitions ****/
/* This class is used to represent an object in a formula, such as
* a number, a bracket, an operator, or a variable */
class Formula_Object {
public:
/* indicates the type of formula object this is */
t_formula_obj type;

/* object data, accessed based on what kind of object this is */
union u_Data {
int num; /*for number objects*/
t_operator op; /*for operator objects*/
bool left_bracket; /*for bracket objects -- specifies if this is a left bracket*/

u_Data() { memset(this, 0, sizeof(u_Data)); }
} data;

Formula_Object() {
this->type = E_FML_UNDEFINED;
}

/* returns integer result according to specified piece-wise formula and data */
int parse_piecewise_formula(const char* formula, const t_formula_data& mydata);
std::string to_string() const {
if (type == E_FML_NUMBER) {
return std::to_string(data.num);
} else if (type == E_FML_BRACKET) {
if (data.left_bracket) {
return "(";
} else {
return ")";
}
} else if (type == E_FML_COMMA) {
return ",";
} else if (type == E_FML_OPERATOR) {
if (data.op == E_OP_ADD) {
return "+";
} else if (data.op == E_OP_SUB) {
return "-";
} else if (data.op == E_OP_MULT) {
return "*";
} else if (data.op == E_OP_DIV) {
return "/";
} else if (data.op == E_OP_MIN) {
return "min";
} else if (data.op == E_OP_MAX) {
return "max";
} else if (data.op == E_OP_GCD) {
return "gcd";
} else if (data.op == E_OP_LCM) {
return "lcm";
} else {
return "???"; //Unkown
}
} else {
return "???"; //Unkown
}
}
};

class FormulaParser {
public:
FormulaParser() = default;
FormulaParser(const FormulaParser&) = delete;
FormulaParser& operator=(const FormulaParser&) = delete;

/* returns integer result according to specified formula and data */
int parse_formula(std::string formula, const t_formula_data& mydata);

/* returns integer result according to specified piece-wise formula and data */
int parse_piecewise_formula(const char* formula, const t_formula_data& mydata);

/* checks if the specified formula is piece-wise defined */
static bool is_piecewise_formula(const char* formula);

private:
std::vector<Formula_Object> rpn_output_;
std::stack<Formula_Object> op_stack_; /* stack for handling operators and brackets in formula */
};

/* checks if the specified formula is piece-wise defined */
bool is_piecewise_formula(const char* formula);
#endif
8 changes: 4 additions & 4 deletions libs/libarchfpga/src/parse_switchblocks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -447,7 +447,7 @@ static void check_wireconn(const t_arch* arch, const t_wireconn_inf& wireconn) {
/*---- Functions for Parsing the Symbolic Switchblock Formulas ----*/

/* returns integer result according to the specified switchblock formula and data. formula may be piece-wise */
int get_sb_formula_raw_result(const char* formula, const t_formula_data& mydata) {
int get_sb_formula_raw_result(FormulaParser& formula_parser, const char* formula, const t_formula_data& mydata) {
/* the result of the formula will be an integer */
int result = -1;

Expand All @@ -459,11 +459,11 @@ int get_sb_formula_raw_result(const char* formula, const t_formula_data& mydata)
}

/* parse based on whether formula is piece-wise or not */
if (is_piecewise_formula(formula)) {
if (formula_parser.is_piecewise_formula(formula)) {
//EXPERIMENTAL
result = parse_piecewise_formula(formula, mydata);
result = formula_parser.parse_piecewise_formula(formula, mydata);
} else {
result = parse_formula(formula, mydata);
result = formula_parser.parse_formula(formula, mydata);
}

return result;
Expand Down
2 changes: 1 addition & 1 deletion libs/libarchfpga/src/parse_switchblocks.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,6 @@ void read_sb_wireconns(const t_arch_switch_inf* switches, int num_switches, pugi
void check_switchblock(const t_switchblock_inf* sb, const t_arch* arch);

/* returns integer result according to the specified formula and data */
int get_sb_formula_raw_result(const char* formula, const t_formula_data& mydata);
int get_sb_formula_raw_result(FormulaParser& formula_parser, const char* formula, const t_formula_data& mydata);

#endif /* PARSE_SWITCHBLOCKS_H */
4 changes: 2 additions & 2 deletions libs/libarchfpga/src/read_xml_arch_file.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4800,7 +4800,7 @@ static void link_physical_logical_types(std::vector<t_physical_tile_type>& Physi

auto& equivalent_sites = physical_tile.equivalent_sites;

auto criteria = [physical_tile](const t_logical_block_type* lhs, const t_logical_block_type* rhs) {
auto criteria = [&physical_tile](const t_logical_block_type* lhs, const t_logical_block_type* rhs) {
int num_physical_pins = physical_tile.num_pins / physical_tile.capacity;

int lhs_num_logical_pins = lhs->pb_type->num_pins;
Expand Down Expand Up @@ -4838,7 +4838,7 @@ static void link_physical_logical_types(std::vector<t_physical_tile_type>& Physi
std::unordered_map<int, bool> ignored_pins_check_map;
std::unordered_map<int, bool> global_pins_check_map;

auto criteria = [logical_block](const t_physical_tile_type* lhs, const t_physical_tile_type* rhs) {
auto criteria = [&logical_block](const t_physical_tile_type* lhs, const t_physical_tile_type* rhs) {
int num_logical_pins = logical_block.pb_type->num_pins;

int lhs_num_physical_pins = lhs->num_pins / lhs->capacity;
Expand Down
Loading