blob: 9699fef8b2f7cc7028c7f8f32d373ab7faf659bd [file] [log] [blame]
Brian Silverman3fec6482020-01-19 17:56:20 -08001from __future__ import print_function
2
3import json
4import sys
5import subprocess
6import os
7import threading
8
9from bazel_tools.tools.python.runfiles import runfiles
10
11def main(params):
12 r = runfiles.Create()
13 generator = r.Rlocation('org_frc971/y2020/vision/sift/fast_gaussian_generator')
14
15 ruledir = sys.argv[2]
16 target_cpu = sys.argv[3]
17
18 target = {
19 'armhf-debian': 'arm-32-linux-no_asserts',
20 'k8': 'x86-64-linux-no_asserts',
21 }[target_cpu]
22
23 commands = []
24
25 env = os.environ.copy()
26 env['LD_LIBRARY_PATH'] = ':'.join([
27 'debian_amd64_sysroot/lib/x86_64-linux-gnu',
28 'debian_amd64_sysroot/lib',
29 'debian_amd64_sysroot/usr/lib/x86_64-linux-gnu',
30 'debian_amd64_sysroot/usr/lib',
31 ])
32
33 all_header = [
34 '#ifndef Y2020_VISION_SIFT_FAST_GAUSSIAN_ALL_H_',
35 '#define Y2020_VISION_SIFT_FAST_GAUSSIAN_ALL_H_',
36 '#include "HalideBuffer.h"',
37 ]
38
39 for cols, rows in params['sizes']:
40 for sigma, sigma_name, filter_width in params['sigmas']:
41 name = "fast_gaussian_%dx%d_%s" % (cols, rows, sigma_name)
42
43 commands.append([
44 generator,
45 '-g', 'gaussian_generator',
46 '-o', ruledir,
47 '-f', name,
48 '-e', 'o,h,html',
49 'target=%s-no_runtime' % target,
50 'cols=%s' % cols,
51 'rows=%s' % rows,
52 'sigma=%s' % sigma,
53 'filter_width=%s' % filter_width,
54 ])
55 all_header += [
56 '#include "y2020/vision/sift/%s.h"' % name,
57 ]
58
59 name = "fast_gaussian_subtract_%dx%d_%s" % (cols, rows, sigma_name)
60
61 commands.append([
62 generator,
63 '-g', 'gaussian_and_subtract_generator',
64 '-o', ruledir,
65 '-f', name,
66 '-e', 'o,h,html',
67 'target=%s-no_runtime' % target,
68 'cols=%s' % cols,
69 'rows=%s' % rows,
70 'sigma=%s' % sigma,
71 'filter_width=%s' % filter_width,
72 ])
73 all_header += [
74 '#include "y2020/vision/sift/%s.h"' % name,
75 ]
76
77 name = 'fast_subtract_%dx%d' % (cols, rows)
78 commands.append([
79 generator,
80 '-g', 'subtract_generator',
81 '-o', ruledir,
82 '-f', name,
83 '-e', 'o,h,html',
84 'target=%s-no_runtime' % target,
85 'cols=%s' % cols,
86 'rows=%s' % rows,
87 ])
88 all_header += [
89 '#include "y2020/vision/sift/%s.h"' % name,
90 ]
91 commands.append([
92 generator,
93 '-r', 'fast_gaussian_runtime',
94 '-o', ruledir,
95 '-e', 'o',
96 'target=%s' % target,
97 ])
98
99 all_header += [
100 'namespace frc971 {',
101 'namespace vision {',
102 '// 0 is success. 1 is non-implemented size. Negative is a Halide error.',
103 'inline int DoGeneratedFastGaussian(',
104 ' Halide::Runtime::Buffer<const int16_t, 2> input,',
105 ' Halide::Runtime::Buffer<int16_t, 2> output,',
106 ' double sigma) {',
107 ]
108
109 for sigma, sigma_name, filter_width in params['sigmas']:
110 for cols, rows in params['sizes']:
111 name = "fast_gaussian_%dx%d_%s" % (cols, rows, sigma_name)
112 all_header += [
113 ' if (input.dim(0).extent() == %s' % cols,
114 ' && input.dim(1).extent() == %s' % rows,
115 ' && sigma == %s) {' % sigma,
116 ' return %s(input, output);' % name,
117 ' }',
118 ]
119
120 all_header += [
121 ' return 1;',
122 '}',
123 'inline int DoGeneratedFastGaussianAndSubtract(',
124 ' Halide::Runtime::Buffer<const int16_t, 2> input,',
125 ' Halide::Runtime::Buffer<int16_t, 2> blurred,',
126 ' Halide::Runtime::Buffer<int16_t, 2> difference,',
127 ' double sigma) {',
128 ]
129
130 for sigma, sigma_name, filter_width in params['sigmas']:
131 for cols, rows in params['sizes']:
132 name = "fast_gaussian_subtract_%dx%d_%s" % (cols, rows, sigma_name)
133 all_header += [
134 ' if (input.dim(0).extent() == %s' % cols,
135 ' && input.dim(1).extent() == %s' % rows,
136 ' && sigma == %s) {' % sigma,
137 ' return %s(input, blurred, difference);' % name,
138 ' }',
139 ]
140
141 all_header += [
142 ' return 1;',
143 '}',
144 'inline int DoGeneratedFastSubtract('
145 ' Halide::Runtime::Buffer<const int16_t, 2> input_a,',
146 ' Halide::Runtime::Buffer<const int16_t, 2> input_b,',
147 ' Halide::Runtime::Buffer<int16_t, 2> output) {',
148 ]
149 for cols, rows in params['sizes']:
150 name = 'fast_subtract_%dx%d' % (cols, rows)
151 all_header += [
152 ' if (input_a.dim(0).extent() == %s' % cols,
153 ' && input_a.dim(1).extent() == %s) {' % rows,
154 ' return %s(input_a, input_b, output);' % name,
155 ' }',
156 ]
157 all_header += [
158 ' return 1;',
159 '}',
160 '} // namespace vision',
161 '} // namespace frc971',
162 '#endif // Y2020_VISION_SIFT_FAST_GAUSSIAN_ALL_H_',
163 ]
164
165 with open(os.path.join(ruledir, 'fast_gaussian_all.h'), 'w') as f:
166 f.writelines([line + '\n' for line in all_header])
167
168 commands_lock = threading.Lock()
169 success = [True]
170
171 def run_commands():
172 while True:
173 with commands_lock:
174 if not commands:
175 return
176 if not success[0]:
177 return
178 command = commands.pop()
179 try:
180 subprocess.check_call(command, env=env)
181 except:
182 with commands_lock:
183 success[0] = False
184 raise
185 threads = [threading.Thread(target=run_commands) for _ in range(4)]
186 for thread in threads:
187 thread.start()
188 for thread in threads:
189 thread.join()
190 if not success[0]:
191 sys.exit(1)
192
193if __name__ == '__main__':
194 main(json.loads(sys.argv[1]))