2 # -*- coding: utf-8 -*-
3 # Halide code generation tool
5 __author__
= __maintainer__
= "Jérôme Carretero <cJ-waf@zougloub.eu>"
6 __copyright__
= "Jérôme Carretero, 2014"
10 Tool to run `Halide <http://halide-lang.org>`_ code generators.
16 # ^ Reference this in use="..." for things using the generated code
17 #target=['pipeline.o', 'pipeline.h']
18 # ^ by default, name.{o,h} is added, but you can set the outputs here
20 halide_env="HL_TRACE=1 HL_TARGET=host-opencl-gpu_debug",
21 # ^ Environment passed to the generator,
22 # can be a dict, k/v list, or string.
24 # ^ Command-line arguments to the generator (optional),
25 # eg. to give parameters to the scheduling
26 source='pipeline_gen',
27 # ^ Name of the source executable
34 - Currently only supports Linux (no ".exe")
36 - Doesn't rerun on input modification when input is part of a build
37 chain, and has been modified externally.
42 from waflib
import Task
, Utils
, Options
, TaskGen
, Errors
44 class run_halide_gen(Task
.Task
):
46 vars = ['HALIDE_ENV', 'HALIDE_ARGS']
47 run_str
= "${SRC[0].abspath()} ${HALIDE_ARGS}"
50 stuff
+= ("[%s]" % (",".join(
51 ('%s=%s' % (k
,v
)) for k
, v
in sorted(self
.env
.env
.items()))))
52 return Task
.Task
.__str
__(self
).replace(self
.__class
__.__name
__,
55 @TaskGen.feature('halide')
56 @TaskGen.before_method('process_source')
67 if isinstance(env
, str):
68 env
= dict(x
.split('=') for x
in env
.split())
69 elif isinstance(env
, list):
70 env
= dict(x
.split('=') for x
in env
)
71 assert isinstance(env
, dict)
72 except Exception as e
:
73 if not isinstance(e
, ValueError) \
74 and not isinstance(e
, AssertionError):
76 raise Errors
.WafError(
77 "halide_env must be under the form" \
78 " {'HL_x':'a', 'HL_y':'b'}" \
79 " or ['HL_x=y', 'HL_y=b']" \
80 " or 'HL_x=y HL_y=b'")
82 src
= self
.to_nodes(self
.source
)
83 assert len(src
) == 1, "Only one source expected"
86 args
= Utils
.to_list(self
.args
)
88 def change_ext(src
, ext
):
89 # Return a node with a new extension, in an appropriate folder
91 xpos
= src
.name
.rfind('.')
94 newname
= name
[:xpos
] + ext
95 if src
.is_child_of(bld
.bldnode
):
96 node
= src
.get_src().parent
.find_or_declare(newname
)
98 node
= bld
.bldnode
.find_or_declare(newname
)
101 def to_nodes(self
, lst
, path
=None):
103 path
= path
or self
.path
104 find
= path
.find_or_declare
106 if isinstance(lst
, self
.path
.__class
__):
109 for x
in Utils
.to_list(lst
):
110 if isinstance(x
, str):
117 tgt
= to_nodes(self
, self
.target
)
119 tgt
= [change_ext(src
, '.o'), change_ext(src
, '.h')]
120 cwd
= tgt
[0].parent
.abspath()
121 task
= self
.create_task('run_halide_gen', src
, tgt
, cwd
=cwd
)
122 task
.env
.append_unique('HALIDE_ARGS', args
)
123 if task
.env
.env
== []:
125 task
.env
.env
.update(env
)
126 task
.env
.HALIDE_ENV
= " ".join(("%s=%s" % (k
,v
)) for (k
,v
) in sorted(env
.items()))
127 task
.env
.HALIDE_ARGS
= args
130 self
.compiled_tasks
.append(task
)
131 except AttributeError:
132 self
.compiled_tasks
= [task
]
136 if Options
.options
.halide_root
is None:
137 conf
.check_cfg(package
='Halide', args
='--cflags --libs')
139 halide_root
= Options
.options
.halide_root
140 conf
.env
.INCLUDES_HALIDE
= [ os
.path
.join(halide_root
, "include") ]
141 conf
.env
.LIBPATH_HALIDE
= [ os
.path
.join(halide_root
, "lib") ]
142 conf
.env
.LIB_HALIDE
= ["Halide"]
144 # You might want to add this, while upstream doesn't fix it
145 #conf.env.LIB_HALIDE += ['ncurses', 'dl', 'pthread']
148 opt
.add_option('--halide-root',
149 help="path to Halide include and lib files",