redshift 1.3.21 → 1.3.22

Sign up to get free protection for your applications and to get access to all the features.
@@ -8,7 +8,7 @@ module RedShift
8
8
  end
9
9
 
10
10
  module RedShift; class Flow
11
- def translate flow_fn, result_var, rk_level, cl, orig_formula = nil
11
+ def translate flow_fn, result_var, cl, rk_level = nil, orig_formula = nil
12
12
  translation = {}
13
13
  setup = [] ## should use accumulator
14
14
 
@@ -43,7 +43,7 @@ module RedShift; class Flow
43
43
 
44
44
  ct_struct = make_ct_struct(flow_fn, cl)
45
45
 
46
- link_type_ssn = link_type.shadow_struct.name
46
+ link_type_ssn = link_type.shadow_struct_name
47
47
  ct_struct.declare link_cname => "#{link_type_ssn} *#{link_cname}"
48
48
  flow_fn.setup link_cname => "ct.#{link_cname} = shadow->#{link}"
49
49
  end
@@ -77,7 +77,8 @@ module RedShift; class Flow
77
77
  }
78
78
  }
79
79
  # The d_tick assignment is explained in component-gen.rb.
80
- setup << "#{var_cname} = #{cont_var}.value_#{rk_level};"
80
+ rk = rk_level || "shadow->world->rk_level"
81
+ setup << "#{var_cname} = #{cont_var}.value[#{rk}];"
81
82
 
82
83
  elsif (kind = cl.input_variables[varsym])
83
84
  # x ==> var_x
@@ -157,7 +158,7 @@ module RedShift; class Flow
157
158
  else
158
159
  ct_struct = sf.declare_struct(CT_STRUCT_NAME)
159
160
 
160
- ct_struct.declare :shadow => "#{cl.shadow_struct.name} *shadow"
161
+ ct_struct.declare :shadow => "#{cl.shadow_struct_name} *shadow"
161
162
 
162
163
  flow_fn.declare :ct => "#{CT_STRUCT_NAME} ct"
163
164
  flow_fn.setup :ct_shadow => "ct.shadow = shadow"
@@ -166,7 +167,7 @@ module RedShift; class Flow
166
167
  ct_struct
167
168
  end
168
169
 
169
- # l.x ==> get_l__x()->value_n
170
+ # l.x ==> get_l__x()->value[n]
170
171
  def translate_link(link, var, translation, flow_fn, cl, expr, rk_level)
171
172
  link_type, link_strictness = cl.link_variables[link.intern]
172
173
  raise(NameError, "No such link, #{link}") unless link_type
@@ -208,7 +209,7 @@ module RedShift; class Flow
208
209
  end
209
210
 
210
211
  if var_type == :continuous
211
- link_cs_ssn = link_type.cont_state_class.shadow_struct.name
212
+ link_cs_ssn = link_type.cont_state_class.shadow_struct_name
212
213
  link_cs_cname = "link_cs_#{link}"
213
214
  ct_struct.declare link_cs_cname => "#{link_cs_ssn} *#{link_cs_cname}"
214
215
  end
@@ -218,7 +219,7 @@ module RedShift; class Flow
218
219
 
219
220
  unless translation[link]
220
221
  translation[link] = link_cname
221
- link_type_ssn = link_type.shadow_struct.name
222
+ link_type_ssn = link_type.shadow_struct_name
222
223
  ct_struct.declare link_cname => "#{link_type_ssn} *#{link_cname}"
223
224
  flow_fn.setup link_cname => "ct.#{link_cname} = shadow->#{link}"
224
225
  end ## same as below
@@ -256,7 +257,8 @@ module RedShift; class Flow
256
257
  }
257
258
  } ## algebraic test is same as above
258
259
 
259
- translation[expr] = "#{get_var_cname}(&ct)->value_#{rk_level}"
260
+ rk = rk_level || "shadow->world->rk_level"
261
+ translation[expr] = "#{get_var_cname}(&ct)->value[#{rk}]"
260
262
 
261
263
  when :constant
