redshift 1.3.21 → 1.3.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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