diff options
| author | jsmall-nvidia <jsmall@nvidia.com> | 2021-04-01 13:39:11 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-04-01 10:39:11 -0700 |
| commit | fa31d21ba92669a521a7768467246918e3947e02 (patch) | |
| tree | af98a593e24bc6309ac4d11a59562be4b22c93d7 /source/core/slang-nvrtc-compiler.cpp | |
| parent | 3f1632a1450a5879f337b4bd178e48880cd583f8 (diff) | |
Added compiler-core project (#1775)
* #include an absolute path didn't work - because paths were taken to always be relative.
* Split out compiler-core initially with just slang-source-loc.cpp
* More lexer, name, token to compiler-core.
* Split Lexer and Core diagnostics.
* Move slang-file-system to core.
* Add slang-file-system to core.
* More DownstreamCompiler into compiler-core
* Fix typo.
* Add compiler-core to bootstrap proj.
* Small fixes to premake
* For linux try with compiler-core
* Remove compiler-core from examples.
* Added NameConventionUtil to compiler-core
* Add global function to CharUtil to *hopefully* avoid linking issue.
* Hack to make linkage of CharUtil work on linux.
Diffstat (limited to 'source/core/slang-nvrtc-compiler.cpp')
| -rw-r--r-- | source/core/slang-nvrtc-compiler.cpp | 773 |
1 files changed, 0 insertions, 773 deletions
diff --git a/source/core/slang-nvrtc-compiler.cpp b/source/core/slang-nvrtc-compiler.cpp deleted file mode 100644 index eb117379f..000000000 --- a/source/core/slang-nvrtc-compiler.cpp +++ /dev/null @@ -1,773 +0,0 @@ -// slang-nvrtc-compiler.cpp -#include "slang-nvrtc-compiler.h" - -#include "slang-common.h" -#include "../../slang-com-helper.h" - -#include "../core/slang-blob.h" - -#include "slang-string-util.h" -#include "slang-string-slice-pool.h" - -#include "slang-io.h" -#include "slang-shared-library.h" -#include "slang-semantic-version.h" - - -namespace nvrtc -{ - -typedef enum { - NVRTC_SUCCESS = 0, - NVRTC_ERROR_OUT_OF_MEMORY = 1, - NVRTC_ERROR_PROGRAM_CREATION_FAILURE = 2, - NVRTC_ERROR_INVALID_INPUT = 3, - NVRTC_ERROR_INVALID_PROGRAM = 4, - NVRTC_ERROR_INVALID_OPTION = 5, - NVRTC_ERROR_COMPILATION = 6, - NVRTC_ERROR_BUILTIN_OPERATION_FAILURE = 7, - NVRTC_ERROR_NO_NAME_EXPRESSIONS_AFTER_COMPILATION = 8, - NVRTC_ERROR_NO_LOWERED_NAMES_BEFORE_COMPILATION = 9, - NVRTC_ERROR_NAME_EXPRESSION_NOT_VALID = 10, - NVRTC_ERROR_INTERNAL_ERROR = 11 -} nvrtcResult; - -typedef struct _nvrtcProgram *nvrtcProgram; - -#define SLANG_NVRTC_FUNCS(x) \ - x(const char*, nvrtcGetErrorString, (nvrtcResult result)) \ - x(nvrtcResult, nvrtcVersion, (int *major, int *minor)) \ - x(nvrtcResult, nvrtcCreateProgram, (nvrtcProgram *prog, const char *src, const char *name, int numHeaders, const char * const *headers, const char * const *includeNames)) \ - x(nvrtcResult, nvrtcDestroyProgram, (nvrtcProgram *prog)) \ - x(nvrtcResult, nvrtcCompileProgram, (nvrtcProgram prog, int numOptions, const char * const *options)) \ - x(nvrtcResult, nvrtcGetPTXSize, (nvrtcProgram prog, size_t *ptxSizeRet)) \ - x(nvrtcResult, nvrtcGetPTX, (nvrtcProgram prog, char *ptx)) \ - x(nvrtcResult, nvrtcGetProgramLogSize, (nvrtcProgram prog, size_t *logSizeRet)) \ - x(nvrtcResult, nvrtcGetProgramLog, (nvrtcProgram prog, char *log))\ - x(nvrtcResult, nvrtcAddNameExpression, (nvrtcProgram prog, const char * const name_expression)) \ - x(nvrtcResult, nvrtcGetLoweredName, (nvrtcProgram prog, const char *const name_expression, const char** lowered_name)) - -} // namespace nvrtc - -namespace Slang -{ -using namespace nvrtc; - -static SlangResult _asResult(nvrtcResult res) -{ - switch (res) - { - case NVRTC_SUCCESS: - { - return SLANG_OK; - } - case NVRTC_ERROR_OUT_OF_MEMORY: - { - return SLANG_E_OUT_OF_MEMORY; - } - case NVRTC_ERROR_PROGRAM_CREATION_FAILURE: - case NVRTC_ERROR_INVALID_INPUT: - case NVRTC_ERROR_INVALID_PROGRAM: - { - return SLANG_FAIL; - } - case NVRTC_ERROR_INVALID_OPTION: - { - return SLANG_E_INVALID_ARG; - } - case NVRTC_ERROR_COMPILATION: - case NVRTC_ERROR_BUILTIN_OPERATION_FAILURE: - case NVRTC_ERROR_NO_NAME_EXPRESSIONS_AFTER_COMPILATION: - case NVRTC_ERROR_NO_LOWERED_NAMES_BEFORE_COMPILATION: - case NVRTC_ERROR_NAME_EXPRESSION_NOT_VALID: - { - return SLANG_FAIL; - } - case NVRTC_ERROR_INTERNAL_ERROR: - { - return SLANG_E_INTERNAL_FAIL; - } - default: return SLANG_FAIL; - } -} - -class NVRTCDownstreamCompiler : public DownstreamCompiler -{ -public: - typedef DownstreamCompiler Super; - - // DownstreamCompiler - virtual SlangResult compile(const CompileOptions& options, RefPtr<DownstreamCompileResult>& outResult) SLANG_OVERRIDE; - virtual ISlangSharedLibrary* getSharedLibrary() SLANG_OVERRIDE { return m_sharedLibrary; } - - /// Must be called before use - SlangResult init(ISlangSharedLibrary* library); - - NVRTCDownstreamCompiler() {} - -protected: - - struct ScopeProgram - { - ScopeProgram(NVRTCDownstreamCompiler* compiler, nvrtcProgram program): - m_compiler(compiler), - m_program(program) - { - } - ~ScopeProgram() - { - m_compiler->m_nvrtcDestroyProgram(&m_program); - } - NVRTCDownstreamCompiler* m_compiler; - nvrtcProgram m_program; - }; - - -#define SLANG_NVTRC_MEMBER_FUNCS(ret, name, params) \ - ret (*m_##name) params; - - SLANG_NVRTC_FUNCS(SLANG_NVTRC_MEMBER_FUNCS); - - ComPtr<ISlangSharedLibrary> m_sharedLibrary; -}; - -#define SLANG_NVRTC_RETURN_ON_FAIL(x) { nvrtcResult _res = x; if (_res != NVRTC_SUCCESS) return _asResult(_res); } - -SlangResult NVRTCDownstreamCompiler::init(ISlangSharedLibrary* library) -{ -#define SLANG_NVTRC_GET_FUNC(ret, name, params) \ - m_##name = (ret (*) params)library->findFuncByName(#name); \ - if (m_##name == nullptr) return SLANG_FAIL; - - SLANG_NVRTC_FUNCS(SLANG_NVTRC_GET_FUNC) - - m_sharedLibrary = library; - - m_desc.type = SLANG_PASS_THROUGH_NVRTC; - - int major, minor; - m_nvrtcVersion(&major, &minor); - m_desc.majorVersion = major; - m_desc.minorVersion = minor; - - return SLANG_OK; -} - -static SlangResult _parseLocation(const UnownedStringSlice& in, DownstreamDiagnostic& outDiagnostic) -{ - const Index startIndex = in.indexOf('('); - - if (startIndex >= 0) - { - outDiagnostic.filePath = UnownedStringSlice(in.begin(), in.begin() + startIndex); - UnownedStringSlice remaining(in.begin() + startIndex + 1, in.end()); - const Int endIndex = remaining.indexOf(')'); - - UnownedStringSlice lineText = UnownedStringSlice(remaining.begin(), remaining.begin() + endIndex); - - Int line; - SLANG_RETURN_ON_FAIL(StringUtil::parseInt(lineText, line)); - outDiagnostic.fileLine = line; - } - else - { - outDiagnostic.fileLine = 0; - outDiagnostic.filePath = in; - } - return SLANG_OK; -} - -static bool _isDriveLetter(char c) -{ - return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'); -} - -static bool _hasDriveLetter(const UnownedStringSlice& line) -{ - return line.getLength() > 2 && line[1] == ':' && _isDriveLetter(line[0]); -} - -static SlangResult _parseNVRTCLine(const UnownedStringSlice& line, DownstreamDiagnostic& outDiagnostic) -{ - typedef DownstreamDiagnostic Diagnostic; - typedef Diagnostic::Severity Severity; - - outDiagnostic.stage = Diagnostic::Stage::Compile; - - List<UnownedStringSlice> split; - if (_hasDriveLetter(line)) - { - // The drive letter has :, which confuses things, so skip that and then fix up first entry - UnownedStringSlice lineWithoutDrive(line.begin() + 2, line.end()); - StringUtil::split(lineWithoutDrive, ':', split); - split[0] = UnownedStringSlice(line.begin(), split[0].end()); - } - else - { - StringUtil::split(line, ':', split); - } - - if (split.getCount() >= 3) - { - // tests/cuda/cuda-compile.cu(7): warning: variable "c" is used before its value is set - - const auto split1 = split[1].trim(); - - if (split1 == "error") - { - outDiagnostic.severity = Severity::Error; - } - else if (split1 == "warning") - { - outDiagnostic.severity = Severity::Warning; - } - outDiagnostic.text = split[2].trim(); - - SLANG_RETURN_ON_FAIL(_parseLocation(split[0], outDiagnostic)); - return SLANG_OK; - } - - return SLANG_E_NOT_FOUND; -} - -SlangResult NVRTCDownstreamCompiler::compile(const CompileOptions& options, RefPtr<DownstreamCompileResult>& outResult) -{ - // This compiler doesn't read files, they should be read externally and stored in sourceContents/sourceContentsPath - if (options.sourceFiles.getCount() > 0) - { - return SLANG_FAIL; - } - - CommandLine cmdLine; - - switch (options.debugInfoType) - { - case DebugInfoType::None: - { - break; - } - default: - { - cmdLine.addArg("--device-debug"); - break; - } - case DebugInfoType::Maximal: - { - cmdLine.addArg("--device-debug"); - cmdLine.addArg("--generate-line-info"); - break; - } - } - - // Don't seem to have such a control, so ignore for now - //switch (options.optimizationLevel) - //{ - // default: break; - //} - - switch (options.floatingPointMode) - { - case FloatingPointMode::Default: break; - case FloatingPointMode::Precise: - { - break; - } - case FloatingPointMode::Fast: - { - cmdLine.addArg("--use_fast_math"); - break; - } - } - - // Add defines - for (const auto& define : options.defines) - { - StringBuilder builder; - builder << "-D"; - builder << define.nameWithSig; - if (define.value.getLength()) - { - builder << "=" << define.value; - } - - cmdLine.addArg(builder); - } - - // Add includes - for (const auto& include : options.includePaths) - { - cmdLine.addArg("-I"); - cmdLine.addArg(include); - } - - // Neither of these options are strictly required, for general use of nvrtc, - // but are enabled to make use withing Slang work more smoothly - { - // Require c++14, as makes initialization construction with {} available and so simplifies code generation - cmdLine.addArg("-std=c++14"); - - // Disable all warnings - // This is arguably too much - but nvrtc does not appear to have a mechanism to switch off individual warnings. - // I tried the -Xcudafe mechanism but that does not appear to work for nvrtc - cmdLine.addArg("-w"); - } - - { - // The lowest supported CUDA architecture version supported - // by NVRTC is `compute_30`. - // - SemanticVersion version(3); - - // Newer releases of NVRTC only support `compute_35` and up - // (with everything before `compute_52` being deprecated). - // - if( m_desc.majorVersion >= 11 ) - { - version = SemanticVersion(3, 5); - } - - // If constructs used in the code to be compield require - // a higher architecture version than the minimum, then - // we will set the version to the highest version listed - // among the requirements. - // - for (const auto& capabilityVersion : options.requiredCapabilityVersions) - { - if (capabilityVersion.kind == DownstreamCompiler::CapabilityVersion::Kind::CUDASM) - { - if (capabilityVersion.version > version) - { - version = capabilityVersion.version; - } - } - } - - StringBuilder builder; - builder << "-arch=compute_"; - builder << version.m_major; - - SLANG_ASSERT(version.m_minor >= 0 && version.m_minor <= 9); - builder << char('0' + version.m_minor); - - cmdLine.addArg(builder); - } - - List<const char*> headers; - List<const char*> headerIncludeNames; - - // If compiling for OptiX, we need to add the appropriate search paths to the command line. - // - if(options.pipelineType == PipelineType::RayTracing) - { - // The device-side OptiX API is accessed through a constellation - // of headers provided by the OptiX SDK, so we need to set an - // include path for the compile that makes those visible. - // - // TODO: The OptiX SDK installer doesn't set any kind of environment - // variable to indicate where the SDK was installed, so we seemingly - // need to probe paths instead. The form of the path will differ - // betwene Windows and Unix-y platforms, and we will need some kind - // of approach to probe multiple versiosn and use the latest. - // - // HACK: For now I'm using the fixed path for the most recent SDK - // release on Windows. This means that OptiX cross-compilation will - // only "work" on a subset of platforms, but that doesn't matter - // for now since it doesn't really "work" at all. - // - cmdLine.addArg("-I"); - cmdLine.addArg("C:/ProgramData/NVIDIA Corporation/OptiX SDK 7.0.0/include/"); - - // The OptiX headers in turn `#include <stddef.h>` and expect that - // to work. We could try to also add in an include path from the CUDA - // SDK (which seems to provide a `stddef.h` in the most recent version), - // but using that version doesn't seem to work (and also bakes in a - // requirement that the user have the CUDA SDK installed in addition - // to the OptiX SDK). - // - // Instead, we will rely on the NVRTC feature that lets us set up - // memory buffers to be used as include files by the we compile. - // We will define a dummy `stddef.h` that includes the bare minimum - // lines required to get the OptiX headers to compile without complaint. - // - // TODO: Confirm that the `LP64` definition herei s actually needed. - // - headerIncludeNames.add("stddef.h"); - headers.add("#pragma once\n" "#define LP64\n"); - - // Finally, we want the CUDA prelude to be able to react to whether - // or not OptiX is required (most notably by `#include`ing the appropriate - // header(s)), so we will insert a preprocessor define to indicate - // the requirement. - // - cmdLine.addArg("-DSLANG_CUDA_ENABLE_OPTIX"); - } - - SLANG_ASSERT(headers.getCount() == headerIncludeNames.getCount()); - - nvrtcProgram program = nullptr; - nvrtcResult res = m_nvrtcCreateProgram(&program, options.sourceContents.getBuffer(), options.sourceContentsPath.getBuffer(), - (int) headers.getCount(), - headers.getBuffer(), - headerIncludeNames.getBuffer()); - if (res != NVRTC_SUCCESS) - { - return _asResult(res); - } - ScopeProgram scope(this, program); - - List<const char*> dstOptions; - dstOptions.setCount(cmdLine.m_args.getCount()); - for (Index i = 0; i < cmdLine.m_args.getCount(); ++i) - { - dstOptions[i] = cmdLine.m_args[i].value.getBuffer(); - } - - res = m_nvrtcCompileProgram(program, int(dstOptions.getCount()), dstOptions.getBuffer()); - - RefPtr<ListBlob> blob; - DownstreamDiagnostics diagnostics; - - diagnostics.result = _asResult(res); - - { - String rawDiagnostics; - - size_t logSize = 0; - SLANG_NVRTC_RETURN_ON_FAIL(m_nvrtcGetProgramLogSize(program, &logSize)); - - if (logSize) - { - char* dst = rawDiagnostics.prepareForAppend(Index(logSize)); - SLANG_NVRTC_RETURN_ON_FAIL(m_nvrtcGetProgramLog(program, dst)); - rawDiagnostics.appendInPlace(dst, Index(logSize)); - - diagnostics.rawDiagnostics = rawDiagnostics; - } - - // Parse the diagnostics here - for (auto line : LineParser(diagnostics.rawDiagnostics.getUnownedSlice())) - { - DownstreamDiagnostic diagnostic; - SlangResult lineRes = _parseNVRTCLine(line, diagnostic); - - if (SLANG_SUCCEEDED(lineRes)) - { - diagnostics.diagnostics.add(diagnostic); - } - else if (lineRes != SLANG_E_NOT_FOUND) - { - return lineRes; - } - } - - // if it has a compilation error.. set on output - if (diagnostics.has(DownstreamDiagnostic::Severity::Error)) - { - diagnostics.result = SLANG_FAIL; - } - } - - if (res == nvrtc::NVRTC_SUCCESS) - { - // We should parse the log to set up the diagnostics - size_t ptxSize; - SLANG_NVRTC_RETURN_ON_FAIL(m_nvrtcGetPTXSize(program, &ptxSize)); - - List<uint8_t> ptx; - ptx.setCount(Index(ptxSize)); - - SLANG_NVRTC_RETURN_ON_FAIL(m_nvrtcGetPTX(program, (char*)ptx.getBuffer())); - - blob = ListBlob::moveCreate(ptx); - } - - outResult = new BlobDownstreamCompileResult(diagnostics, blob); - - return SLANG_OK; -} - -/* An implementation of Path::Visitor that can be used for finding NVRTC shared library installations. */ -struct NVRTCPathVisitor : Path::Visitor -{ - struct Candidate - { - typedef Candidate ThisType; - - bool operator==(const ThisType& rhs) const { return path == rhs.path && version == rhs.version; } - bool operator!=(const ThisType& rhs) const { return !(*this == rhs); } - - static Candidate make(const String& path, const SemanticVersion& version) - { - Candidate can; - can.version = version; - can.path = path; - return can; - } - String path; - SemanticVersion version; - }; - - Index findVersion(const SemanticVersion& version) const - { - const Index count = m_candidates.getCount(); - for (Index i = 0; i < count; ++i) - { - if (m_candidates[i].version == version) - { - return i; - } - } - return -1; - } - - static bool _orderCandiate(const Candidate& a, const Candidate& b) { return a.version < b.version; } - void sortCandidates() { m_candidates.sort(_orderCandiate); } - - void accept(Path::Type type, const UnownedStringSlice& filename) SLANG_OVERRIDE - { - // Lets make sure it start's with nvrtc64, but not worry about case - if (type == Path::Type::File) - { - // If there is a defined extension, make sure it has it - if (m_postfix.getLength() && filename.getLength() >= m_postfix.getLength()) - { - // We test without case - really for windows - UnownedStringSlice filenamePostfix = filename.tail(filename.getLength() - m_postfix.getLength()); - if (!filenamePostfix.caseInsensitiveEquals(m_postfix.getUnownedSlice())) - { - return; - } - } - - if (filename.getLength() >= m_prefix.getLength() && - filename.subString(0, m_prefix.getLength()).caseInsensitiveEquals(m_prefix.getUnownedSlice())) - { - // Versions are typically (on windows) of the form - // nvrtc64_110_2.dll - // 11 - Major - // 0 Minor - // 2 Patch - Index endIndex = filename.indexOf('.'); - endIndex = (endIndex < 0) ? filename.getLength() : endIndex; - - UnownedStringSlice versionSlice = UnownedStringSlice(filename.begin() + m_prefix.getLength(), filename.begin() + endIndex); - - Int patch = 0; - UnownedStringSlice majorMinorSlice; - { - List<UnownedStringSlice> slices; - StringUtil::split(versionSlice, '_', slices); - if (slices.getCount() >= 2) - { - // We don't bother checking for error here, if it's not parsable, it will be 0 - StringUtil::parseInt(slices[1], patch); - } - majorMinorSlice = slices[0]; - } - - if (majorMinorSlice.getLength() < 2) - { - // Must be a major and minor - return; - } - - UnownedStringSlice majorSlice = majorMinorSlice.head(majorMinorSlice.getLength() - 1); - UnownedStringSlice minorSlice = majorMinorSlice.subString(majorMinorSlice.getLength() - 1, 1); - - Int major; - Int minor; - - if (SLANG_FAILED(StringUtil::parseInt(majorSlice, major)) || - SLANG_FAILED(StringUtil::parseInt(minorSlice, minor))) - { - return; - } - - const SemanticVersion version = SemanticVersion(int(major), int(minor), int(patch)); - - // We may want to add multiple versions, if they are in different locations - as there may be multiple entries - // in the PATH, and only one works. We'll only know which works by loading -#if 0 - // We already found this version, so let's not add it again - if (findVersion(version) >= 0) - { - return; - } -#endif - - // Strip to make a shared library name - UnownedStringSlice sharedLibraryName = filename.tail(m_prefix.getLength() - m_sharedLibraryStem.getLength()); - sharedLibraryName = filename.head(filename.getLength() - m_postfix.getLength()); - - auto candidate = Candidate::make(Path::combine(m_basePath, sharedLibraryName), version); - - // If we already have this candidate, then skip - if (m_candidates.indexOf(candidate) >= 0) - { - return; - } - - // Add to the list of candidates - m_candidates.add(candidate); - } - } - } - - SlangResult findInDirectory(const String& path) - { - m_basePath = path; - return Path::find(path, nullptr, this); - } - - bool hasCandidates() const { return m_candidates.getCount() > 0; } - - NVRTCPathVisitor(const UnownedStringSlice& sharedLibraryStem): - m_sharedLibraryStem(sharedLibraryStem) - { - // Work out the prefix and postfix of the shader - StringBuilder buf; - SharedLibrary::appendPlatformFileName(sharedLibraryStem, buf); - const Index index = buf.indexOf(sharedLibraryStem); - SLANG_ASSERT(index >= 0); - - m_prefix = buf.getUnownedSlice().head(index + sharedLibraryStem.getLength()); - m_postfix = buf.getUnownedSlice().tail(index + sharedLibraryStem.getLength()); - } - - String m_prefix; - String m_postfix; - String m_basePath; - String m_sharedLibraryStem; - - List<Candidate> m_candidates; -}; - -static SlangResult _findAndLoadNVRTC(ISlangSharedLibraryLoader* loader, ComPtr<ISlangSharedLibrary>& outLibrary) -{ -#if SLANG_WINDOWS_FAMILY - // We only need to search 64 bit versions on windows - NVRTCPathVisitor visitor(UnownedStringSlice::fromLiteral("nvrtc64_")); - - // First try the instance path (if supported on platform) - { - StringBuilder instancePath; - if (SLANG_SUCCEEDED(PlatformUtil::getInstancePath(instancePath))) - { - visitor.findInDirectory(instancePath); - } - } - - // If we don't have a candidate try CUDA_PATH - if (!visitor.hasCandidates()) - { - StringBuilder buf; - if (!SLANG_SUCCEEDED(PlatformUtil::getEnvironmentVariable(UnownedStringSlice::fromLiteral("CUDA_PATH"), buf))) - { - // Look for candidates in the directory - visitor.findInDirectory(Path::combine(buf, "bin")); - } - } - - // If we haven't we go searching through PATH - if (!visitor.hasCandidates()) - { - List<UnownedStringSlice> splitPath; - - StringBuilder buf; - if (SLANG_SUCCEEDED(PlatformUtil::getEnvironmentVariable(UnownedStringSlice::fromLiteral("PATH"), buf))) - { - // Split so we get individual paths - List<UnownedStringSlice> paths; - StringUtil::split(buf.getUnownedSlice(), ';', paths); - - // We use a pool to make sure we only check each path once - StringSlicePool pool(StringSlicePool::Style::Empty); - - // We are going to search the paths in order - for (const auto path : paths) - { - // PATH can have the same path multiple times. If we have already searched this path, we don't need to again - if (!pool.has(path)) - { - pool.add(path); - - Path::split(path, splitPath); - - // We could search every path, but here we restrict to paths that look like CUDA installations. - // It's a path that contains a CUDA directory and has bin - if (splitPath.indexOf("CUDA") >= 0 && splitPath[splitPath.getCount() - 1].caseInsensitiveEquals(UnownedStringSlice::fromLiteral("bin"))) - { - // Okay lets search it - visitor.findInDirectory(path); - } - } - } - } - } - - // Put into version order with oldest first. - visitor.sortCandidates(); - - // We want to start with the newest version... - for (Index i = visitor.m_candidates.getCount() - 1; i >= 0; --i) - { - const auto& candidate = visitor.m_candidates[i]; - if (SLANG_SUCCEEDED(loader->loadSharedLibrary(candidate.path.getBuffer(), outLibrary.writeRef()))) - { - return SLANG_OK; - } - } -#endif - // This is an official-ish list of versions is here: - // https://developer.nvidia.com/cuda-toolkit-archive - - // Filenames for NVRTC - // https://docs.nvidia.com/cuda/nvrtc/index.html - // - // From this it appears on platforms other than windows the SharedLibrary name - // should be nvrtc which is already tried, so we can give up now. - return SLANG_E_NOT_FOUND; -} - -/* static */SlangResult NVRTCDownstreamCompilerUtil::locateCompilers(const String& path, ISlangSharedLibraryLoader* loader, DownstreamCompilerSet* set) -{ - ComPtr<ISlangSharedLibrary> library; - - // If the user supplies a path to their preferred version of NVRTC, - // we just use this. - if (path.getLength() != 0) - { - SLANG_RETURN_ON_FAIL(loader->loadSharedLibrary(path.getBuffer(), library.writeRef())); - } - else - { - // As a catch-all for non-Windows platforms, we search for - // a library simply named `nvrtc` (well, `libnvrtc`) which - // is expected to match whatever the user has installed. - // - // On Windows an installation could place the version of nvrtc it uses in the same directory - // as the slang binary, such that it's loaded. - // Using this name also allows a ISlangSharedLibraryLoader to easily identify what is required - // and perhaps load a specific version - if (SLANG_FAILED(loader->loadSharedLibrary("nvrtc", library.writeRef()))) - { - // Try something more sophisticated to locate NVRTC - SLANG_RETURN_ON_FAIL(_findAndLoadNVRTC(loader, library)); - } - } - - SLANG_ASSERT(library); - if (!library) - { - return SLANG_FAIL; - } - - RefPtr<NVRTCDownstreamCompiler> compiler(new NVRTCDownstreamCompiler); - SLANG_RETURN_ON_FAIL(compiler->init(library)); - - set->addCompiler(compiler); - return SLANG_OK; -} - - -} |