262
264
  sf.declare get_var_cname => %{
@@ -270,7 +272,7 @@ module RedShift; class Flow
270
272
  translation[expr] = "#{get_var_cname}(&ct)"
271
273
 
272
274
  when :link
273
- link_link_type_ssn = link_link_type.shadow_struct.name
275
+ link_link_type_ssn = link_link_type.shadow_struct_name
274
276
  sf.declare get_var_cname => %{
275
277
  inline static #{link_link_type_ssn} *#{get_var_cname}(#{CT_STRUCT_NAME} *ct) {
276
278
  if (!ct->#{link_cname})
@@ -1,20 +1,27 @@
1
1
  module RedShift; class AlgebraicFlow
2
- def flow_wrapper cl, state
3
- var_name = @var
4
- flow = self
5
- flow_name = "flow_#{CGenerator.make_c_name cl.name}_#{var_name}_#{state}"
2
+ def make_generator cl, state
3
+ @fname = "flow_#{CGenerator.make_c_name cl.name}_#{var}_#{state}"
4
+ @inspect_str = "#{cl.name}:#{state}: #{var} = #{formula}"
6
5
 
7
- Component::FlowWrapper.make_subclass flow_name do
8
- @inspect_str = "#{cl.name}:#{state}: #{var_name} = #{flow.formula}"
6
+ @generator = proc do
7
+ sl = cl.shadow_library
8
+ ssn = cl.shadow_struct_name
9
+ cont_state_ssn = cl.cont_state_class.shadow_struct_name
10
+
11
+ ## use an accumulator for these
12
+ sl.init_library_function.body \
13
+ "s_init_flow(#{fname}, #{fname.inspect}, #{inspect_str.inspect}, ALGEBRAIC);"
9
14
 
10
- ssn = cl.shadow_struct.name
11
- cont_state_ssn = cl.cont_state_class.shadow_struct.name
15
+ include_file, source_file = sl.add_file fname
12
16
 
13
17
  # We need the struct
14
- shadow_library_source_file.include(cl.shadow_library_include_file)
18
+ source_file.include(cl.shadow_library_include_file)
15
19
 
16
- shadow_library_source_file.define(flow_name).instance_eval do
20
+ flow = self
21
+ var_name = @var
22
+ source_file.define(fname).instance_eval do
17
23
  arguments "ComponentShadow *comp_shdw"
24
+ scope :extern
18
25
  declare :shadow => %{
19
26
  struct #{ssn} *shadow;
20
27
  struct #{cont_state_ssn} *cont_state;
@@ -28,45 +35,31 @@ module RedShift; class AlgebraicFlow
28
35
 
29
36
  setup :shadow => %{
30
37
  shadow = (#{ssn} *)comp_shdw;
31
- cont_state = (#{cont_state_ssn} *)shadow->cont_state;
38
+ cont_state = (struct #{cont_state_ssn} *)shadow->cont_state;
32
39
  var = &cont_state->#{var_name};
33
40
  assert(var->algebraic);
34
- if (shadow->world->alg_nest > 100) {
41
+ if (shadow->world->alg_nest > shadow->world->alg_depth_limit) {
35
42
  shadow->world->alg_nest = 0;
36
43
  rs_raise(#{exc}, shadow->self, #{msg.inspect});
37
44
  }
38
45
  shadow->world->alg_nest++;
39
46
  }
40
- ## 100 not always enough, so could increase limit exponentially,
41
- ## and look in subsequent iterations for repeats of this [var, obj].
42
47
 
43
- ## optimization: it might be possible to translate once and
44
- ## use gsub to make each of the four versions, or use a template.
45
48
  body %{
49
+ #{flow.translate(self,
50
+ "var->value[shadow->world->rk_level]", cl) {|strict|
51
+ flow.instance_eval {@strict = strict}
52
+ }.join("
53
+ ")};
54
+
46
55
  switch (shadow->world->rk_level) {
47
56
  case 0:
48
- #{flow.translate(self, "var->value_0", 0, cl).join("
49
- ")};
50
57
  var->d_tick = shadow->world->d_tick;
51
58
  break;
52
59
 
53
60
  case 1:
54
- #{flow.translate(self, "var->value_1", 1, cl).join("
55
- ")};
56
- var->rk_level = shadow->world->rk_level;
57
- break;
58
-
59
61
  case 2:
60
- #{flow.translate(self, "var->value_2", 2, cl).join("
61
- ")};
62
- var->rk_level = shadow->world->rk_level;
63
- break;
64
-
65
62
  case 3:
66
- #{flow.translate(self, "var->value_3", 3, cl){|strict|
67
- flow.instance_eval {@strict = strict}
68
- }.join("
69
- ")};
70
63
  var->rk_level = shadow->world->rk_level;
71
64
  break;
72
65
 
@@ -77,12 +70,14 @@ module RedShift; class AlgebraicFlow
77
70
 
78
71
  shadow->world->alg_nest--;
79
72
  }
80
- end # Case 0 applies during discrete update.
81
- # alg flows are lazy
82
-
83
- define_c_method :calc_function_pointer do
84
- body "shadow->flow = &#{flow_name}", "shadow->algebraic = 1"
85
73
  end
74
+ # Case 0 applies during discrete update.
75
+ # Alg flows are lazy.
76
+ # Note that @strict does not need to propagate to wrapper
77
+ # (as it does in CexprGuard) since checking is done statically
78
+ # in Component.define_flow.
86
79
  end
80
+
81
+ return self
87
82
  end
88
83
  end; end
@@ -1,24 +1,22 @@
1
1
  module RedShift; class DelayFlow
2
- def flow_wrapper cl, state
3
- var_name = @var
4
- flow = self
5
- flow_name = "flow_#{CGenerator.make_c_name cl.name}_#{var_name}_#{state}"
2
+ def make_generator cl, state
6
3
  delay_by = @delay_by
7
-
8
- Component::FlowWrapper.make_subclass flow_name do
9
- @inspect_str =
10
- "#{cl.name}:#{state}: " +
11
- "#{var_name} = #{flow.formula} [delay: #{delay_by}]"
4
+ @fname = "flow_#{CGenerator.make_c_name cl.name}_#{var}_#{state}"
5
+ @inspect_str =
6
+ "#{cl.name}:#{state}: " +
7
+ "#{var} = #{formula} [delay: #{delay_by}]"
12
8
 
13
- ssn = cl.shadow_struct.name
14
- cont_state_ssn = cl.cont_state_class.shadow_struct.name
9
+ @generator = proc do
10
+ sl = cl.shadow_library
11
+ ssn = cl.shadow_struct_name
12
+ cont_state_ssn = cl.cont_state_class.shadow_struct_name
15
13
 
16
14
  require "redshift/target/c/flow/buffer"
17
15
  RedShift.library.define_buffer
18
16
 
19
- bufname = "#{var_name}_buffer_data"
20
- delayname = "#{var_name}_delay"
21
- tsname = "#{var_name}_time_step"
17
+ bufname = "#{var}_buffer_data"
18
+ delayname = "#{var}_delay"
19
+ tsname = "#{var}_time_step"
22
20
 
23
21
  cl.class_eval do
24
22
  shadow_attr_accessor bufname => "RSBuffer #{bufname}"
@@ -37,11 +35,19 @@ module RedShift; class DelayFlow
37
35
  private :"#{delayname}="
38
36
  end
39
37
 
38
+ sl.init_library_function.body \
39
+ "s_init_flow(#{fname}, #{fname.inspect}, #{inspect_str.inspect}, NONALGEBRAIC);"
40
+
41
+ include_file, source_file = sl.add_file fname
42
+
40
43
  # We need the struct
41
- shadow_library_source_file.include(cl.shadow_library_include_file)
44
+ source_file.include(cl.shadow_library_include_file)
42
45
 
43
- shadow_library_source_file.define(flow_name).instance_eval do
46
+ flow = self
47
+ var_name = @var
48
+ source_file.define(fname).instance_eval do
44
49
  arguments "ComponentShadow *comp_shdw"
50
+ scope :extern
45
51
  declare :shadow => %{
46
52
  struct #{ssn} *shadow;
47
53
  struct #{cont_state_ssn} *cont_state;
@@ -53,7 +59,7 @@ module RedShift; class DelayFlow
53
59
  }
54
60
  setup :shadow => %{
55
61
  shadow = (#{ssn} *)comp_shdw;
56
- cont_state = (#{cont_state_ssn} *)shadow->cont_state;
62
+ cont_state = (struct #{cont_state_ssn} *)shadow->cont_state;
57
63
  var = &cont_state->#{var_name};
58
64
  }
59
65
  setup :rk_level => %{
@@ -64,7 +70,7 @@ module RedShift; class DelayFlow
64
70
  begin
65
71
  "delay = #{Float(delay_by)}"
66
72
  rescue ArgumentError
67
- flow.translate(self, "delay", 0, cl, delay_by)
73
+ flow.translate(self, "delay", cl, 0, delay_by)
68
74
  end
69
75
 
70
76
  include World.shadow_library_include_file
@@ -101,7 +107,7 @@ module RedShift; class DelayFlow
101
107
  len = steps*4;
102
108
 
103
109
  if (!ptr) {
104
- #{flow.translate(self, "fill", 0, cl).join("
110
+ #{flow.translate(self, "fill", cl, 0).join("
105
111
  ")};
106
112
 
107
113
  rs_buffer_init(&shadow->#{bufname}, len, fill);
@@ -115,12 +121,12 @@ module RedShift; class DelayFlow
115
121
  offset = shadow->#{bufname}.offset;
116
122
  }
117
123
 
118
- var->value_0 = ptr[offset];
119
- var->value_1 = ptr[offset + 1];
120
- var->value_2 = ptr[offset + 2];
121
- var->value_3 = ptr[offset + 3];
124
+ var->value[0] = ptr[offset];
125
+ var->value[1] = ptr[offset + 1];
126
+ var->value[2] = ptr[offset + 2];
127
+ var->value[3] = ptr[offset + 3];
122
128
 
123
- #{flow.translate(self, "ptr[offset]", 0, cl).join("
129
+ #{flow.translate(self, "ptr[offset]", cl, 0).join("
124
130
  ")};
125
131
  break;
126
132
 
@@ -133,15 +139,15 @@ module RedShift; class DelayFlow
133
139
  len = shadow->#{bufname}.len;
134
140
  offset = shadow->#{bufname}.offset;
135
141
 
136
- #{flow.translate(self, "ptr[offset+1]", 1, cl).join("
142
+ #{flow.translate(self, "ptr[offset+1]", cl, 1).join("
137
143
  ")};
138
- #{flow.translate(self, "ptr[offset+2]", 2, cl).join("
144
+ #{flow.translate(self, "ptr[offset+2]", cl, 2).join("
139
145
  ")};
140
- #{flow.translate(self, "ptr[offset+3]", 3, cl).join("
146
+ #{flow.translate(self, "ptr[offset+3]", cl, 3).join("
141
147
  ")};
142
148
 
143
149
  offset = (offset + 4) % len;
144
- var->value_0 = ptr[offset];
150
+ var->value[0] = ptr[offset];
145
151
  shadow->#{bufname}.offset = offset;
146
152
  break;
147
153
 
@@ -154,10 +160,6 @@ module RedShift; class DelayFlow
154
160
  var->rk_level = shadow->world->rk_level;
155
161
  }
156
162
  end
157
-
158
- define_c_method :calc_function_pointer do
159
- body "shadow->flow = &#{flow_name}"
160
- end
161
163
  end
162
164
  end
163
165
  end; end
@@ -1,26 +1,32 @@
1
1
  module RedShift; class DerivativeFlow
2
- def flow_wrapper cl, state
3
- var_name = @var
4
- flow = self
5
- flow_name = "flow_#{CGenerator.make_c_name cl.name}_#{var_name}_#{state}"
6
- feedback = @feedback
7
-
8
- Component::FlowWrapper.make_subclass flow_name do
9
- @inspect_str = "#{cl.name}:#{state}: #{var_name} = #{flow.formula}'"
2
+ def make_generator cl, state
3
+ @fname = "flow_#{CGenerator.make_c_name cl.name}_#{var}_#{state}"
4
+ @inspect_str = "#{cl.name}:#{state}: #{var} = #{formula}"
10
5
 
11
- ssn = cl.shadow_struct.name
12
- cont_state_ssn = cl.cont_state_class.shadow_struct.name
6
+ @generator = proc do
7
+ sl = cl.shadow_library
8
+ ssn = cl.shadow_struct_name
9
+ cont_state_ssn = cl.cont_state_class.shadow_struct_name
10
+
11
+ sl.init_library_function.body \
12
+ "s_init_flow(#{fname}, #{fname.inspect}, #{inspect_str.inspect}, NONALGEBRAIC);"
13
+
14
+ include_file, source_file = sl.add_file fname
13
15
 
14
16
  # We need the struct
15
- shadow_library_source_file.include(cl.shadow_library_include_file)
17
+ source_file.include(cl.shadow_library_include_file)
16
18
 
17
- init_rhs_name = "#{var_name}_init_rhs"
19
+ init_rhs_name = "#{var}_init_rhs"
18
20
  cl.class_eval do
19
21
  shadow_attr_accessor init_rhs_name => "double #{init_rhs_name}"
20
22
  end
21
23
 
22
- shadow_library_source_file.define(flow_name).instance_eval do
24
+ flow = self
25
+ var_name = @var
26
+ feedback = @feedback
27
+ source_file.define(fname).instance_eval do
23
28
  arguments "ComponentShadow *comp_shdw"
29
+ scope :extern
24
30
  declare :shadow => %{
25
31
  struct #{ssn} *shadow;
26
32
  struct #{cont_state_ssn} *cont_state;
@@ -30,7 +36,7 @@ module RedShift; class DerivativeFlow
30
36
  }
31
37
  setup :shadow => %{
32
38
  shadow = (#{ssn} *)comp_shdw;
33
- cont_state = (#{cont_state_ssn} *)shadow->cont_state;
39
+ cont_state = (struct #{cont_state_ssn} *)shadow->cont_state;
34
40
  var = &cont_state->#{var_name};
35
41
  scratch = &shadow->#{init_rhs_name};
36
42
  time_step = shadow->world->time_step;
@@ -42,10 +48,10 @@ module RedShift; class DerivativeFlow
42
48
  body %{
43
49
  switch (shadow->world->rk_level) {
44
50
  case 0:
45
- #{flow.translate(self, "antiddt", 0, cl).join("
51
+ #{flow.translate(self, "antiddt", cl, 0).join("
46
52
  ")};
47
- var->value_0 = var->value_1 =
48
- var->value_2 = var->value_3 =
53
+ var->value[0] = var->value[1] =
54
+ var->value[2] = var->value[3] =
49
55
  (antiddt - *scratch) / time_step;
50
56
  *scratch = antiddt;
51
57
  }
@@ -54,31 +60,26 @@ module RedShift; class DerivativeFlow
54
60
  }
55
61
  else
56
62
  body %{
63
+ #{flow.translate(self, "antiddt", cl).join("
64
+ ")};
65
+
57
66
  switch (shadow->world->rk_level) {
58
67
  case 0:
59
- #{flow.translate(self, "antiddt", 0, cl).join("
60
- ")};
61
- var->value_1 = var->value_0;
68
+ var->value[1] = var->value[0];
62
69
  *scratch = antiddt;
63
70
  break;
64
71
 
65
72
  case 1:
66
- #{flow.translate(self, "antiddt", 1, cl).join("
67
- ")};
68
- var->value_2 = (antiddt - *scratch) / (time_step/2);
73
+ var->value[2] = (antiddt - *scratch) / (time_step/2);
69
74
  *scratch = antiddt;
70
75
  break;
71
76
 
72
77
  case 2:
73
- #{flow.translate(self, "antiddt", 2, cl).join("
74
- ")};
75
- var->value_3 = (antiddt - *scratch) / (time_step/2);
78
+ var->value[3] = (antiddt - *scratch) / (time_step/2);
76
79
  break;
77
80
 
78
81
  case 3:
79
- #{flow.translate(self, "antiddt", 3, cl).join("
80
- ")};
81
- var->value_0 = (antiddt - *scratch) / (time_step/2);
82
+ var->value[0] = (antiddt - *scratch) / (time_step/2);
82
83
  break;
83
84
 
84
85
  default:
@@ -91,10 +92,6 @@ module RedShift; class DerivativeFlow
91
92
  }
92
93
  end
93
94
  end
94
-
95
- define_c_method :calc_function_pointer do
96
- body "shadow->flow = &#{flow_name}"
97
- end
98
95
  end
99
96
  end
100
97
 
@@ -1,21 +1,26 @@
1
1
  module RedShift; class EulerDifferentialFlow
2
- def flow_wrapper cl, state
3
- var_name = @var
4
- flow = self
5
-
6
- flow_name = "flow_#{CGenerator.make_c_name cl.name}_#{var_name}_#{state}"
7
-
8
- Component::FlowWrapper.make_subclass flow_name do
9
- @inspect_str = "#{cl.name}:#{state}: #{var_name} = #{flow.formula}"
2
+ def make_generator cl, state
3
+ @fname = "flow_#{CGenerator.make_c_name cl.name}_#{var}_#{state}"
4
+ @inspect_str = "#{cl.name}:#{state}: #{var} = #{formula}"
10
5
 
11
- ssn = cl.shadow_struct.name
12
- cont_state_ssn = cl.cont_state_class.shadow_struct.name
6
+ @generator = proc do
7
+ sl = cl.shadow_library
8
+ ssn = cl.shadow_struct_name
9
+ cont_state_ssn = cl.cont_state_class.shadow_struct_name
10
+
11
+ sl.init_library_function.body \
12
+ "s_init_flow(#{fname}, #{fname.inspect}, #{inspect_str.inspect}, NONALGEBRAIC);"
13
+
14
+ include_file, source_file = sl.add_file fname
13
15
 
14
16
  # We need the struct
15
- shadow_library_source_file.include(cl.shadow_library_include_file)
17
+ source_file.include(cl.shadow_library_include_file)
16
18
 
17
- shadow_library_source_file.define(flow_name).instance_eval do
19
+ flow = self
20
+ var_name = @var
21
+ source_file.define(fname).instance_eval do
18
22
  arguments "ComponentShadow *comp_shdw"
23
+ scope :extern
19
24
  declare :shadow => %{
20
25
  struct #{ssn} *shadow;
21
26
  struct #{cont_state_ssn} *cont_state;
@@ -30,7 +35,7 @@ module RedShift; class EulerDifferentialFlow
30
35
  } ## optimization: in rk_level==4 case, don't need to calc deps
31
36
  setup :shadow => %{
32
37
  shadow = (#{ssn} *)comp_shdw;
33
- cont_state = (#{cont_state_ssn} *)shadow->cont_state;
38
+ cont_state = (struct #{cont_state_ssn} *)shadow->cont_state;
34
39
  var = &cont_state->#{var_name};
35
40
  time_step = shadow->world->time_step;
36
41
  } # return is necessary--else shadow, cont_state, var are uninitialized
@@ -40,18 +45,18 @@ module RedShift; class EulerDifferentialFlow
40
45
  body %{
41
46
  switch (shadow->world->rk_level) {
42
47
  case 0:
43
- #{flow.translate(self, "ddt_#{var_name}", 0, cl).join("
48
+ #{flow.translate(self, "ddt_#{var_name}", cl, 0).join("
44
49
  ")};
45
50
 
46
- var->value_1 = var->value_2 =
47
- var->value_0 + ddt_#{var_name} * time_step/2;
48
- var->value_3 =
49
- var->value_0 + ddt_#{var_name} * time_step;
51
+ var->value[1] = var->value[2] =
52
+ var->value[0] + ddt_#{var_name} * time_step/2;
53
+ var->value[3] =
54
+ var->value[0] + ddt_#{var_name} * time_step;
50
55
  var->rk_level = 3;
51
56
  break;
52
57
 
53
58
  case 3:
54
- var->value_0 = var->value_3;
59
+ var->value[0] = var->value[3];
55
60
  var->rk_level = 4;
56
61
  break;
57
62
  }
@@ -59,9 +64,6 @@ module RedShift; class EulerDifferentialFlow
59
64
  shadow->world->rk_level++;
60
65
  }
61
66
  end
62
- define_c_method :calc_function_pointer do
63
- body "shadow->flow = &#{flow_name}"
64
- end
65
67
  end
66
68
  end
67
69
  end; end