jack2 codebase
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

151 lines
3.9KB

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