Skip to content

Commit 982814a

Browse files
committed
A major change to Coek internals
1. Removing void* references to Var/Param reference types 2. Using shared pointer references instead, to ensure proper memory mangement. 3. MANY follow-on changes were required to implement this change. 4. A key change is the reversion of IndexVector to std::vector<int>. The simple memory management used in IndexVector is not sufficient to handle the potential for dynamic alloction/decallocation of IndexVectors. NOTE: These changes will likely incur a performance penalty in coek (especialy #4). But the earlier code design did not work properly when using mapped variables and parameters.
1 parent 1b9c32c commit 982814a

26 files changed

+431
-180
lines changed

Diff for: lib/coek/coek/api/expression.cpp

+14
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,20 @@ bool Variable::is_binary() const { return repn->binary; }
282282

283283
bool Variable::is_integer() const { return repn->integer; }
284284

285+
Variable Variable::expand()
286+
{
287+
#ifdef COEK_WITH_COMPACT_MODEL
288+
auto var = Variable().
289+
lower( this->lower_expression().expand() ).
290+
upper( this->upper_expression().expand() ).
291+
value( this->value_expression().expand() ).
292+
within( this->within() );
293+
return var;
294+
#else
295+
return *this;
296+
#endif
297+
}
298+
285299
std::ostream& operator<<(std::ostream& ostr, const Variable& arg)
286300
{
287301
write_expr(arg.repn, ostr);

Diff for: lib/coek/coek/api/expression.hpp

+3
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,9 @@ class Variable {
268268
/** \returns \c false because this is not a constant expression */
269269
bool is_constant() const { return false; }
270270

271+
/** \returns an expanded Variable */
272+
Variable expand();
273+
271274
/**
272275
* \name Stream operator
273276
*

Diff for: lib/coek/coek/api/indexed_container.defs.hpp

+20-4
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@ class IndexedComponentRepn_multiarray : public IndexedComponentRepn<TYPE> {
1212
public:
1313
IndexedComponentRepn_multiarray(size_t n) : IndexedComponentRepn<TYPE>(1), shape({n})
1414
{
15-
this->cache.resize((n + 1) * 2);
15+
#ifdef CUSTOM_INDEXVECTOR
16+
this->cache.resize(2 * (n + 1) * 2);
17+
#endif
1618
}
1719

1820
IndexedComponentRepn_multiarray(const std::vector<size_t>& _shape)
@@ -21,7 +23,9 @@ class IndexedComponentRepn_multiarray : public IndexedComponentRepn<TYPE> {
2123
size_t _size = 1;
2224
for (auto n : shape)
2325
_size *= n;
24-
this->cache.resize((_size + 1) * (_shape.size() + 1));
26+
#ifdef CUSTOM_INDEXVECTOR
27+
this->cache.resize(2 * (_size + 1) * (_shape.size() + 1));
28+
#endif
2529
}
2630

2731
IndexedComponentRepn_multiarray(const std::initializer_list<size_t>& _shape)
@@ -30,7 +34,9 @@ class IndexedComponentRepn_multiarray : public IndexedComponentRepn<TYPE> {
3034
size_t _size = 1;
3135
for (auto n : shape)
3236
_size *= n;
33-
this->cache.resize((_size + 1) * (_shape.size() + 1));
37+
#ifdef CUSTOM_INDEXVECTOR
38+
this->cache.resize(2 * (_size + 1) * (_shape.size() + 1));
39+
#endif
3440
}
3541

3642
virtual ~IndexedComponentRepn_multiarray() {}
@@ -88,7 +94,9 @@ class IndexedComponentRepn_setindex : public IndexedComponentRepn<TYPE> {
8894
IndexedComponentRepn_setindex(ConcreteSet& _arg)
8995
: IndexedComponentRepn<TYPE>(_arg.dim()), concrete_set(_arg)
9096
{
91-
this->cache.resize((this->dim() + 1) * (_arg.size() + 1));
97+
#ifdef CUSTOM_INDEXVECTOR
98+
this->cache.resize(2 * (this->dim() + 1) * (_arg.size() + 1));
99+
#endif
92100
this->tmp.resize(this->dim());
93101
}
94102

@@ -119,8 +127,12 @@ void IndexedComponentRepn_setindex<TYPE>::generate_names()
119127
return;
120128

121129
size_t _dim = this->dim();
130+
#ifdef CUSTOM_INDEXVECTOR
122131
std::vector<int> x_data(_dim);
123132
IndexVector x(&(x_data[0]), _dim);
133+
#else
134+
IndexVector x(_dim);
135+
#endif
124136
for (auto& indices : concrete_set) {
125137
for (size_t j = 0; j < _dim; j++)
126138
x[j] = indices[j];
@@ -209,7 +221,11 @@ TYPE& IndexedComponent_Map<TYPE>::index(const IndexVector& args)
209221

210222
auto curr = this->repn->value.find(args);
211223
if (curr == this->repn->value.end()) {
224+
#ifdef CUSTOM_INDEXVECTOR
212225
auto _args = this->repn->cache.clone(args);
226+
#else
227+
auto& _args = args;
228+
#endif
213229
TYPE tmp;
214230
auto& res = this->repn->value[_args] = tmp;
215231
return res;

Diff for: lib/coek/coek/api/indexed_container.hpp

+7-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@ typedef std::variant<int, expr_pointer_t> refarg_types;
2424
template <class TYPE>
2525
class IndexedComponentRepn {
2626
public:
27+
#ifdef CUSTOM_INDEXVECTOR
2728
IndexVectorCache cache;
29+
#endif
2830
std::map<IndexVector, TYPE> value;
2931
size_t _dim;
3032
std::string _name;
@@ -38,7 +40,11 @@ class IndexedComponentRepn {
3840

3941
void resize_index_vectors(IndexVector& tmp, std::vector<refarg_types>& reftmp)
4042
{
41-
tmp = cache.alloc(dim());
43+
#ifdef CUSTOM_INDEXVECTOR
44+
tmp = cache.alloc(2*dim());
45+
#else
46+
tmp.resize(dim());
47+
#endif
4248
reftmp.resize(dim());
4349
}
4450

Diff for: lib/coek/coek/api/parameter_array.cpp

+25-11
Original file line numberDiff line numberDiff line change
@@ -12,24 +12,35 @@ class ParameterArrayRepn : public ParameterAssocArrayRepn {
1212
size_t _size;
1313

1414
public:
15-
ParameterArrayRepn(size_t n) : shape({n}), _size(n) { cache.resize((size() + 1) * 2); }
15+
ParameterArrayRepn(size_t n) : shape({n}), _size(n)
16+
{
17+
#ifdef CUSTOM_INDEXVECTOR
18+
cache.resize(2 * (size() + 1) * 2);
19+
#endif
20+
}
1621

1722
ParameterArrayRepn(const std::vector<size_t>& _shape) : shape(_shape), _size(1)
1823
{
1924
for (auto n : shape)
2025
_size *= n;
21-
cache.resize((size() + 1) * (dim() + 1));
26+
#ifdef CUSTOM_INDEXVECTOR
27+
cache.resize(2 * (size() + 1) * (dim() + 1));
28+
#endif
2229
}
2330

2431
ParameterArrayRepn(const std::initializer_list<size_t>& _shape) : shape(_shape), _size(1)
2532
{
2633
for (auto n : shape)
2734
_size *= n;
28-
cache.resize((size() + 1) * (dim() + 1));
35+
#ifdef CUSTOM_INDEXVECTOR
36+
cache.resize(2 * (size() + 1) * (dim() + 1));
37+
#endif
2938
}
3039

3140
virtual ~ParameterArrayRepn() {}
3241

42+
Parameter index(const IndexVector& args);
43+
3344
size_t dim() { return shape.size(); }
3445

3546
size_t size() { return _size; }
@@ -72,7 +83,7 @@ void ParameterArrayRepn::generate_names()
7283
if (name.size() == 0)
7384
return;
7485

75-
setup();
86+
expand();
7687

7788
size_t ctr = 0;
7889
for (auto& param : values)
@@ -101,15 +112,18 @@ ParameterArray::ParameterArray(const std::initializer_list<size_t>& shape)
101112
repn->resize_index_vectors(tmp, reftmp);
102113
}
103114

104-
ParameterAssocArrayRepn* ParameterArray::get_repn() { return repn.get(); }
115+
std::shared_ptr<ParameterAssocArrayRepn> ParameterArray::get_repn() { return repn; }
105116

106117
Parameter ParameterArray::index(const IndexVector& args)
118+
{ return repn->index(args); }
119+
120+
Parameter ParameterArrayRepn::index(const IndexVector& args)
107121
{
108-
auto _repn = repn.get();
109-
auto& shape = _repn->shape;
122+
//auto _repn = repn.get();
123+
//auto& shape = _repn->shape;
110124
assert(args.size() == shape.size());
111125

112-
_repn->setup();
126+
expand();
113127

114128
// We know that the args[i] values are nonnegative b.c. we have asserted that while
115129
// processing these arguments
@@ -120,7 +134,7 @@ Parameter ParameterArray::index(const IndexVector& args)
120134
if (ndx > size()) {
121135
// TODO - Can't we do better than this check? Do we check if each index is in the correct
122136
// range?
123-
std::string err = "Unknown index value: " + _repn->parameter_template.name() + "[";
137+
std::string err = "Unknown index value: " + parameter_template.name() + "[";
124138
for (size_t i = 0; i < args.size(); i++) {
125139
if (i > 0)
126140
err += ",";
@@ -130,7 +144,7 @@ Parameter ParameterArray::index(const IndexVector& args)
130144
throw std::runtime_error(err);
131145
}
132146

133-
return _repn->values[ndx];
147+
return values[ndx];
134148
}
135149

136150
void ParameterArray::index_error(size_t i)
@@ -181,7 +195,7 @@ ParameterArray parameter(const std::initializer_list<size_t>& shape)
181195

182196
ParameterArray& Model::add_parameter(ParameterArray& params)
183197
{
184-
params.repn->setup();
198+
params.repn->expand();
185199
if (repn->name_generation_policy == Model::NameGeneration::eager)
186200
params.generate_names();
187201
else if (repn->name_generation_policy == Model::NameGeneration::lazy)

Diff for: lib/coek/coek/api/parameter_array.hpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ class ParameterArrayRepn;
1414
class ParameterArray : public ParameterAssocArray {
1515
public:
1616
std::shared_ptr<ParameterArrayRepn> repn;
17-
ParameterAssocArrayRepn* get_repn();
17+
std::shared_ptr<ParameterAssocArrayRepn> get_repn();
1818

1919
Parameter index(const IndexVector& args);
2020
void index_error(size_t i);

Diff for: lib/coek/coek/api/parameter_assoc_array.cpp

+23-12
Original file line numberDiff line numberDiff line change
@@ -13,22 +13,30 @@ namespace coek {
1313

1414
ParameterAssocArrayRepn::ParameterAssocArrayRepn() { parameter_template.name("p"); }
1515

16-
void ParameterAssocArrayRepn::resize_index_vectors(IndexVector& tmp,
17-
std::vector<refarg_types>& reftmp)
16+
void ParameterAssocArrayRepn::resize_index_vectors(IndexVector& tmp_,
17+
std::vector<refarg_types>& reftmp_)
1818
{
19-
tmp = cache.alloc(dim());
20-
reftmp.resize(dim());
19+
auto dim_ = dim();
20+
#ifdef CUSTOM_INDEXVECTOR
21+
tmp = cache.alloc(dim_);
22+
tmp_ = cache.alloc(dim_);
23+
#else
24+
tmp.resize(dim_);
25+
tmp_.resize(dim_);
26+
#endif
27+
reftmp.resize(dim_);
28+
reftmp_.resize(dim_);
2129
}
2230

23-
void ParameterAssocArrayRepn::setup()
31+
void ParameterAssocArrayRepn::expand()
2432
{
25-
if (first_setup) {
33+
if (first_expand) {
2634
auto value = std::make_shared<ConstantTerm>(
2735
parameter_template.value_expression().expand().value());
2836
for (size_t i = 0; i < size(); i++) {
2937
values.emplace_back(CREATE_POINTER(ParameterTerm, value));
3038
}
31-
first_setup = false;
39+
first_expand = false;
3240
}
3341
}
3442

@@ -80,11 +88,12 @@ std::vector<Parameter>::iterator ParameterAssocArray::end() { return get_repn()-
8088

8189
#ifdef COEK_WITH_COMPACT_MODEL
8290
expr_pointer_t create_paramref(const std::vector<refarg_types>& indices, const std::string& name,
83-
void* var);
91+
std::shared_ptr<ParameterAssocArrayRepn>& var);
8492

8593
Expression ParameterAssocArray::create_paramref(const std::vector<refarg_types>& args)
8694
{
87-
return coek::create_paramref(args, get_repn()->parameter_template.name(), this);
95+
auto repn = get_repn();
96+
return coek::create_paramref(args, repn->parameter_template.name(), repn);
8897
}
8998
#endif
9099

@@ -95,11 +104,13 @@ Expression ParameterAssocArray::create_paramref(const std::vector<refarg_types>&
95104
#ifdef COEK_WITH_COMPACT_MODEL
96105
expr_pointer_t get_concrete_param(ParameterRefTerm& paramref)
97106
{
98-
ParameterAssocArray* param = static_cast<ParameterAssocArray*>(paramref.param);
107+
//* param = static_cast<ParameterAssocArray*>(paramref.param);
108+
auto param = std::dynamic_pointer_cast<ParameterAssocArrayRepn>(paramref.param);
99109

100110
std::vector<int> index;
101-
for (auto it = paramref.indices.begin(); it != paramref.indices.end(); ++it) {
102-
refarg_types& reftmp = *it;
111+
//for (auto it = paramref.indices.begin(); it != paramref.indices.end(); ++it) {
112+
// refarg_types& reftmp = *it;
113+
for (auto& reftmp : paramref.indices) {
103114
if (auto ival = std::get_if<int>(&reftmp))
104115
index.push_back(*ival);
105116
else {

Diff for: lib/coek/coek/api/parameter_assoc_array.hpp

+3-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ namespace coek {
66

77
class ParameterAssocArray {
88
public:
9-
virtual ParameterAssocArrayRepn* get_repn() = 0;
9+
10+
virtual std::shared_ptr<ParameterAssocArrayRepn> get_repn() = 0;
1011
IndexVector tmp;
1112
std::vector<refarg_types> reftmp;
1213

@@ -17,7 +18,7 @@ class ParameterAssocArray {
1718
size_t size();
1819
size_t dim();
1920

20-
virtual Parameter index(const IndexVector& args) = 0;
21+
//virtual Parameter index(const IndexVector& args) = 0;
2122
#ifdef COEK_WITH_COMPACT_MODEL
2223
Expression create_paramref(const std::vector<refarg_types>& indices);
2324
#endif

Diff for: lib/coek/coek/api/parameter_assoc_array_repn.hpp

+13-2
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,21 @@ typedef std::variant<int, expr_pointer_t> refarg_types;
1717

1818
class ParameterAssocArrayRepn {
1919
public:
20+
#ifdef CUSTOM_INDEXVECTOR
2021
IndexVectorCache cache;
22+
#endif
2123
std::vector<Parameter> values;
2224
Parameter parameter_template;
2325

24-
bool first_setup = true;
26+
IndexVector tmp;
27+
std::vector<refarg_types> reftmp;
28+
29+
bool first_expand = true;
2530

2631
public:
2732
ParameterAssocArrayRepn();
2833

29-
virtual void setup();
34+
virtual void expand();
3035
virtual void generate_names() = 0;
3136

3237
virtual size_t dim() = 0;
@@ -41,6 +46,12 @@ class ParameterAssocArrayRepn {
4146

4247
/** Set the name of the variable. */
4348
void name(const std::string& name);
49+
50+
virtual Parameter index(const IndexVector& args) = 0;
51+
52+
#ifdef COEK_WITH_COMPACT_MODEL
53+
Expression create_paramref(const std::vector<refarg_types>& indices);
54+
#endif
4455
};
4556

4657
} // namespace coek

0 commit comments

Comments
 (0)