Halide 14.0.0
Halide compiler and libraries
ExternalCode.h
Go to the documentation of this file.
1#ifndef HALIDE_EXTERNAL_CODE_H
2#define HALIDE_EXTERNAL_CODE_H
3
4#include <vector>
5
6#include "Expr.h"
7#include "Target.h"
8
9namespace Halide {
10
12private:
13 enum Kind {
14 LLVMBitcode,
15 DeviceCode,
16 CPlusPlusSource,
17 } kind;
18
19 Target llvm_target; // For LLVMBitcode.
20 DeviceAPI device_code_kind;
21
22 std::vector<uint8_t> code;
23
24 // Used for debugging and naming the module to llvm.
25 std::string nametag;
26
27 ExternalCode(Kind kind, const Target &llvm_target, DeviceAPI device_api, const std::vector<uint8_t> &code, const std::string &name)
28 : kind(kind), llvm_target(llvm_target), device_code_kind(device_api), code(code), nametag(name) {
29 }
30
31public:
32 /** Construct an ExternalCode container from llvm bitcode. The
33 * result can be passed to Halide::Module::append to have the
34 * contained bitcode linked with that module. The Module's target
35 * must match the target argument here on architecture, bit width,
36 * and operating system. The name is used as a unique identifier
37 * for the external code and duplicates will be reduced to a
38 * single instance. Halide does not do anything other than to
39 * compare names for equality. To guarantee uniqueness in public
40 * code, we suggest using a Java style inverted domain name
41 * followed by organization specific naming. E.g.:
42 * com.initech.y2k.5d2ac80aaf522eec6cb4b40f39fb923f9902bc7e */
43 static ExternalCode bitcode_wrapper(const Target &cpu_type, const std::vector<uint8_t> &code, const std::string &name) {
44 return ExternalCode(LLVMBitcode, cpu_type, DeviceAPI::None, code, name);
45 }
46
47 /** Construct an ExternalCode container from GPU "source code."
48 * This container can be used to insert its code into the GPU code
49 * generated for a given DeviceAPI. The specific type of code
50 * depends on the device API used as follows:
51 * CUDA: llvm bitcode for PTX
52 * OpenCL: OpenCL source code
53 * GLSL: GLSL source code
54 * OpenGLCompute: GLSL source code
55 * Metal: Metal source code
56 * Hexagon: llvm bitcode for Hexagon
57 *
58 * At present, this API is not fully working. See Issue:
59 * https://github.com/halide/Halide/issues/1971
60 *
61 * The name is used as a unique identifier for the external code
62 * and duplicates will be reduced to a single instance. Halide
63 * does not do anything other than to compare names for
64 * equality. To guarantee uniqueness in public code, we suggest
65 * using a Java style inverted domain name followed by
66 * organization specific naming. E.g.:
67 * com.tyrell.nexus-6.53947db86ba97a9ca5ecd5e60052880945bfeb37 */
68 static ExternalCode device_code_wrapper(DeviceAPI device_api, const std::vector<uint8_t> &code, const std::string &name) {
69 return ExternalCode(DeviceCode, Target(), device_api, code, name);
70 }
71
72 /** Construct an ExternalCode container from C++ source code. This
73 * container can be used to insert its code into C++ output from
74 * Halide.
75 *
76 * At present, this API is not fully working. See Issue:
77 * https://github.com/halide/Halide/issues/1971
78 *
79 * The name is used as a unique identifier for the external code
80 * and duplicates will be reduced to a single instance. Halide
81 * does not do anything other than to compare names for
82 * equality. To guarantee uniqueness in public code, we suggest
83 * using a Java style inverted domain name followed by
84 * organization specific naming. E.g.:
85 * com.cyberdyne.skynet.78ad6c411d313f050f172cd3d440f23fdd797d0d */
86 static ExternalCode c_plus_plus_code_wrapper(const std::vector<uint8_t> &code, const std::string &name) {
87 return ExternalCode(CPlusPlusSource, Target(), DeviceAPI::None, code, name);
88 }
89
90 /** Return true if this container holds llvm bitcode linkable with
91 * code generated for the target argument. The matching is done
92 * on the architecture, bit width, and operating system
93 * only. Features are ignored. If the container is for
94 * Target::ArchUnkonwn, it applies to all architectures -- meaning
95 * it is generic llvm bitcode. If the OS is OSUnknown, it applies
96 * to all operationg systems. The bit width must match.
97 *
98 * Ignoring feature flags isn't too important since generally
99 * ExternalCode will be constructed in a Generator which has
100 * access to the feature flags in effect and can select code
101 * appropriately. */
102 bool is_for_cpu_target(const Target &host) const {
103 return kind == LLVMBitcode &&
104 (llvm_target.arch == Target::ArchUnknown || llvm_target.arch == host.arch) &&
105 (llvm_target.os == Target::OSUnknown || llvm_target.os == host.os) &&
106 (llvm_target.bits == host.bits);
107 }
108
109 /** True if this container holds code linkable with a code generated for a GPU. */
110 bool is_for_device_api(DeviceAPI current_device) const {
111 return kind == DeviceCode && device_code_kind == current_device;
112 }
113
114 /** True if this container holds C++ source code for inclusion in
115 * generating C++ output. */
117 return kind == CPlusPlusSource;
118 }
119
120 /** Retrieve the bytes of external code held by this container. */
121 const std::vector<uint8_t> &contents() const {
122 return code;
123 }
124
125 /** Retrieve the name of this container. Used to ensure the same
126 * piece of external code is only included once in linkage. */
127 const std::string &name() const {
128 return nametag;
129 }
130};
131
132} // namespace Halide
133
134#endif
Base classes for Halide expressions (Halide::Expr) and statements (Halide::Internal::Stmt)
Defines the structure that describes a Halide target.
bool is_c_plus_plus_source() const
True if this container holds C++ source code for inclusion in generating C++ output.
Definition: ExternalCode.h:116
bool is_for_cpu_target(const Target &host) const
Return true if this container holds llvm bitcode linkable with code generated for the target argument...
Definition: ExternalCode.h:102
static ExternalCode bitcode_wrapper(const Target &cpu_type, const std::vector< uint8_t > &code, const std::string &name)
Construct an ExternalCode container from llvm bitcode.
Definition: ExternalCode.h:43
static ExternalCode c_plus_plus_code_wrapper(const std::vector< uint8_t > &code, const std::string &name)
Construct an ExternalCode container from C++ source code.
Definition: ExternalCode.h:86
const std::vector< uint8_t > & contents() const
Retrieve the bytes of external code held by this container.
Definition: ExternalCode.h:121
bool is_for_device_api(DeviceAPI current_device) const
True if this container holds code linkable with a code generated for a GPU.
Definition: ExternalCode.h:110
static ExternalCode device_code_wrapper(DeviceAPI device_api, const std::vector< uint8_t > &code, const std::string &name)
Construct an ExternalCode container from GPU "source code." This container can be used to insert its ...
Definition: ExternalCode.h:68
const std::string & name() const
Retrieve the name of this container.
Definition: ExternalCode.h:127
This file defines the class FunctionDAG, which is our representation of a Halide pipeline,...
DeviceAPI
An enum describing a type of device API.
Definition: DeviceAPI.h:15
A struct representing a target machine and os to generate code for.
Definition: Target.h:19
enum Halide::Target::Arch arch
int bits
The bit-width of the target machine.
Definition: Target.h:51
enum Halide::Target::OS os