rl-language-core 0.3.6__py3-none-win_amd64.whl

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.
Files changed (79) hide show
  1. command_line/__init__.py +14 -0
  2. command_line/utils.py +107 -0
  3. loader/__init__.py +10 -0
  4. loader/simulation.py +286 -0
  5. ml/__init__.py +9 -0
  6. ml/action_oracle.py +61 -0
  7. ml/env.py +280 -0
  8. ml/ppg/__init__.py +0 -0
  9. ml/ppg/constants.py +56 -0
  10. ml/ppg/distr_builder.py +98 -0
  11. ml/ppg/envs.py +109 -0
  12. ml/ppg/graph.py +94 -0
  13. ml/ppg/graph_util.py +193 -0
  14. ml/ppg/impala_cnn.py +271 -0
  15. ml/ppg/log_save_helper.py +183 -0
  16. ml/ppg/logger.py +522 -0
  17. ml/ppg/minibatch_optimize.py +95 -0
  18. ml/ppg/ppg.py +313 -0
  19. ml/ppg/ppo.py +299 -0
  20. ml/ppg/reward_normalizer.py +105 -0
  21. ml/ppg/roller.py +253 -0
  22. ml/ppg/tic_tac_toe.py +149 -0
  23. ml/ppg/torch_util.py +597 -0
  24. ml/ppg/train.py +190 -0
  25. ml/ppg/tree_util.py +219 -0
  26. ml/ppg/vec_monitor2.py +142 -0
  27. ml/raylib/__init__.py +0 -0
  28. ml/raylib/action_mask.py +202 -0
  29. ml/raylib/environment.py +370 -0
  30. ml/raylib/module_config.py +207 -0
  31. ml/training_data.py +121 -0
  32. ml/transformer.py +267 -0
  33. ml/utils.py +16 -0
  34. rl_language_core-0.3.6.data/data/Scripts/rlc-doc.exe +0 -0
  35. rl_language_core-0.3.6.data/data/Scripts/rlc-lsp.exe +0 -0
  36. rl_language_core-0.3.6.data/data/Scripts/rlc.exe +0 -0
  37. rl_language_core-0.3.6.data/data/lib/fuzzer.lib +0 -0
  38. rl_language_core-0.3.6.data/data/lib/pyrlc.lib +0 -0
  39. rl_language_core-0.3.6.data/data/lib/rlc/stdlib/action.rl +517 -0
  40. rl_language_core-0.3.6.data/data/lib/rlc/stdlib/algorithms/equal.rl +34 -0
  41. rl_language_core-0.3.6.data/data/lib/rlc/stdlib/bounded_arg.rl +347 -0
  42. rl_language_core-0.3.6.data/data/lib/rlc/stdlib/collections/dictionary.rl +317 -0
  43. rl_language_core-0.3.6.data/data/lib/rlc/stdlib/collections/graph.rl +179 -0
  44. rl_language_core-0.3.6.data/data/lib/rlc/stdlib/collections/pair.rl +37 -0
  45. rl_language_core-0.3.6.data/data/lib/rlc/stdlib/collections/vector.rl +242 -0
  46. rl_language_core-0.3.6.data/data/lib/rlc/stdlib/enum_utils.rl +22 -0
  47. rl_language_core-0.3.6.data/data/lib/rlc/stdlib/learn.rl +23 -0
  48. rl_language_core-0.3.6.data/data/lib/rlc/stdlib/machine_learning.rl +66 -0
  49. rl_language_core-0.3.6.data/data/lib/rlc/stdlib/math/numeric.rl +32 -0
  50. rl_language_core-0.3.6.data/data/lib/rlc/stdlib/none.rl +15 -0
  51. rl_language_core-0.3.6.data/data/lib/rlc/stdlib/python.rl +43 -0
  52. rl_language_core-0.3.6.data/data/lib/rlc/stdlib/range.rl +30 -0
  53. rl_language_core-0.3.6.data/data/lib/rlc/stdlib/serialization/key_equal.rl +109 -0
  54. rl_language_core-0.3.6.data/data/lib/rlc/stdlib/serialization/print.rl +37 -0
  55. rl_language_core-0.3.6.data/data/lib/rlc/stdlib/serialization/to_byte_vector.rl +201 -0
  56. rl_language_core-0.3.6.data/data/lib/rlc/stdlib/serialization/to_hash.rl +123 -0
  57. rl_language_core-0.3.6.data/data/lib/rlc/stdlib/string.rl +566 -0
  58. rl_language_core-0.3.6.data/data/lib/runtime.lib +0 -0
  59. rl_language_core-0.3.6.data/data/lib/site-packages/impl/action.py +117 -0
  60. rl_language_core-0.3.6.data/data/lib/site-packages/impl/fix_ray.py +28 -0
  61. rl_language_core-0.3.6.data/data/lib/site-packages/impl/learn.py +118 -0
  62. rl_language_core-0.3.6.data/data/lib/site-packages/impl/llmplayer.py +71 -0
  63. rl_language_core-0.3.6.data/data/lib/site-packages/impl/make_report.py +223 -0
  64. rl_language_core-0.3.6.data/data/lib/site-packages/impl/play.py +78 -0
  65. rl_language_core-0.3.6.data/data/lib/site-packages/impl/probs.py +91 -0
  66. rl_language_core-0.3.6.data/data/lib/site-packages/impl/solve.py +91 -0
  67. rl_language_core-0.3.6.data/data/lib/site-packages/impl/test.py +53 -0
  68. rl_language_core-0.3.6.data/data/share/rlc/cmake/rlcConfig.cmake +101 -0
  69. rl_language_core-0.3.6.dist-info/METADATA +25 -0
  70. rl_language_core-0.3.6.dist-info/RECORD +79 -0
  71. rl_language_core-0.3.6.dist-info/WHEEL +5 -0
  72. rl_language_core-0.3.6.dist-info/entry_points.txt +9 -0
  73. rl_language_core-0.3.6.dist-info/top_level.txt +4 -0
  74. rlc/__init__.py +12 -0
  75. rlc/llm_runner.py +174 -0
  76. rlc/program.py +341 -0
  77. rlc/program_graph.py +122 -0
  78. test/__init__.py +9 -0
  79. test/example_test.py +11 -0
