Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit a00f7e2

Browse files
committed
Open source release of Brain Coder.
1 parent 54babf6 commit a00f7e2

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+11177
-0
lines changed

CODEOWNERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
/research/attention_ocr/ @alexgorban
66
/research/audioset/ @plakal @dpwe
77
/research/autoencoders/ @snurkabill
8+
/research/brain_coder/ @danabo
89
/research/cognitive_mapping_and_planning/ @s-gupta
910
/research/compression/ @nmjohn
1011
/research/delf/ @andrefaraujo

research/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ installation](https://www.tensorflow.org/install).
2020
- [audioset](audioset): Models and supporting code for use with
2121
[AudioSet](http://g.co/audioset).
2222
- [autoencoder](autoencoder): various autoencoders.
23+
- [brain_coder](brain_coder): Program synthesis with reinforcement learning.
2324
- [cognitive_mapping_and_planning](cognitive_mapping_and_planning):
2425
implementation of a spatial memory based mapping and planning architecture
2526
for visual navigation.

research/brain_coder/README.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# Brain Coder
2+
3+
*Authors: Daniel Abolafia, Quoc Le, Mohammad Norouzi*
4+
5+
Brain coder is a code synthesis experimental environment. We provide code that reproduces the results from our recent paper [Code Synthesis with Priority Queue Training](https://openreview.net/forum?id=r1AoGNlC-). See single_task/README.md for details on how to build and reproduce those experiments.
6+
7+
## Installation
8+
9+
First install dependencies seperately:
10+
11+
* [bazel](https://docs.bazel.build/versions/master/install.html)
12+
* [TensorFlow](https://www.tensorflow.org/install/)
13+
* [scipy](https://www.scipy.org/install.html)
14+
* [absl-py](https://github.com/abseil/abseil-py)
15+
16+
Note: even if you already have these dependencies installed, make sure they are
17+
up-to-date to avoid unnecessary debugging.
18+
19+
20+
## Building
21+
22+
Use bazel from the top-level repo directory.
23+
24+
For example:
25+
26+
```bash
27+
bazel build single_task:run
28+
```
29+
30+
View README.md files in subdirectories for more details.

research/brain_coder/WORKSPACE

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
git_repository(
2+
name = "subpar",
3+
remote = "https://github.com/google/subpar",
4+
tag = "1.0.0",
5+
)

research/brain_coder/common/BUILD

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
licenses(["notice"])
2+
3+
package(default_visibility = [
4+
"//:__subpackages__",
5+
])
6+
7+
py_library(
8+
name = "bf",
9+
srcs = ["bf.py"],
10+
)
11+
12+
py_test(
13+
name = "bf_test",
14+
srcs = ["bf_test.py"],
15+
deps = [
16+
":bf",
17+
# tensorflow dep
18+
],
19+
)
20+
21+
py_library(
22+
name = "config_lib",
23+
srcs = ["config_lib.py"],
24+
)
25+
26+
py_test(
27+
name = "config_lib_test",
28+
srcs = ["config_lib_test.py"],
29+
deps = [
30+
":config_lib",
31+
# tensorflow dep
32+
],
33+
)
34+
35+
py_library(
36+
name = "reward",
37+
srcs = ["reward.py"],
38+
)
39+
40+
py_test(
41+
name = "reward_test",
42+
srcs = ["reward_test.py"],
43+
deps = [
44+
":reward",
45+
# numpy dep
46+
# tensorflow dep
47+
],
48+
)
49+
50+
py_library(
51+
name = "rollout",
52+
srcs = ["rollout.py"],
53+
deps = [
54+
":utils",
55+
# numpy dep
56+
# scipy dep
57+
],
58+
)
59+
60+
py_test(
61+
name = "rollout_test",
62+
srcs = ["rollout_test.py"],
63+
deps = [
64+
":rollout",
65+
# numpy dep
66+
# tensorflow dep
67+
],
68+
)
69+
70+
py_library(
71+
name = "schedules",
72+
srcs = ["schedules.py"],
73+
deps = [":config_lib"],
74+
)
75+
76+
py_test(
77+
name = "schedules_test",
78+
srcs = ["schedules_test.py"],
79+
deps = [
80+
":config_lib",
81+
":schedules",
82+
# numpy dep
83+
# tensorflow dep
84+
],
85+
)
86+
87+
py_library(
88+
name = "utils",
89+
srcs = ["utils.py"],
90+
deps = [
91+
# file dep
92+
# absl dep /logging
93+
# numpy dep
94+
# tensorflow dep
95+
],
96+
)
97+
98+
py_test(
99+
name = "utils_test",
100+
srcs = ["utils_test.py"],
101+
deps = [
102+
":utils",
103+
# numpy dep
104+
# tensorflow dep
105+
],
106+
)

research/brain_coder/common/bf.py

Lines changed: 234 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,234 @@
1+
from __future__ import absolute_import
2+
from __future__ import division
3+
from __future__ import print_function
4+
5+
"""BrainF**k interpreter.
6+
7+
Language info: https://en.wikipedia.org/wiki/Brainfuck
8+
9+
Based on public implementation:
10+
https://github.com/pocmo/Python-Brainfuck/blob/master/brainfuck.py
11+
"""
12+
13+
from collections import namedtuple
14+
import time
15+
16+
17+
EvalResult = namedtuple(
18+
'EvalResult', ['output', 'success', 'failure_reason', 'steps', 'time',
19+
'memory', 'program_trace'])
20+
21+
22+
ExecutionSnapshot = namedtuple(
23+
'ExecutionSnapshot',
24+
['codeptr', 'codechar', 'memptr', 'memval', 'memory', 'next_input',
25+
'output_buffer'])
26+
27+
28+
class Status(object):
29+
SUCCESS = 'success'
30+
TIMEOUT = 'timeout'
31+
STEP_LIMIT = 'step-limit'
32+
SYNTAX_ERROR = 'syntax-error'
33+
34+
35+
CHARS = INT_TO_CHAR = ['>', '<', '+', '-', '[', ']', '.', ',']
36+
CHAR_TO_INT = dict([(c, i) for i, c in enumerate(INT_TO_CHAR)])
37+
38+
39+
class LookAheadIterator(object):
40+
"""Same API as Python iterator, with additional peek method."""
41+
42+
def __init__(self, iterable):
43+
self._it = iter(iterable)
44+
self._current_element = None
45+
self._done = False
46+
self._preload_next()
47+
48+
def _preload_next(self):
49+
try:
50+
self._current_element = self._it.next()
51+
except StopIteration:
52+
self._done = True
53+
54+
def next(self):
55+
if self._done:
56+
raise StopIteration
57+
element = self._current_element
58+
self._preload_next()
59+
return element
60+
61+
def peek(self, default_value=None):
62+
if self._done:
63+
if default_value is None:
64+
raise StopIteration
65+
return default_value
66+
return self._current_element
67+
68+
69+
def buildbracemap(code):
70+
"""Build jump map.
71+
72+
Args:
73+
code: List or string or BF chars.
74+
75+
Returns:
76+
bracemap: dict mapping open and close brace positions in the code to their
77+
destination jumps. Specifically, positions of matching open/close braces
78+
if they exist.
79+
correct_syntax: True if all braces match. False if there are unmatched
80+
braces in the code. Even if there are unmatched braces, a bracemap will
81+
be built, and unmatched braces will map to themselves.
82+
"""
83+
bracestack, bracemap = [], {}
84+
85+
correct_syntax = True
86+
for position, command in enumerate(code):
87+
if command == '[':
88+
bracestack.append(position)
89+
if command == ']':
90+
if not bracestack: # Unmatched closing brace.
91+
bracemap[position] = position # Don't jump to any position.
92+
correct_syntax = False
93+
continue
94+
start = bracestack.pop()
95+
bracemap[start] = position
96+
bracemap[position] = start
97+
if bracestack: # Unmatched opening braces.
98+
for pos in bracestack:
99+
bracemap[pos] = pos # Don't jump to any position.
100+
correct_syntax = False
101+
return bracemap, correct_syntax
102+
103+
104+
def evaluate(code, input_buffer=None, init_memory=None, base=256, timeout=1.0,
105+
max_steps=None, require_correct_syntax=True, output_memory=False,
106+
debug=False):
107+
"""Execute BF code.
108+
109+
Args:
110+
code: String or list of BF characters. Any character not in CHARS will be
111+
ignored.
112+
input_buffer: A list of ints which will be used as the program's input
113+
stream. Each read op "," will read an int from this list. 0's will be
114+
read once the end of the list is reached, or if no input buffer is
115+
given.
116+
init_memory: A list of ints. Memory for first k positions will be
117+
initialized to this list (where k = len(init_memory)). Memory positions
118+
are initialized to 0 by default.
119+
base: Integer base for the memory. When a memory value is incremented to
120+
`base` it will overflow to 0. When a memory value is decremented to -1
121+
it will underflow to `base` - 1.
122+
timeout: Time limit for program execution in seconds. Set to None to
123+
disable.
124+
max_steps: Execution step limit. An execution step is the execution of one
125+
operation (code character), even if that op has been executed before.
126+
Execution exits when this many steps are reached. Set to None to
127+
disable. Disabled by default.
128+
require_correct_syntax: If True, unmatched braces will cause `evaluate` to
129+
return without executing the code. The failure reason will be
130+
`Status.SYNTAX_ERROR`. If False, unmatched braces are ignored
131+
and execution will continue.
132+
output_memory: If True, the state of the memory at the end of execution is
133+
returned.
134+
debug: If True, then a full program trace will be returned.
135+
136+
Returns:
137+
EvalResult namedtuple containing
138+
output: List of ints which were written out by the program with the "."
139+
operation.
140+
success: Boolean. Whether execution completed successfully.
141+
failure_reason: One of the attributes of `Status`. Gives extra info
142+
about why execution was not successful.
143+
steps: Number of execution steps the program ran for.
144+
time: Amount of time in seconds the program ran for.
145+
memory: If `output_memory` is True, a list of memory cells up to the last
146+
one written to. otherwise, None.
147+
"""
148+
input_iter = (
149+
LookAheadIterator(input_buffer) if input_buffer is not None
150+
else LookAheadIterator([]))
151+
152+
# Null memory value. This is the value of an empty memory. Also the value
153+
# returned by the read operation when the input buffer is empty, or the
154+
# end of the buffer is reached.
155+
null_value = 0
156+
157+
code = list(code)
158+
bracemap, correct_syntax = buildbracemap(code) # will modify code list
159+
if require_correct_syntax and not correct_syntax:
160+
return EvalResult([], False, Status.SYNTAX_ERROR, 0, 0.0,
161+
[] if output_memory else None, [] if debug else None)
162+
163+
output_buffer = []
164+
165+
codeptr, cellptr = 0, 0
166+
167+
cells = list(init_memory) if init_memory else [0]
168+
169+
program_trace = [] if debug else None
170+
success = True
171+
reason = Status.SUCCESS
172+
start_time = time.time()
173+
steps = 0
174+
while codeptr < len(code):
175+
command = code[codeptr]
176+
177+
if debug:
178+
# Add step to program trace.
179+
program_trace.append(ExecutionSnapshot(
180+
codeptr=codeptr, codechar=command, memptr=cellptr,
181+
memval=cells[cellptr], memory=list(cells),
182+
next_input=input_iter.peek(null_value),
183+
output_buffer=list(output_buffer)))
184+
185+
if command == '>':
186+
cellptr += 1
187+
if cellptr == len(cells): cells.append(null_value)
188+
189+
if command == '<':
190+
cellptr = 0 if cellptr <= 0 else cellptr - 1
191+
192+
if command == '+':
193+
cells[cellptr] = cells[cellptr] + 1 if cells[cellptr] < (base - 1) else 0
194+
195+
if command == '-':
196+
cells[cellptr] = cells[cellptr] - 1 if cells[cellptr] > 0 else (base - 1)
197+
198+
if command == '[' and cells[cellptr] == 0: codeptr = bracemap[codeptr]
199+
if command == ']' and cells[cellptr] != 0: codeptr = bracemap[codeptr]
200+
201+
if command == '.': output_buffer.append(cells[cellptr])
202+
if command == ',': cells[cellptr] = next(input_iter, null_value)
203+
204+
codeptr += 1
205+
steps += 1
206+
207+
if timeout is not None and time.time() - start_time > timeout:
208+
success = False
209+
reason = Status.TIMEOUT
210+
break
211+
if max_steps is not None and steps >= max_steps:
212+
success = False
213+
reason = Status.STEP_LIMIT
214+
break
215+
216+
if debug:
217+
# Add step to program trace.
218+
command = code[codeptr] if codeptr < len(code) else ''
219+
program_trace.append(ExecutionSnapshot(
220+
codeptr=codeptr, codechar=command, memptr=cellptr,
221+
memval=cells[cellptr], memory=list(cells),
222+
next_input=input_iter.peek(null_value),
223+
output_buffer=list(output_buffer)))
224+
225+
return EvalResult(
226+
output=output_buffer,
227+
success=success,
228+
failure_reason=reason,
229+
steps=steps,
230+
time=time.time() - start_time,
231+
memory=cells if output_memory else None,
232+
program_trace=program_trace)
233+
234+

0 commit comments

Comments
 (0)