1616#include " mlir/Dialect/GPU/IR/CompilationInterfaces.h"
1717#include " mlir/Dialect/GPU/IR/GPUDialect.h"
1818#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"
1923#include " mlir/Target/LLVM/NVVM/Utils.h"
2024#include " mlir/Target/LLVMIR/Dialect/GPU/GPUToLLVMIRTranslation.h"
2125#include " mlir/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.h"
3337#include " llvm/Support/TargetSelect.h"
3438#include " llvm/Support/raw_ostream.h"
3539
40+ #include < cstdint>
3641#include < cstdlib>
3742
3843using namespace mlir ;
@@ -42,6 +47,9 @@ using namespace mlir::NVVM;
4247#define __DEFAULT_CUDATOOLKIT_PATH__ " "
4348#endif
4449
50+ extern " C" const char _mlir_embedded_libdevice[];
51+ extern " C" const unsigned _mlir_embedded_libdevice_size;
52+
4553namespace {
4654// Implementation of the `TargetAttrInterface` model.
4755class NVVMTargetAttrImpl
@@ -130,6 +138,33 @@ ArrayRef<Attribute> SerializeGPUModuleBase::getLibrariesToLink() const {
130138
131139// Try to append `libdevice` from a CUDA toolkit installation.
132140LogicalResult 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
133168 StringRef pathRef = getToolkitPath ();
134169 if (!pathRef.empty ()) {
135170 SmallVector<char , 256 > path;
@@ -149,6 +184,7 @@ LogicalResult SerializeGPUModuleBase::appendStandardLibs() {
149184 }
150185 librariesToLink.push_back (StringAttr::get (target.getContext (), pathRef));
151186 }
187+ #endif
152188 return success ();
153189}
154190
0 commit comments