1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
|
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Halide code generation tool
__author__ = __maintainer__ = "Jérôme Carretero <cJ-waf@zougloub.eu>"
__copyright__ = "Jérôme Carretero, 2014"
"""
Tool to run `Halide <http://halide-lang.org>`_ code generators.
Usage::
bld(
name='pipeline',
# ^ Reference this in use="..." for things using the generated code
#target=['pipeline.o', 'pipeline.h']
# ^ by default, name.{o,h} is added, but you can set the outputs here
features='halide',
halide_env="HL_TRACE=1 HL_TARGET=host-opencl-gpu_debug",
# ^ Environment passed to the generator,
# can be a dict, k/v list, or string.
args=[],
# ^ Command-line arguments to the generator (optional),
# eg. to give parameters to the scheduling
source='pipeline_gen',
# ^ Name of the source executable
)
Known issues:
- Currently only supports Linux (no ".exe")
- Doesn't rerun on input modification when input is part of a build
chain, and has been modified externally.
"""
import os
from waflib import Task, Utils, Options, TaskGen, Errors
class run_halide_gen(Task.Task):
color = 'CYAN'
vars = ['HALIDE_ENV', 'HALIDE_ARGS']
run_str = "${SRC[0].abspath()} ${HALIDE_ARGS}"
def __str__(self):
stuff = "halide"
stuff += ("[%s]" % (",".join(
('%s=%s' % (k,v)) for k, v in sorted(self.env.env.items()))))
return Task.Task.__str__(self).replace(self.__class__.__name__,
stuff)
@TaskGen.feature('halide')
@TaskGen.before_method('process_source')
def halide(self):
Utils.def_attrs(self,
args=[],
halide_env={},
)
bld = self.bld
env = self.halide_env
try:
if isinstance(env, str):
env = dict(x.split('=') for x in env.split())
elif isinstance(env, list):
env = dict(x.split('=') for x in env)
assert isinstance(env, dict)
except Exception as e:
if not isinstance(e, ValueError) \
and not isinstance(e, AssertionError):
raise
raise Errors.WafError(
"halide_env must be under the form" \
" {'HL_x':'a', 'HL_y':'b'}" \
" or ['HL_x=y', 'HL_y=b']" \
" or 'HL_x=y HL_y=b'")
src = self.to_nodes(self.source)
assert len(src) == 1, "Only one source expected"
src = src[0]
args = Utils.to_list(self.args)
def change_ext(src, ext):
# Return a node with a new extension, in an appropriate folder
name = src.name
xpos = src.name.rfind('.')
if xpos == -1:
xpos = len(src.name)
newname = name[:xpos] + ext
if src.is_child_of(bld.bldnode):
node = src.get_src().parent.find_or_declare(newname)
else:
node = bld.bldnode.find_or_declare(newname)
return node
def to_nodes(self, lst, path=None):
tmp = []
path = path or self.path
find = path.find_or_declare
if isinstance(lst, self.path.__class__):
lst = [lst]
for x in Utils.to_list(lst):
if isinstance(x, str):
node = find(x)
else:
node = x
tmp.append(node)
return tmp
tgt = to_nodes(self, self.target)
if not tgt:
tgt = [change_ext(src, '.o'), change_ext(src, '.h')]
cwd = tgt[0].parent.abspath()
task = self.create_task('run_halide_gen', src, tgt, cwd=cwd)
task.env.append_unique('HALIDE_ARGS', args)
if task.env.env == []:
task.env.env = {}
task.env.env.update(env)
task.env.HALIDE_ENV = " ".join(("%s=%s" % (k,v)) for (k,v) in sorted(env.items()))
task.env.HALIDE_ARGS = args
try:
self.compiled_tasks.append(task)
except AttributeError:
self.compiled_tasks = [task]
self.source = []
def configure(conf):
if Options.options.halide_root is None:
conf.check_cfg(package='Halide', args='--cflags --libs')
else:
halide_root = Options.options.halide_root
conf.env.INCLUDES_HALIDE = [ os.path.join(halide_root, "include") ]
conf.env.LIBPATH_HALIDE = [ os.path.join(halide_root, "lib") ]
conf.env.LIB_HALIDE = ["Halide"]
# You might want to add this, while upstream doesn't fix it
#conf.env.LIB_HALIDE += ['ncurses', 'dl', 'pthread']
def options(opt):
opt.add_option('--halide-root',
help="path to Halide include and lib files",
)
|