@@ -0,0 +1,14 @@
1
+ #
2
+ # This file is part of the RLC project.
3
+ #
4
+ # RLC is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation.
5
+ #
6
+ # RLC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
7
+ #
8
+ # You should have received a copy of the GNU General Public License along with RLC. If not, see <https://www.gnu.org/licenses/>.
9
+ #
10
+ from .utils import (
11
+ make_rlc_argparse,
12
+ load_program_from_args,
13
+ get_included_conents_from_args,
14
+ )
command_line/utils.py ADDED
@@ -0,0 +1,107 @@
1
+ #
2
+ # This file is part of the RLC project.
3
+ #
4
+ # RLC is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation.
5
+ #
6
+ # RLC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
7
+ #
8
+ # You should have received a copy of the GNU General Public License along with RLC. If not, see <https://www.gnu.org/licenses/>.
9
+ #
10
+ from shutil import which
11
+ import argparse
12
+ from rlc import Program, State, compile, get_included_contents
13
+ import pickle
14
+ import torch
15
+ import pathlib
16
+
17
+
18
+ def make_rlc_argparse(name, description):
19
+ parser = argparse.ArgumentParser(name, description=description)
20
+ parser.add_argument(
21
+ "source_file",
22
+ type=str,
23
+ help="path to .rl source file, or to a python wrapper obtained with rlc --python",
24
+ )
25
+ parser.add_argument(
26
+ "--include",
27
+ "-i",
28
+ type=str,
29
+ nargs="*",
30
+ help="path to folder where rl files can be found",
31
+ default=[],
32
+ )
33
+ parser.add_argument(
34
+ "--stdlib",
35
+ type=str,
36
+ nargs="?",
37
+ help="path to stdlib",
38
+ default=None,
39
+ )
40
+ parser.add_argument(
41
+ "--pyrlc",
42
+ type=str,
43
+ nargs="?",
44
+ help="path to pyrlc lib",
45
+ default=None,
46
+ )
47
+ parser.add_argument(
48
+ "--rlc",
49
+ "-c",
50
+ type=str,
51
+ nargs="?",
52
+ help="path to rlc compiler",
53
+ default="rlc",
54
+ )
55
+ parser.add_argument(
56
+ "--runtime",
57
+ "-rt",
58
+ type=str,
59
+ default="",
60
+ nargs="?",
61
+ help="path to runtime library",
62
+ )
63
+ parser.add_argument(
64
+ "--extra-rlc-args",
65
+ "-args",
66
+ type=str,
67
+ default="",
68
+ nargs="?",
69
+ help="extra args to send to rlc",
70
+ )
71
+ return parser
72
+
73
+
74
+ def get_included_conents_from_args(args):
75
+ return get_included_contents(
76
+ rl_file=args.source_file,
77
+ exclude_stdlib=True,
78
+ rlc_compiler=args.rlc,
79
+ rlc_includes=[include for include in args.include],
80
+ stdlib=args.stdlib,
81
+ )
82
+
83
+
84
+ def load_program_from_args(
85
+ args, optimize=False, extra_source_files=[], gen_python_methods=True
86
+ ):
87
+ assert (
88
+ which(args.rlc) is not None
89
+ ), "could not find executable {}, use --rlc <path_to_rlc> to configure it".format(
90
+ args.rlc
91
+ )
92
+
93
+ if args.source_file.endswith(".py"):
94
+ return Program(args.source_file)
95
+ else:
96
+ includes = [include for include in args.include]
97
+ return compile(
98
+ [args.source_file] + extra_source_files,
99
+ args.rlc,
100
+ includes,
101
+ args.runtime,
102
+ optimized=optimize,
103
+ stdlib=args.stdlib,
104
+ pyrlc_runtime_lib=args.pyrlc,
105
+ gen_python_methods=gen_python_methods,
106
+ extra_rlc_args=args.extra_rlc_args.split(" "),
107
+ )
loader/__init__.py ADDED
@@ -0,0 +1,10 @@
1
+ #
2
+ # This file is part of the RLC project.
3
+ #
4
+ # RLC is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation.
5
+ #
6
+ # RLC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
7
+ #
8
+ # You should have received a copy of the GNU General Public License along with RLC. If not, see <https://www.gnu.org/licenses/>.
9
+ #
10
+ from .simulation import Simulation, Action, State, compile
loader/simulation.py ADDED
@@ -0,0 +1,286 @@
1
+ #
2
+ # Copyright 2024 Massimo Fioravanti
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+ from importlib import import_module, machinery, util
17
+ import os
18
+ import inspect
19
+ from math import log2, ceil, floor
20
+ from pathlib import Path
21
+ from collections import defaultdict
22
+ from tempfile import mkdtemp
23
+ from subprocess import run
24
+ from ctypes import Structure, Array
25
+ from sys import stdout, stderr
26
+
27
+ loaded_libs = {}
28
+
29
+ def import_file(name, file_path):
30
+ if name in loaded_libs:
31
+ return loaded_libs[name]
32
+ loader = machinery.SourceFileLoader(name, file_path)
33
+ spec = util.spec_from_loader(name, loader)
34
+ mod = util.module_from_spec(spec)
35
+ loader.exec_module(mod)
36
+ loaded_libs[name] = mod
37
+ return mod
38
+
39
+
40
+ class Action:
41
+ def __init__(self, action, simulation):
42
+ self.action = action
43
+ self.simulation = simulation
44
+ self.functions = simulation.module.functions
45
+
46
+ def __str__(self) -> str:
47
+ return self.simulation.to_python_string(self.functions.to_string(self.action))
48
+
49
+ def to_bytes(self) -> bytes:
50
+ result = self.functions.as_byte_vector(self.action)
51
+ real_content = []
52
+ for i in range(getattr(result, "__size")):
53
+ real_content.append(getattr(result, "__data")[i] + 128)
54
+ return bytes(real_content)
55
+
56
+ def can_run(self, state) -> bool:
57
+ return self.functions.can_apply(self.action, state.state).value
58
+
59
+ def run(self, state):
60
+ self.functions.apply(self.action, state.state)
61
+ return state
62
+
63
+ def copy(self):
64
+ return Action(self.state.copy(), self.simulation)
65
+
66
+
67
+ class ActionType:
68
+ def __init__(self, action_type, action_id, simulation):
69
+ self.simulation = simulation
70
+ self.action_type = action_type
71
+ self.action_id = action_id
72
+
73
+ def get_arg_min_maxs(self):
74
+ return [(0, 3), (0, 3)]
75
+
76
+ def materialize(self, *args):
77
+ empty_action = Action(self.simulation.any_action(), self.simulation)
78
+ current_action = self.action_type()
79
+ for (name, type), value in zip(getattr(current_action, "_fields_"), args):
80
+ setattr(current_action, name, value)
81
+
82
+ self.simulation.module.functions.assign(empty_action.action, current_action)
83
+ return empty_action
84
+
85
+
86
+ class State:
87
+ def __init__(self, simulation, state):
88
+ self.simulation = simulation
89
+ self.state = state
90
+
91
+ def copy(self):
92
+ return State(self.simulation, self.state.copy())
93
+
94
+ def is_done(self) -> bool:
95
+ return self.state.resume_index == -1
96
+
97
+ def __str__(self) -> str:
98
+ return self.simulation.to_python_string(
99
+ self.simulation.module.functions.to_string(self.state)
100
+ )
101
+
102
+ def from_string(self, string: str) -> bool:
103
+ rl_string = self.simulation.to_rl_string(str)
104
+ return self.simulation.module.functions.from_string(self.state, rl_string)
105
+
106
+ @property
107
+ def actions(self) -> [Action]:
108
+ return self.simulation.get_actions()
109
+
110
+ def as_byte_vector(self):
111
+ result = self.simulation.module.functions.as_byte_vector(self.state)
112
+ real_content = []
113
+ for i in range(getattr(result, "__size")):
114
+ real_content.append(getattr(result, "__data")[i] + 128)
115
+ return bytes(real_content)
116
+
117
+ def from_byte_vector(self, byte_vector):
118
+ vector = self.simulation.module.VectorTint8_tT()
119
+ for byte in byte_vector:
120
+ self.simulation.module.functions.append(vector, byte - 128)
121
+ self.simulation.module.functions.from_byte_vector(self.state, vector)
122
+
123
+ def write_binary(self, path: str):
124
+ with open(path, mode="wb") as file:
125
+ file.write(self.as_byte_vector())
126
+ file.flush()
127
+
128
+ def load_binary(self, path: str):
129
+ with open(path, mode="rb") as file:
130
+ bytes = file.read()
131
+ self.from_byte_vector(bytes)
132
+
133
+ def load(self, path: str) -> bool:
134
+ with open(path, mode="r") as file:
135
+ bytes = file.read()
136
+ return self.from_string(bytes)
137
+
138
+ def score(self):
139
+ return self.state.score
140
+
141
+
142
+ class Simulation:
143
+ def __init__(self, wrapper: str, tmp_dir=None):
144
+ self.wrapper_path = wrapper
145
+ self.module = import_file("sim", wrapper)
146
+ self.tmp_dir = tmp_dir
147
+
148
+ if "play" in self.module.actionToAnyFunctionType:
149
+ self.any_action = self.module.actionToAnyFunctionType["play"]
150
+ any_action_union = getattr(self.any_action(), "content")
151
+ alternatives = getattr(any_action_union, "_fields_")
152
+
153
+ self.actions = [
154
+ ActionType(action_type, i, self)
155
+ for (i, (_, action_type)) in enumerate(alternatives)
156
+ ]
157
+
158
+ def get_class(self, name):
159
+ return getattr(self.module, name)
160
+
161
+ def get_all_actions(self):
162
+ action = self.module.AnyGameAction()
163
+ actions = self.module.functions.enumerate(action)
164
+ result = []
165
+ for i in range(self.module.functions.size(actions)):
166
+ copy = self.module.AnyGameAction()
167
+ self.module.functions.assign(copy, self.module.functions.get(actions, i).contents)
168
+ result.append(copy)
169
+
170
+
171
+ return result
172
+
173
+ def valid_actions(self, state):
174
+ # Convert NumPy arrays to nested tuples to make them hashable.
175
+ x = []
176
+ for action in self.get_all_actions():
177
+ if self.module.functions.can_apply_impl(action, state):
178
+ x.append(action)
179
+ return x
180
+
181
+ def can_apply_action(self, action, state):
182
+ return self.module.functions.can_apply_impl(action, state)
183
+
184
+
185
+ def start(self, name: str, *args):
186
+ return State(self, getattr(self.module.functions, name)(*args))
187
+
188
+ def parse_action(self, action: str) -> Action:
189
+ any_action = self.module.actionToAnyFunctionType["play"]()
190
+ rl_string = self.to_rl_string(action)
191
+ if self.module.functions.from_string(any_action, rl_string):
192
+ return Action(any_action, self)
193
+ else:
194
+ return None
195
+
196
+ def parse_actions_from_binary_buffer(self, actions: bytes) -> [list]:
197
+ vector = self._bytes_to_byte_vector(actions)
198
+ any_action = self.module.actionToAnyFunctionType["play"]()
199
+ vec = self.module.functions.parse_actions(any_action, vector)
200
+ to_return = []
201
+ for i in range(getattr(vec, "__size")):
202
+ to_return.append(getattr(vec, "__data")[i])
203
+ return to_return
204
+
205
+ def _bytes_to_byte_vector(self, byte_vector: bytes):
206
+ vector = self.module.VectorTint8_tT()
207
+ for byte in byte_vector:
208
+ self.module.functions.append(vector, byte)
209
+ return vector
210
+
211
+ @property
212
+ def action_names(self) -> [str]:
213
+ return [name for name in self.module.actions.keys()]
214
+
215
+ def dump(self):
216
+ for name in self.action_names:
217
+ print(name)
218
+
219
+ def to_rl_string(self, string):
220
+ return self.module.rl_s__strlit_r_String(string)
221
+
222
+ def to_python_string(self, string):
223
+ first_character = getattr(getattr(string, "__data"), "__data")
224
+ return self.module.cast(first_character, self.module.c_char_p).value.decode(
225
+ "utf-8"
226
+ )
227
+
228
+ def action_from_string(self, string: str) -> Action:
229
+ rl_string = self.to_rl_string(str)
230
+ action = self.any_action()
231
+ if not self.module.functions.from_string(action, rl_string):
232
+ return None
233
+ return Action(action, self)
234
+
235
+ def action_from_byte_vector(self, byte_vector) -> Action:
236
+ action = self.any_action()
237
+ vector = self.module.VectorTint8_tT()
238
+ for byte in byte_vector:
239
+ self.module.functions.append(vector, byte - 128)
240
+ if not self.module.functions.parse_action_optimized(action, vector, 0):
241
+ return None
242
+ return Action(action, self)
243
+
244
+ def __enter__(self):
245
+ return self
246
+
247
+ def cleanup(self):
248
+ self.__exit__()
249
+
250
+ def __exit__(self, *args):
251
+ import ctypes
252
+ import _ctypes
253
+ libHandle = self.module.lib._handle
254
+
255
+
256
+ @property
257
+ def functions(self):
258
+ return self.module.functions
259
+
260
+
261
+ def compile(sources=[], rlc_compiler="rlc", rlc_includes=[], rlc_runtime_lib="", optimized=True):
262
+ include_args = []
263
+ for arg in rlc_includes:
264
+ include_args.append("-i")
265
+ include_args.append(arg)
266
+ tmp_dir = mkdtemp()
267
+ assert (
268
+ run(
269
+ [
270
+ rlc_compiler,
271
+ *sources,
272
+ "--python",
273
+ "-o",
274
+ Path(tmp_dir) / Path("wrapper.py"),
275
+ "-O2" if optimized else "",
276
+ ]
277
+ + include_args
278
+ ).returncode
279
+ == 0
280
+ )
281
+ lib_name = "lib.dll" if os.name == "nt" else "lib.so"
282
+ args = [rlc_compiler, *sources, "--shared", "-o", Path(tmp_dir) / Path(lib_name), "-O2" if optimized else ""]
283
+ if rlc_runtime_lib != "":
284
+ args = args + ["--runtime-lib", rlc_runtime_lib]
285
+ assert run(args + include_args).returncode == 0
286
+ return Simulation(str(Path(tmp_dir) / Path("wrapper.py")), tmp_dir)
ml/__init__.py ADDED
@@ -0,0 +1,9 @@
1
+ #
2
+ # This file is part of the RLC project.
3
+ #
4
+ # RLC is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation.
5
+ #
6
+ # RLC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
7
+ #
8
+ # You should have received a copy of the GNU General Public License along with RLC. If not, see <https://www.gnu.org/licenses/>.
9
+ #
ml/action_oracle.py ADDED
@@ -0,0 +1,61 @@
1
+ #
2
+ # Copyright 2024 Massimo Fioravanti
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+ from loader import State
17
+ import torch
18
+ from ml import RLCTransformer, run_once
19
+
20
+
21
+ class ActionOracle:
22
+ def __init__(self, transformer: RLCTransformer, action_table):
23
+ self.transformer = transformer
24
+ self.action_table = action_table
25
+
26
+ def __call__(self, states: State):
27
+ non_null_states = [state for state in states if state is not None]
28
+ tensor = (
29
+ torch.IntTensor(
30
+ [[int(x) for x in state.as_byte_vector()] for state in non_null_states]
31
+ )
32
+ .t()
33
+ .to(self.transformer.device)
34
+ )
35
+ result_bytes = run_once(
36
+ self.transformer.model,
37
+ tensor,
38
+ True,
39
+ 3,
40
+ self.transformer.device,
41
+ self.transformer.ntokens,
42
+ )
43
+
44
+ result = []
45
+ index = 0
46
+ for state in states:
47
+ if state is None:
48
+ result.append(None)
49
+ else:
50
+ num = result_bytes[0, index]
51
+ num = num % len(self.action_table)
52
+ if num >= len(self.action_table) or num < 0:
53
+ result.append(None)
54
+ else:
55
+ action = self.action_table[num]
56
+ if not action.can_run(state):
57
+ result.append(None)
58
+ else:
59
+ result.append(action)
60
+ index = index + 1
61
+ return result