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