16
16
#include " mlir/Dialect/GPU/IR/CompilationInterfaces.h"
17
17
#include " mlir/Dialect/GPU/IR/GPUDialect.h"
18
18
#include " mlir/Dialect/LLVMIR/NVVMDialect.h"
19
+ #include " mlir/IR/BuiltinAttributeInterfaces.h"
20
+ #include " mlir/IR/BuiltinDialect.h"
21
+ #include " mlir/IR/BuiltinTypes.h"
22
+ #include " mlir/IR/DialectResourceBlobManager.h"
19
23
#include " mlir/Target/LLVM/NVVM/Utils.h"
20
24
#include " mlir/Target/LLVMIR/Dialect/GPU/GPUToLLVMIRTranslation.h"
21
25
#include " mlir/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.h"
33
37
#include " llvm/Support/TargetSelect.h"
34
38
#include " llvm/Support/raw_ostream.h"
35
39
40
+ #include < cstdint>
36
41
#include < cstdlib>
37
42
38
43
using namespace mlir ;
@@ -42,6 +47,9 @@ using namespace mlir::NVVM;
42
47
#define __DEFAULT_CUDATOOLKIT_PATH__ " "
43
48
#endif
44
49
50
+ extern " C" const char _mlir_embedded_libdevice[];
51
+ extern " C" const unsigned _mlir_embedded_libdevice_size;
52
+
45
53
namespace {
46
54
// Implementation of the `TargetAttrInterface` model.
47
55
class NVVMTargetAttrImpl
@@ -130,6 +138,33 @@ ArrayRef<Attribute> SerializeGPUModuleBase::getLibrariesToLink() const {
130
138
131
139
// Try to append `libdevice` from a CUDA toolkit installation.
132
140
LogicalResult SerializeGPUModuleBase::appendStandardLibs () {
141
+ #if MLIR_NVVM_EMBED_LIBDEVICE
142
+ // If libdevice is embedded in the binary, we don't look it up on the
143
+ // filesystem.
144
+ MLIRContext *ctx = target.getContext ();
145
+ auto type =
146
+ RankedTensorType::get (ArrayRef<int64_t >{_mlir_embedded_libdevice_size},
147
+ IntegerType::get (ctx, 8 ));
148
+ auto resourceManager = DenseResourceElementsHandle::getManagerInterface (ctx);
149
+
150
+ // Lookup if we already loaded the resource, otherwise create it.
151
+ DialectResourceBlobManager::BlobEntry *blob =
152
+ resourceManager.getBlobManager ().lookup (" _mlir_embedded_libdevice" );
153
+ if (blob) {
154
+ librariesToLink.push_back (DenseResourceElementsAttr::get (
155
+ type, DenseResourceElementsHandle (
156
+ blob, ctx->getLoadedDialect <BuiltinDialect>())));
157
+ return success ();
158
+ }
159
+
160
+ // Allocate a resource using one of the UnManagedResourceBlob method to wrap
161
+ // the embedded data.
162
+ auto unmanagedBlob = UnmanagedAsmResourceBlob::allocateInferAlign (
163
+ ArrayRef<char >{_mlir_embedded_libdevice, _mlir_embedded_libdevice_size});
164
+ librariesToLink.push_back (DenseResourceElementsAttr::get (
165
+ type, resourceManager.insert (" _mlir_embedded_libdevice" ,
166
+ std::move (unmanagedBlob))));
167
+ #else
133
168
StringRef pathRef = getToolkitPath ();
134
169
if (!pathRef.empty ()) {
135
170
SmallVector<char , 256 > path;
@@ -149,6 +184,7 @@ LogicalResult SerializeGPUModuleBase::appendStandardLibs() {
149
184
}
150
185
librariesToLink.push_back (StringAttr::get (target.getContext (), pathRef));
151
186
}
187
+ #endif
152
188
return success ();
153
189
}
154
190
0 commit comments