tinybaselines 0.1.0a4__tar.gz → 0.1.0a5__tar.gz
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.
- tinybaselines-0.1.0a5/MANIFEST.in +1 -0
- {tinybaselines-0.1.0a4/tinybaselines.egg-info → tinybaselines-0.1.0a5}/PKG-INFO +6 -2
- {tinybaselines-0.1.0a4 → tinybaselines-0.1.0a5}/README.md +5 -1
- tinybaselines-0.1.0a5/examples/cartpole/README.md +5 -0
- tinybaselines-0.1.0a5/examples/cartpole/checkpoint.png +0 -0
- tinybaselines-0.1.0a5/examples/lunar_lander/README.md +6 -0
- tinybaselines-0.1.0a5/examples/lunar_lander/checkpoint.png +0 -0
- tinybaselines-0.1.0a5/examples/pendulum/README.md +6 -0
- tinybaselines-0.1.0a5/examples/pendulum/checkpoint.png +0 -0
- tinybaselines-0.1.0a5/examples/puffer/README.md +57 -0
- tinybaselines-0.1.0a5/examples/puffer/checkpoint.png +0 -0
- tinybaselines-0.1.0a5/examples/puffer/env.py +83 -0
- tinybaselines-0.1.0a5/examples/puffer/results/observations.jsonl +10 -0
- tinybaselines-0.1.0a5/examples/puffer/smoke.py +43 -0
- tinybaselines-0.1.0a5/examples/puffer/squared_bridge.c +17 -0
- tinybaselines-0.1.0a5/examples/puffer/squared_smoke.c +39 -0
- tinybaselines-0.1.0a5/examples/puffer/train.py +66 -0
- {tinybaselines-0.1.0a4 → tinybaselines-0.1.0a5}/pyproject.toml +1 -1
- {tinybaselines-0.1.0a4 → tinybaselines-0.1.0a5/tinybaselines.egg-info}/PKG-INFO +6 -2
- {tinybaselines-0.1.0a4 → tinybaselines-0.1.0a5}/tinybaselines.egg-info/SOURCES.txt +14 -0
- tinybaselines-0.1.0a4/MANIFEST.in +0 -1
- {tinybaselines-0.1.0a4 → tinybaselines-0.1.0a5}/LICENSE +0 -0
- {tinybaselines-0.1.0a4 → tinybaselines-0.1.0a5}/examples/__init__.py +0 -0
- {tinybaselines-0.1.0a4 → tinybaselines-0.1.0a5}/examples/cartpole/results/cpu.jsonl +0 -0
- {tinybaselines-0.1.0a4 → tinybaselines-0.1.0a5}/examples/cartpole/train.py +0 -0
- {tinybaselines-0.1.0a4 → tinybaselines-0.1.0a5}/examples/lunar_lander/__init__.py +0 -0
- {tinybaselines-0.1.0a4 → tinybaselines-0.1.0a5}/examples/lunar_lander/config.py +0 -0
- {tinybaselines-0.1.0a4 → tinybaselines-0.1.0a5}/examples/lunar_lander/reference.py +0 -0
- {tinybaselines-0.1.0a4 → tinybaselines-0.1.0a5}/examples/lunar_lander/requirements-reference.txt +0 -0
- {tinybaselines-0.1.0a4 → tinybaselines-0.1.0a5}/examples/lunar_lander/requirements.txt +0 -0
- {tinybaselines-0.1.0a4 → tinybaselines-0.1.0a5}/examples/lunar_lander/results/2026-10-26/phase-initial-tinygrad-thread4.jsonl +0 -0
- {tinybaselines-0.1.0a4 → tinybaselines-0.1.0a5}/examples/lunar_lander/results/2026-10-26/phase-initial-torch.jsonl +0 -0
- {tinybaselines-0.1.0a4 → tinybaselines-0.1.0a5}/examples/lunar_lander/results/2026-10-26/phase-protocol.json +0 -0
- {tinybaselines-0.1.0a4 → tinybaselines-0.1.0a5}/examples/lunar_lander/results/2026-10-26/phase-tinygrad-thread10.jsonl +0 -0
- {tinybaselines-0.1.0a4 → tinybaselines-0.1.0a5}/examples/lunar_lander/results/2026-10-26/phase-tinygrad-thread4-error.jsonl +0 -0
- {tinybaselines-0.1.0a4 → tinybaselines-0.1.0a5}/examples/lunar_lander/results/2026-10-26/phase-torch-thread4.jsonl +0 -0
- {tinybaselines-0.1.0a4 → tinybaselines-0.1.0a5}/examples/lunar_lander/results/2026-10-26/protocol.json +0 -0
- {tinybaselines-0.1.0a4 → tinybaselines-0.1.0a5}/examples/lunar_lander/results/2026-10-26/tinygrad-cpu.jsonl +0 -0
- {tinybaselines-0.1.0a4 → tinybaselines-0.1.0a5}/examples/lunar_lander/results/2026-10-26/torch-cpu.jsonl +0 -0
- {tinybaselines-0.1.0a4 → tinybaselines-0.1.0a5}/examples/lunar_lander/results/cpu-padding.jsonl +0 -0
- {tinybaselines-0.1.0a4 → tinybaselines-0.1.0a5}/examples/lunar_lander/run_learning.py +0 -0
- {tinybaselines-0.1.0a4 → tinybaselines-0.1.0a5}/examples/lunar_lander/train.py +0 -0
- {tinybaselines-0.1.0a4 → tinybaselines-0.1.0a5}/examples/pendulum/__init__.py +0 -0
- {tinybaselines-0.1.0a4 → tinybaselines-0.1.0a5}/examples/pendulum/env.py +0 -0
- {tinybaselines-0.1.0a4 → tinybaselines-0.1.0a5}/examples/pendulum/requirements.txt +0 -0
- {tinybaselines-0.1.0a4 → tinybaselines-0.1.0a5}/examples/pendulum/results/cpu-2.jsonl +0 -0
- {tinybaselines-0.1.0a4 → tinybaselines-0.1.0a5}/examples/pendulum/results/cpu-3.jsonl +0 -0
- {tinybaselines-0.1.0a4 → tinybaselines-0.1.0a5}/examples/pendulum/results/cpu.jsonl +0 -0
- {tinybaselines-0.1.0a4 → tinybaselines-0.1.0a5}/examples/pendulum/train.py +0 -0
- {tinybaselines-0.1.0a4 → tinybaselines-0.1.0a5}/requirements.txt +0 -0
- {tinybaselines-0.1.0a4 → tinybaselines-0.1.0a5}/setup.cfg +0 -0
- {tinybaselines-0.1.0a4 → tinybaselines-0.1.0a5}/tests/test_cartpole.py +0 -0
- {tinybaselines-0.1.0a4 → tinybaselines-0.1.0a5}/tests/test_checkpoint.py +0 -0
- {tinybaselines-0.1.0a4 → tinybaselines-0.1.0a5}/tests/test_core.py +0 -0
- {tinybaselines-0.1.0a4 → tinybaselines-0.1.0a5}/tests/test_evaluation.py +0 -0
- {tinybaselines-0.1.0a4 → tinybaselines-0.1.0a5}/tests/test_learning.py +0 -0
- {tinybaselines-0.1.0a4 → tinybaselines-0.1.0a5}/tests/test_learning_run.py +0 -0
- {tinybaselines-0.1.0a4 → tinybaselines-0.1.0a5}/tests/test_parity.py +0 -0
- {tinybaselines-0.1.0a4 → tinybaselines-0.1.0a5}/tests/test_pendulum.py +0 -0
- {tinybaselines-0.1.0a4 → tinybaselines-0.1.0a5}/tests/test_rollout.py +0 -0
- {tinybaselines-0.1.0a4 → tinybaselines-0.1.0a5}/tests/test_training.py +0 -0
- {tinybaselines-0.1.0a4 → tinybaselines-0.1.0a5}/tinybaselines/__init__.py +0 -0
- {tinybaselines-0.1.0a4 → tinybaselines-0.1.0a5}/tinybaselines/evaluation.py +0 -0
- {tinybaselines-0.1.0a4 → tinybaselines-0.1.0a5}/tinybaselines/policies.py +0 -0
- {tinybaselines-0.1.0a4 → tinybaselines-0.1.0a5}/tinybaselines/ppo.py +0 -0
- {tinybaselines-0.1.0a4 → tinybaselines-0.1.0a5}/tinybaselines/rollout.py +0 -0
- {tinybaselines-0.1.0a4 → tinybaselines-0.1.0a5}/tinybaselines/training.py +0 -0
- {tinybaselines-0.1.0a4 → tinybaselines-0.1.0a5}/tinybaselines.egg-info/dependency_links.txt +0 -0
- {tinybaselines-0.1.0a4 → tinybaselines-0.1.0a5}/tinybaselines.egg-info/requires.txt +0 -0
- {tinybaselines-0.1.0a4 → tinybaselines-0.1.0a5}/tinybaselines.egg-info/top_level.txt +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
recursive-include examples *.py *.txt *.json *.jsonl *.c *.png README.md
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: tinybaselines
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.0a5
|
|
4
4
|
Summary: PPO in tinygrad.
|
|
5
5
|
License-Expression: MIT
|
|
6
6
|
Requires-Python: >=3.11
|
|
@@ -21,7 +21,7 @@ Use Python 3.11 and clang. The library install does not include Gymnasium.
|
|
|
21
21
|
```sh
|
|
22
22
|
python3.11 -m venv .venv
|
|
23
23
|
source .venv/bin/activate
|
|
24
|
-
python -m pip install tinybaselines==0.1.
|
|
24
|
+
python -m pip install tinybaselines==0.1.0a5
|
|
25
25
|
```
|
|
26
26
|
|
|
27
27
|
Install Gymnasium and Box2D to run this example:
|
|
@@ -79,6 +79,10 @@ Each `learn` call starts fresh episodes and a new transition counter.
|
|
|
79
79
|
|
|
80
80
|
## Repository examples
|
|
81
81
|
|
|
82
|
+
Example READMEs and screenshots: [LunarLander](examples/lunar_lander/README.md),
|
|
83
|
+
[CartPole](examples/cartpole/README.md), [Pendulum](examples/pendulum/README.md),
|
|
84
|
+
and [Squared Continuous](examples/puffer/README.md).
|
|
85
|
+
|
|
82
86
|
From a checkout, run the full LunarLander trainer:
|
|
83
87
|
|
|
84
88
|
```sh
|
|
@@ -9,7 +9,7 @@ Use Python 3.11 and clang. The library install does not include Gymnasium.
|
|
|
9
9
|
```sh
|
|
10
10
|
python3.11 -m venv .venv
|
|
11
11
|
source .venv/bin/activate
|
|
12
|
-
python -m pip install tinybaselines==0.1.
|
|
12
|
+
python -m pip install tinybaselines==0.1.0a5
|
|
13
13
|
```
|
|
14
14
|
|
|
15
15
|
Install Gymnasium and Box2D to run this example:
|
|
@@ -67,6 +67,10 @@ Each `learn` call starts fresh episodes and a new transition counter.
|
|
|
67
67
|
|
|
68
68
|
## Repository examples
|
|
69
69
|
|
|
70
|
+
Example READMEs and screenshots: [LunarLander](examples/lunar_lander/README.md),
|
|
71
|
+
[CartPole](examples/cartpole/README.md), [Pendulum](examples/pendulum/README.md),
|
|
72
|
+
and [Squared Continuous](examples/puffer/README.md).
|
|
73
|
+
|
|
70
74
|
From a checkout, run the full LunarLander trainer:
|
|
71
75
|
|
|
72
76
|
```sh
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# PufferLib Squared Continuous
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+
|
|
5
|
+
Live board one move before the reloaded PPO policy earned +1. The next step
|
|
6
|
+
reached the target and reset the board.
|
|
7
|
+
|
|
8
|
+
Native CPU smoke test on macOS. It calls PufferLib's reset and step functions
|
|
9
|
+
directly and opens no window. Run from the tinybaselines checkout:
|
|
10
|
+
|
|
11
|
+
```sh
|
|
12
|
+
puffer_smoke=$(mktemp -d)
|
|
13
|
+
git init "$puffer_smoke/pufferlib"
|
|
14
|
+
git -C "$puffer_smoke/pufferlib" fetch --depth=1 https://github.com/PufferAI/PufferLib.git ea7f989371270d2948f96728bda8aec5e7634a4c
|
|
15
|
+
git -C "$puffer_smoke/pufferlib" checkout --detach FETCH_HEAD
|
|
16
|
+
curl -fL https://github.com/raysan5/raylib/releases/download/5.5/raylib-5.5_macos.tar.gz \
|
|
17
|
+
-o "$puffer_smoke/raylib.tar.gz"
|
|
18
|
+
tar -xzf "$puffer_smoke/raylib.tar.gz" -C "$puffer_smoke"
|
|
19
|
+
clang -O2 -I"$puffer_smoke/pufferlib" -I"$puffer_smoke/pufferlib/src" \
|
|
20
|
+
-I"$puffer_smoke/raylib-5.5_macos/include" examples/puffer/squared_smoke.c \
|
|
21
|
+
"$puffer_smoke/raylib-5.5_macos/lib/libraylib.a" \
|
|
22
|
+
-framework Cocoa -framework IOKit -framework CoreVideo -framework OpenGL \
|
|
23
|
+
-o "$puffer_smoke/squared_smoke"
|
|
24
|
+
"$puffer_smoke/squared_smoke"
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
With tinybaselines installed, build the Python adapter's shared library and run
|
|
28
|
+
its reset checks and one PPO update:
|
|
29
|
+
|
|
30
|
+
```sh
|
|
31
|
+
clang -O2 -dynamiclib -I"$puffer_smoke/pufferlib" -I"$puffer_smoke/pufferlib/src" \
|
|
32
|
+
-I"$puffer_smoke/raylib-5.5_macos/include" examples/puffer/squared_bridge.c \
|
|
33
|
+
"$puffer_smoke/raylib-5.5_macos/lib/libraylib.a" \
|
|
34
|
+
-framework Cocoa -framework IOKit -framework CoreVideo -framework OpenGL \
|
|
35
|
+
-o "$puffer_smoke/libsquared.dylib"
|
|
36
|
+
DEV=CPU BEAM=0 python -m examples.puffer.smoke "$puffer_smoke/libsquared.dylib"
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Train for 204,800 transitions across four environments:
|
|
40
|
+
|
|
41
|
+
```sh
|
|
42
|
+
DEV=CPU BEAM=0 python -m examples.puffer.train "$puffer_smoke/libsquared.dylib" \
|
|
43
|
+
--output runs/puffer-squared-ppo
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
The run saves `ppo.safetensors` and records goals over 100 sampled episodes
|
|
47
|
+
before training and after checkpoint reload.
|
|
48
|
+
|
|
49
|
+
The default observation is the centered agent and target coordinates, divided by
|
|
50
|
+
5. Use `--observations board` for the flat grid or `--observations relative` for
|
|
51
|
+
the agent coordinates and signed target offset. Use the same observation mode
|
|
52
|
+
when evaluating a saved policy.
|
|
53
|
+
|
|
54
|
+
At the same budget, three runs per mode reached 56/300 goals with the board,
|
|
55
|
+
299/300 with absolute coordinates, and 296/300 with relative coordinates. Each
|
|
56
|
+
score uses 100 fresh sampled episodes per reloaded checkpoint.
|
|
57
|
+
[Settings and episode returns](results/observations.jsonl).
|
|
Binary file
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
from ctypes import CDLL, c_uint, c_void_p
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class SquaredVectorEnv:
|
|
7
|
+
"""Headless native environments. Observations and rewards reuse their buffers."""
|
|
8
|
+
|
|
9
|
+
metadata = {'autoreset_mode': 'SameStep'}
|
|
10
|
+
|
|
11
|
+
def __init__(self, library, num_envs=4):
|
|
12
|
+
if num_envs <= 0:
|
|
13
|
+
raise ValueError('num_envs must be positive')
|
|
14
|
+
self.num_envs = num_envs
|
|
15
|
+
self._lib = CDLL(str(library))
|
|
16
|
+
self._lib.squared_create.argtypes = [c_void_p] * 4 + [c_uint]
|
|
17
|
+
self._lib.squared_create.restype = c_void_p
|
|
18
|
+
for name in ('puf_reset', 'puf_step', 'squared_destroy'):
|
|
19
|
+
function = getattr(self._lib, name)
|
|
20
|
+
function.argtypes = [c_void_p]
|
|
21
|
+
function.restype = None
|
|
22
|
+
|
|
23
|
+
self._observations = np.empty((num_envs, 121), dtype=np.uint8)
|
|
24
|
+
self._actions = np.zeros((num_envs, 2), dtype=np.float32)
|
|
25
|
+
self._rewards = np.zeros(num_envs, dtype=np.float32)
|
|
26
|
+
self._terminals = np.zeros(num_envs, dtype=np.float32)
|
|
27
|
+
self._envs = []
|
|
28
|
+
try:
|
|
29
|
+
for i, seed in enumerate(np.random.SeedSequence().generate_state(num_envs)):
|
|
30
|
+
handle = self._lib.squared_create(
|
|
31
|
+
self._observations[i].ctypes.data, self._actions[i].ctypes.data,
|
|
32
|
+
self._rewards[i:i+1].ctypes.data, self._terminals[i:i+1].ctypes.data, int(seed))
|
|
33
|
+
if not handle:
|
|
34
|
+
raise MemoryError('could not allocate Squared Continuous')
|
|
35
|
+
self._envs.append(handle)
|
|
36
|
+
except BaseException:
|
|
37
|
+
self.close()
|
|
38
|
+
raise
|
|
39
|
+
|
|
40
|
+
def reset(self):
|
|
41
|
+
if not self._envs:
|
|
42
|
+
raise RuntimeError('environment is closed')
|
|
43
|
+
for handle in self._envs:
|
|
44
|
+
self._lib.puf_reset(handle)
|
|
45
|
+
self._rewards.fill(0)
|
|
46
|
+
self._terminals.fill(0)
|
|
47
|
+
return self._observations, {}
|
|
48
|
+
|
|
49
|
+
def step(self, actions):
|
|
50
|
+
if not self._envs:
|
|
51
|
+
raise RuntimeError('environment is closed')
|
|
52
|
+
self._actions[:] = actions
|
|
53
|
+
for handle in self._envs:
|
|
54
|
+
self._lib.puf_step(handle)
|
|
55
|
+
# The native timeout is a terminal loss, with an immediate reset.
|
|
56
|
+
return self._observations, self._rewards, self._terminals.astype(bool), np.zeros(self.num_envs, bool), {}
|
|
57
|
+
|
|
58
|
+
def close(self):
|
|
59
|
+
for handle in self._envs:
|
|
60
|
+
self._lib.squared_destroy(handle)
|
|
61
|
+
self._envs.clear()
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
class CoordinateSquaredVectorEnv(SquaredVectorEnv):
|
|
65
|
+
def __init__(self, library, num_envs=4, *, relative):
|
|
66
|
+
super().__init__(library, num_envs)
|
|
67
|
+
self.relative = relative
|
|
68
|
+
|
|
69
|
+
def _observe(self, board):
|
|
70
|
+
def position(tile):
|
|
71
|
+
return np.column_stack(np.divmod((board == tile).argmax(axis=1), 11))
|
|
72
|
+
|
|
73
|
+
agent, target = position(1), position(2)
|
|
74
|
+
target_features = target - agent if self.relative else target - 5
|
|
75
|
+
return np.concatenate((agent - 5, target_features), axis=1).astype(np.float32) / 5
|
|
76
|
+
|
|
77
|
+
def reset(self):
|
|
78
|
+
board, info = super().reset()
|
|
79
|
+
return self._observe(board), info
|
|
80
|
+
|
|
81
|
+
def step(self, actions):
|
|
82
|
+
board, *transition = super().step(actions)
|
|
83
|
+
return self._observe(board), *transition
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{"event":"config","platform":"macOS-27.0.1-arm64-arm-64bit","python":"3.11.14","versions":{"tinygrad":"0.14.0","numpy":"2.4.6"},"library_sha256":"c83b0740db881ebd616282528e4b224a456d92074b7666b156edaff8f744c0c1","device":"CPU","num_envs":4,"requested_timesteps":204800,"rollout_steps":2048,"deterministic":false,"policy":{"action_dim":2,"hidden_dim":64,"actor_layers":2,"critic_layers":2},"ppo":{"pi_lr":0.0003000000142492354,"vf_lr":0.0010000000474974513,"gamma":0.99,"lamda":0.95,"K_epochs":4,"eps_clip":0.2,"batch_size":256,"vf_coef":0.5,"entropy_coef":0.001},"modes":{"board":{"source_commit":"5629a259ba3d9a6f8e1ea93e7b72bc41913eee64","state_dim":121},"relative":{"source_commit":"5629a259ba3d9a6f8e1ea93e7b72bc41913eee64","state_dim":4},"absolute":{"source_commit":"5629a259ba3d9a6f8e1ea93e7b72bc41913eee64","state_dim":4}},"evaluation_episodes":100,"run_order":["board-1","relative-1","relative-2","board-2","board-3","relative-3","absolute-1","absolute-2","absolute-3"]}
|
|
2
|
+
{"event":"result","observations":"board","trial":1,"training_seconds":67.8307276670239,"initial":{"goals":10,"episodes":100,"episode_returns":[-1.0,-1.0,-1.0,-1.0,1.0,-1.0,1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,1.0,-1.0,-1.0,-1.0,-1.0,-1.0,1.0,-1.0,-1.0,-1.0,-1.0,-1.0,1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,1.0,-1.0,-1.0,-1.0,-1.0,1.0,-1.0,-1.0,-1.0,1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,1.0,-1.0,-1.0,-1.0]},"final":{"goals":25,"episodes":100,"episode_returns":[-1.0,1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,1.0,-1.0,1.0,1.0,-1.0,-1.0,1.0,-1.0,-1.0,-1.0,-1.0,-1.0,1.0,-1.0,-1.0,-1.0,1.0,-1.0,1.0,1.0,1.0,-1.0,-1.0,-1.0,-1.0,-1.0,1.0,-1.0,-1.0,-1.0,-1.0,1.0,-1.0,-1.0,1.0,-1.0,-1.0,-1.0,-1.0,-1.0,1.0,-1.0,-1.0,-1.0,1.0,-1.0,-1.0,-1.0,1.0,-1.0,1.0,-1.0,1.0,-1.0,-1.0,-1.0,-1.0,-1.0,1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,1.0,1.0,-1.0,-1.0,-1.0,1.0,1.0,-1.0,1.0,-1.0,-1.0]}}
|
|
3
|
+
{"event":"result","observations":"board","trial":2,"training_seconds":65.84727108303923,"initial":{"goals":4,"episodes":100,"episode_returns":[-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,1.0,-1.0,-1.0,-1.0,1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0]},"final":{"goals":18,"episodes":100,"episode_returns":[1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,1.0,-1.0,1.0,-1.0,1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,1.0,1.0,-1.0,-1.0,-1.0,-1.0,-1.0,1.0,1.0,-1.0,-1.0,-1.0,-1.0,-1.0,1.0,1.0,-1.0,1.0,-1.0,-1.0,-1.0,-1.0,-1.0,1.0,-1.0,1.0,-1.0,-1.0,-1.0,-1.0,1.0,-1.0,-1.0,1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0]}}
|
|
4
|
+
{"event":"result","observations":"board","trial":3,"training_seconds":67.56618995795725,"initial":{"goals":4,"episodes":100,"episode_returns":[-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,1.0,-1.0,-1.0,-1.0,-1.0]},"final":{"goals":13,"episodes":100,"episode_returns":[-1.0,1.0,-1.0,-1.0,-1.0,-1.0,1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,1.0,-1.0,-1.0,-1.0,-1.0,-1.0,1.0,-1.0,-1.0,1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,1.0,-1.0,1.0,-1.0,1.0,-1.0,-1.0,-1.0,-1.0,1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,1.0,-1.0,1.0,-1.0,-1.0,-1.0,-1.0,-1.0,1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0]}}
|
|
5
|
+
{"event":"result","observations":"relative","trial":1,"training_seconds":61.09397924999939,"initial":{"goals":16,"episodes":100,"episode_returns":[-1.0,-1.0,1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,1.0,-1.0,-1.0,1.0,-1.0,-1.0,-1.0,-1.0,-1.0,1.0,-1.0,1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,1.0,1.0,-1.0,-1.0,-1.0,1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,1.0,1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,1.0,-1.0,-1.0,1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,1.0,-1.0,1.0,-1.0,-1.0]},"final":{"goals":99,"episodes":100,"episode_returns":[1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,-1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0]}}
|
|
6
|
+
{"event":"result","observations":"relative","trial":2,"training_seconds":60.07157345901942,"initial":{"goals":16,"episodes":100,"episode_returns":[1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,1.0,-1.0,-1.0,-1.0,-1.0,-1.0,1.0,-1.0,-1.0,1.0,1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,1.0,-1.0,1.0,-1.0,-1.0,1.0,-1.0,-1.0,-1.0,-1.0,1.0,-1.0,1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,1.0,-1.0,-1.0,-1.0,-1.0,1.0,-1.0,1.0,-1.0,1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0]},"final":{"goals":100,"episodes":100,"episode_returns":[1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0]}}
|
|
7
|
+
{"event":"result","observations":"relative","trial":3,"training_seconds":61.71542754204711,"initial":{"goals":10,"episodes":100,"episode_returns":[-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,1.0,1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,1.0,-1.0,-1.0,-1.0,-1.0,-1.0,1.0,-1.0,1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,1.0,-1.0,-1.0,-1.0,-1.0,-1.0,1.0,-1.0,-1.0]},"final":{"goals":97,"episodes":100,"episode_returns":[1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,-1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,-1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,-1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0]}}
|
|
8
|
+
{"event":"result","observations":"absolute","trial":1,"training_seconds":61.760505666956306,"initial":{"goals":13,"episodes":100,"episode_returns":[-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,1.0,-1.0,-1.0,-1.0,-1.0,1.0,-1.0,1.0,-1.0,-1.0,-1.0,-1.0,1.0,-1.0,-1.0,1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,1.0,-1.0,-1.0,-1.0,-1.0,-1.0,1.0,-1.0,-1.0,1.0,-1.0,-1.0,-1.0,-1.0,1.0,-1.0,1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,1.0,-1.0]},"final":{"goals":99,"episodes":100,"episode_returns":[1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,-1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0]}}
|
|
9
|
+
{"event":"result","observations":"absolute","trial":2,"training_seconds":59.79912408301607,"initial":{"goals":16,"episodes":100,"episode_returns":[1.0,1.0,-1.0,1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,1.0,1.0,1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,1.0,1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,1.0,1.0,1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,1.0,-1.0,-1.0,1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,1.0]},"final":{"goals":100,"episodes":100,"episode_returns":[1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0]}}
|
|
10
|
+
{"event":"result","observations":"absolute","trial":3,"training_seconds":60.650998707977124,"initial":{"goals":7,"episodes":100,"episode_returns":[-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,1.0,-1.0,-1.0,1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,1.0,-1.0,-1.0,-1.0,-1.0,1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0]},"final":{"goals":100,"episodes":100,"episode_returns":[1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0]}}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
from contextlib import closing
|
|
3
|
+
|
|
4
|
+
import numpy as np
|
|
5
|
+
|
|
6
|
+
from tinybaselines import GaussianActorCritic, PPO, learn
|
|
7
|
+
from .env import SquaredVectorEnv
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def main(library):
|
|
11
|
+
with closing(SquaredVectorEnv(library)) as env:
|
|
12
|
+
observations, _ = env.reset()
|
|
13
|
+
observations[observations == 2] = 0
|
|
14
|
+
observations[:, 61] = 2 # One tile right of the centered agent.
|
|
15
|
+
actions = np.zeros((4, 2), dtype=np.float32)
|
|
16
|
+
actions[:2, 1] = 1
|
|
17
|
+
observations, rewards, terminated, truncated, _ = env.step(actions)
|
|
18
|
+
np.testing.assert_array_equal(rewards, [1, 1, 0, 0])
|
|
19
|
+
np.testing.assert_array_equal(terminated, [True, True, False, False])
|
|
20
|
+
assert not truncated.any() and np.all(observations[2:, 61] == 2)
|
|
21
|
+
assert np.all(observations[:, 60] == 1)
|
|
22
|
+
env.reset()
|
|
23
|
+
actions.fill(0)
|
|
24
|
+
for _ in range(33):
|
|
25
|
+
_, rewards, terminated, truncated, _ = env.step(actions)
|
|
26
|
+
assert np.all(rewards == 0) and not terminated.any() and not truncated.any()
|
|
27
|
+
observations, rewards, terminated, truncated, _ = env.step(actions)
|
|
28
|
+
assert np.all(rewards == -1) and terminated.all() and not truncated.any()
|
|
29
|
+
assert np.all(observations[:, 60] == 1)
|
|
30
|
+
print('Goal and timeout rewards and terminal flags survive same-step resets.')
|
|
31
|
+
|
|
32
|
+
policy = GaussianActorCritic(121, 2, 16, 1, 1)
|
|
33
|
+
ppo = PPO(policy, pi_lr=1e-3, vf_lr=1e-3, gamma=0.99, lamda=0.95, K_epochs=1,
|
|
34
|
+
eps_clip=0.2, batch_size=256, vf_coef=0.5, entropy_coef=0.01)
|
|
35
|
+
before = policy.log_std.numpy().copy()
|
|
36
|
+
step, = learn(env, ppo, total_timesteps=256, rollout_steps=256)
|
|
37
|
+
assert step.timesteps == 256 and step.episode_returns
|
|
38
|
+
assert np.isfinite(policy.log_std.numpy()).all() and not np.array_equal(policy.log_std.numpy(), before)
|
|
39
|
+
print(f'One PPO update on {step.timesteps} transitions, {len(step.episode_returns)} finished episodes.')
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
if __name__ == '__main__':
|
|
43
|
+
main(sys.argv[1])
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#include "ocean/squared_continuous/squared_continuous.h"
|
|
2
|
+
|
|
3
|
+
Squared* squared_create(obs_t* observations, float* actions, float* reward, float* terminal, unsigned int seed) {
|
|
4
|
+
Squared* env = calloc(1, sizeof(*env));
|
|
5
|
+
if (!env) return NULL;
|
|
6
|
+
DictItem size = {.key = "size", .value = 11};
|
|
7
|
+
Dict options = {.items = &size, .size = 1, .cap = 1};
|
|
8
|
+
env->rng = seed;
|
|
9
|
+
env->agents[0] = (Agent){.observations = observations, .actions = actions,
|
|
10
|
+
.rewards = reward, .terminals = terminal};
|
|
11
|
+
puf_init(env, &options);
|
|
12
|
+
return env;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
void squared_destroy(Squared* env) {
|
|
16
|
+
free(env);
|
|
17
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
#include <assert.h>
|
|
2
|
+
|
|
3
|
+
#include "ocean/squared_continuous/squared_continuous.h"
|
|
4
|
+
|
|
5
|
+
int main(void) {
|
|
6
|
+
obs_t observations[OBS_SIZE] = {0};
|
|
7
|
+
float actions[NUM_ATNS] = {0}, reward = 0, terminal = 0;
|
|
8
|
+
DictItem size = {.key = "size", .value = 11};
|
|
9
|
+
Dict options = {.items = &size, .size = 1, .cap = 1};
|
|
10
|
+
Squared env = {.rng = 1};
|
|
11
|
+
env.agents[0] = (Agent){.observations = observations, .actions = actions,
|
|
12
|
+
.rewards = &reward, .terminals = &terminal};
|
|
13
|
+
puf_init(&env, &options);
|
|
14
|
+
puf_reset(&env);
|
|
15
|
+
|
|
16
|
+
const int center = OBS_SIZE / 2;
|
|
17
|
+
assert(env.num_agents == 1 && observations[center] == AGENT && !IsWindowReady());
|
|
18
|
+
memset(observations, EMPTY, sizeof(observations));
|
|
19
|
+
observations[center] = AGENT;
|
|
20
|
+
observations[center + 1] = TARGET;
|
|
21
|
+
|
|
22
|
+
actions[1] = 0.2f;
|
|
23
|
+
puf_step(&env);
|
|
24
|
+
assert(reward == 0 && terminal == 0 && observations[center] == AGENT);
|
|
25
|
+
actions[1] = 0.3f;
|
|
26
|
+
puf_step(&env);
|
|
27
|
+
assert(reward == 1 && terminal == 1 && env.tick == 0 && observations[center] == AGENT);
|
|
28
|
+
|
|
29
|
+
actions[1] = 0;
|
|
30
|
+
for (int i = 0; i < 3 * env.size; i++) {
|
|
31
|
+
puf_step(&env);
|
|
32
|
+
assert(reward == 0 && terminal == 0);
|
|
33
|
+
}
|
|
34
|
+
puf_step(&env);
|
|
35
|
+
assert(reward == -1 && terminal == 1 && env.tick == 0 && observations[center] == AGENT);
|
|
36
|
+
assert(!IsWindowReady());
|
|
37
|
+
puf_close(&env);
|
|
38
|
+
puts("Squared Continuous: movement threshold, goal, timeout, and same-step reset passed.");
|
|
39
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import argparse
|
|
2
|
+
from contextlib import closing
|
|
3
|
+
from hashlib import sha256
|
|
4
|
+
from importlib.metadata import version
|
|
5
|
+
import json
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
import platform
|
|
8
|
+
import subprocess
|
|
9
|
+
from time import perf_counter
|
|
10
|
+
|
|
11
|
+
from tinybaselines import GaussianActorCritic, PPO, evaluate, learn
|
|
12
|
+
from .env import CoordinateSquaredVectorEnv, SquaredVectorEnv
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def run(library, output, total_timesteps, observations='absolute'):
|
|
16
|
+
output.mkdir(parents=True, exist_ok=False)
|
|
17
|
+
def make_env():
|
|
18
|
+
if observations == 'board':
|
|
19
|
+
return SquaredVectorEnv(library, num_envs=4)
|
|
20
|
+
return CoordinateSquaredVectorEnv(library, num_envs=4, relative=observations == 'relative')
|
|
21
|
+
|
|
22
|
+
state_dim = 121 if observations == 'board' else 4
|
|
23
|
+
policy = GaussianActorCritic(state_dim, 2, 64, 2, 2)
|
|
24
|
+
ppo = PPO(policy, pi_lr=3e-4, vf_lr=1e-3, gamma=0.99, lamda=0.95, K_epochs=4,
|
|
25
|
+
eps_clip=0.2, batch_size=256, vf_coef=0.5, entropy_coef=0.001)
|
|
26
|
+
|
|
27
|
+
with (output / 'metrics.jsonl').open('x') as log:
|
|
28
|
+
def record(event, **fields):
|
|
29
|
+
line = json.dumps(dict(event=event, **fields), allow_nan=False)
|
|
30
|
+
print(line, file=log, flush=True)
|
|
31
|
+
print(line, flush=True)
|
|
32
|
+
|
|
33
|
+
def score(event, actor):
|
|
34
|
+
with closing(make_env()) as env:
|
|
35
|
+
returns = list(map(float, evaluate(env, actor, num_episodes=100, deterministic=False)))
|
|
36
|
+
assert len(returns) == 100 and all(value in (-1, 1) for value in returns)
|
|
37
|
+
record(event, goals=returns.count(1), episodes=len(returns), episode_returns=returns)
|
|
38
|
+
|
|
39
|
+
commit = subprocess.run(['git', 'rev-parse', 'HEAD'], capture_output=True, text=True).stdout.strip()
|
|
40
|
+
record('config', source_commit=commit or None, platform=platform.platform(), python=platform.python_version(),
|
|
41
|
+
versions={name: version(name) for name in ('tinygrad', 'numpy')},
|
|
42
|
+
library_sha256=sha256(library.read_bytes()).hexdigest(), device=ppo.device,
|
|
43
|
+
num_envs=4, requested_timesteps=total_timesteps, rollout_steps=2048,
|
|
44
|
+
deterministic=False, observations=observations, policy=policy.config, ppo=ppo.config)
|
|
45
|
+
score('initial', policy)
|
|
46
|
+
timesteps = 0
|
|
47
|
+
with closing(make_env()) as env:
|
|
48
|
+
started = perf_counter()
|
|
49
|
+
for step in learn(env, ppo, total_timesteps=total_timesteps, rollout_steps=2048):
|
|
50
|
+
timesteps = step.timesteps
|
|
51
|
+
record('update', **step._asdict())
|
|
52
|
+
training_seconds = perf_counter() - started
|
|
53
|
+
checkpoint = output / 'ppo.safetensors'
|
|
54
|
+
ppo.save(checkpoint)
|
|
55
|
+
record('checkpoint', timesteps=timesteps, training_seconds=training_seconds, path=checkpoint.name)
|
|
56
|
+
score('final', PPO.load(checkpoint).actor_critic)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
if __name__ == '__main__':
|
|
60
|
+
parser = argparse.ArgumentParser(description='Train PPO on headless Squared Continuous.')
|
|
61
|
+
parser.add_argument('library', type=Path)
|
|
62
|
+
parser.add_argument('--output', required=True, type=Path)
|
|
63
|
+
parser.add_argument('--timesteps', type=int, default=204_800)
|
|
64
|
+
parser.add_argument('--observations', choices=('board', 'absolute', 'relative'), default='absolute')
|
|
65
|
+
args = parser.parse_args()
|
|
66
|
+
run(args.library, args.output, args.timesteps, args.observations)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: tinybaselines
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.0a5
|
|
4
4
|
Summary: PPO in tinygrad.
|
|
5
5
|
License-Expression: MIT
|
|
6
6
|
Requires-Python: >=3.11
|
|
@@ -21,7 +21,7 @@ Use Python 3.11 and clang. The library install does not include Gymnasium.
|
|
|
21
21
|
```sh
|
|
22
22
|
python3.11 -m venv .venv
|
|
23
23
|
source .venv/bin/activate
|
|
24
|
-
python -m pip install tinybaselines==0.1.
|
|
24
|
+
python -m pip install tinybaselines==0.1.0a5
|
|
25
25
|
```
|
|
26
26
|
|
|
27
27
|
Install Gymnasium and Box2D to run this example:
|
|
@@ -79,6 +79,10 @@ Each `learn` call starts fresh episodes and a new transition counter.
|
|
|
79
79
|
|
|
80
80
|
## Repository examples
|
|
81
81
|
|
|
82
|
+
Example READMEs and screenshots: [LunarLander](examples/lunar_lander/README.md),
|
|
83
|
+
[CartPole](examples/cartpole/README.md), [Pendulum](examples/pendulum/README.md),
|
|
84
|
+
and [Squared Continuous](examples/puffer/README.md).
|
|
85
|
+
|
|
82
86
|
From a checkout, run the full LunarLander trainer:
|
|
83
87
|
|
|
84
88
|
```sh
|
|
@@ -4,9 +4,13 @@ README.md
|
|
|
4
4
|
pyproject.toml
|
|
5
5
|
requirements.txt
|
|
6
6
|
examples/__init__.py
|
|
7
|
+
examples/cartpole/README.md
|
|
8
|
+
examples/cartpole/checkpoint.png
|
|
7
9
|
examples/cartpole/train.py
|
|
8
10
|
examples/cartpole/results/cpu.jsonl
|
|
11
|
+
examples/lunar_lander/README.md
|
|
9
12
|
examples/lunar_lander/__init__.py
|
|
13
|
+
examples/lunar_lander/checkpoint.png
|
|
10
14
|
examples/lunar_lander/config.py
|
|
11
15
|
examples/lunar_lander/reference.py
|
|
12
16
|
examples/lunar_lander/requirements-reference.txt
|
|
@@ -23,13 +27,23 @@ examples/lunar_lander/results/2026-10-26/phase-torch-thread4.jsonl
|
|
|
23
27
|
examples/lunar_lander/results/2026-10-26/protocol.json
|
|
24
28
|
examples/lunar_lander/results/2026-10-26/tinygrad-cpu.jsonl
|
|
25
29
|
examples/lunar_lander/results/2026-10-26/torch-cpu.jsonl
|
|
30
|
+
examples/pendulum/README.md
|
|
26
31
|
examples/pendulum/__init__.py
|
|
32
|
+
examples/pendulum/checkpoint.png
|
|
27
33
|
examples/pendulum/env.py
|
|
28
34
|
examples/pendulum/requirements.txt
|
|
29
35
|
examples/pendulum/train.py
|
|
30
36
|
examples/pendulum/results/cpu-2.jsonl
|
|
31
37
|
examples/pendulum/results/cpu-3.jsonl
|
|
32
38
|
examples/pendulum/results/cpu.jsonl
|
|
39
|
+
examples/puffer/README.md
|
|
40
|
+
examples/puffer/checkpoint.png
|
|
41
|
+
examples/puffer/env.py
|
|
42
|
+
examples/puffer/smoke.py
|
|
43
|
+
examples/puffer/squared_bridge.c
|
|
44
|
+
examples/puffer/squared_smoke.c
|
|
45
|
+
examples/puffer/train.py
|
|
46
|
+
examples/puffer/results/observations.jsonl
|
|
33
47
|
tests/test_cartpole.py
|
|
34
48
|
tests/test_checkpoint.py
|
|
35
49
|
tests/test_core.py
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
recursive-include examples *.py *.txt *.json *.jsonl
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tinybaselines-0.1.0a4 → tinybaselines-0.1.0a5}/examples/lunar_lander/requirements-reference.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tinybaselines-0.1.0a4 → tinybaselines-0.1.0a5}/examples/lunar_lander/results/cpu-padding.jsonl
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|