First upload version 0.0.1
This commit is contained in:
311
node_modules/node-llama-cpp/dist/bindings/utils/detectAvailableComputeLayers.js
generated
vendored
Normal file
311
node_modules/node-llama-cpp/dist/bindings/utils/detectAvailableComputeLayers.js
generated
vendored
Normal file
@@ -0,0 +1,311 @@
|
||||
import process from "process";
|
||||
import path from "path";
|
||||
import fs from "fs-extra";
|
||||
import semver from "semver";
|
||||
import { getConsoleLogPrefix } from "../../utils/getConsoleLogPrefix.js";
|
||||
import { getPlatform } from "./getPlatform.js";
|
||||
import { hasFileInPath } from "./hasFileInPath.js";
|
||||
import { asyncSome } from "./asyncSome.js";
|
||||
import { asyncEvery } from "./asyncEvery.js";
|
||||
export async function detectAvailableComputeLayers({ platform = getPlatform() } = {}) {
|
||||
const [cuda, vulkan, metal] = await Promise.all([
|
||||
detectCudaSupport({ platform }),
|
||||
detectVulkanSupport({ platform }),
|
||||
detectMetalSupport({ platform })
|
||||
]);
|
||||
return {
|
||||
cuda,
|
||||
vulkan,
|
||||
metal
|
||||
};
|
||||
}
|
||||
async function detectCudaSupport({ platform }) {
|
||||
if (platform === "win") {
|
||||
const librarySearchPaths = (await getCudaInstallationPaths({ platform }))
|
||||
.flatMap((cudaInstallationPath) => [cudaInstallationPath, path.join(cudaInstallationPath, "bin")]);
|
||||
const windir = getWindir();
|
||||
const [hasNvidiaDriver, hasCudaRuntime] = await Promise.all([
|
||||
asyncSome([
|
||||
hasFileInPath("nvml.dll"),
|
||||
fs.pathExists(path.join(windir, "System32", "nvml.dll"))
|
||||
]),
|
||||
asyncEvery([
|
||||
asyncSome([
|
||||
hasFileInPath("cudart64_110.dll", librarySearchPaths),
|
||||
hasFileInPath("cudart64_11.dll", librarySearchPaths),
|
||||
hasFileInPath("cudart64_12.dll", librarySearchPaths),
|
||||
hasFileInPath("cudart64_13.dll", librarySearchPaths) // for when the next version comes out
|
||||
]),
|
||||
asyncSome([
|
||||
hasFileInPath("cublas64_11.dll", librarySearchPaths),
|
||||
hasFileInPath("cublas64_12.dll", librarySearchPaths),
|
||||
hasFileInPath("cublas64_13.dll", librarySearchPaths) // for when the next version comes out
|
||||
]),
|
||||
asyncSome([
|
||||
hasFileInPath("cublasLt64_11.dll", librarySearchPaths),
|
||||
hasFileInPath("cublasLt64_12.dll", librarySearchPaths),
|
||||
hasFileInPath("cublasLt64_13.dll", librarySearchPaths) // for when the next version comes out
|
||||
])
|
||||
])
|
||||
]);
|
||||
return {
|
||||
hasNvidiaDriver,
|
||||
hasCudaRuntime
|
||||
};
|
||||
}
|
||||
else if (platform === "linux") {
|
||||
const cudaLibraryPaths = await getLinuxCudaLibraryPaths();
|
||||
const librarySearchPaths = [
|
||||
process.env.LD_LIBRARY_PATH,
|
||||
process.env.CUDA_PATH,
|
||||
"/usr/lib",
|
||||
"/usr/lib64",
|
||||
"/usr/lib/x86_64-linux-gnu",
|
||||
"/usr/lib/aarch64-linux-gnu",
|
||||
"/usr/lib/armv7l-linux-gnu",
|
||||
...cudaLibraryPaths
|
||||
];
|
||||
const [hasNvidiaDriver, hasCudaRuntime] = await Promise.all([
|
||||
asyncSome([
|
||||
hasFileInPath("libnvidia-ml.so", librarySearchPaths),
|
||||
hasFileInPath("libnvidia-ml.so.1", librarySearchPaths)
|
||||
]),
|
||||
asyncEvery([
|
||||
asyncSome([
|
||||
hasFileInPath("libcuda.so", librarySearchPaths),
|
||||
hasFileInPath("libcuda.so.1", librarySearchPaths)
|
||||
]),
|
||||
asyncSome([
|
||||
hasFileInPath("libcudart.so", librarySearchPaths),
|
||||
hasFileInPath("libcudart.so.11", librarySearchPaths),
|
||||
hasFileInPath("libcudart.so.12", librarySearchPaths),
|
||||
hasFileInPath("libcudart.so.13", librarySearchPaths) // for when the next version comes out
|
||||
]),
|
||||
asyncSome([
|
||||
hasFileInPath("libcublas.so", librarySearchPaths),
|
||||
hasFileInPath("libcublas.so.11", librarySearchPaths),
|
||||
hasFileInPath("libcublas.so.12", librarySearchPaths),
|
||||
hasFileInPath("libcublas.so.13", librarySearchPaths) // for when the next version comes out
|
||||
]),
|
||||
asyncSome([
|
||||
hasFileInPath("libcublasLt.so", librarySearchPaths),
|
||||
hasFileInPath("libcublasLt.so.11", librarySearchPaths),
|
||||
hasFileInPath("libcublasLt.so.12", librarySearchPaths),
|
||||
hasFileInPath("libcublasLt.so.13", librarySearchPaths) // for when the next version comes out
|
||||
])
|
||||
])
|
||||
]);
|
||||
return {
|
||||
hasNvidiaDriver,
|
||||
hasCudaRuntime
|
||||
};
|
||||
}
|
||||
return {
|
||||
hasNvidiaDriver: false,
|
||||
hasCudaRuntime: false
|
||||
};
|
||||
}
|
||||
async function detectVulkanSupport({ platform }) {
|
||||
if (platform === "win") {
|
||||
const windir = getWindir();
|
||||
return await asyncSome([
|
||||
hasFileInPath("vulkan-1.dll"),
|
||||
fs.pathExists(path.join(windir, "System32", "vulkan-1.dll")),
|
||||
fs.pathExists(path.join(windir, "SysWOW64", "vulkan-1.dll"))
|
||||
]);
|
||||
}
|
||||
else if (platform === "linux") {
|
||||
const librarySearchPaths = [
|
||||
process.env.LD_LIBRARY_PATH,
|
||||
"/usr/lib",
|
||||
"/usr/lib64",
|
||||
"/usr/lib/x86_64-linux-gnu",
|
||||
"/usr/lib/aarch64-linux-gnu",
|
||||
"/usr/lib/armv7l-linux-gnu",
|
||||
(process.env.PREFIX != null && process.env.PREFIX?.toLowerCase()?.includes?.("termux"))
|
||||
? `${process.env.PREFIX}/usr/lib`
|
||||
: undefined
|
||||
];
|
||||
return await asyncSome([
|
||||
hasFileInPath("libvulkan.so", librarySearchPaths),
|
||||
hasFileInPath("libvulkan.so.1", librarySearchPaths)
|
||||
]);
|
||||
}
|
||||
else if (platform === "mac") {
|
||||
return await asyncSome([
|
||||
hasFileInPath("libvulkan.dylib"),
|
||||
hasFileInPath("libvulkan.dylib.1")
|
||||
]);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
async function detectMetalSupport({ platform }) {
|
||||
return platform === "mac";
|
||||
}
|
||||
async function getLinuxCudaLibraryPaths() {
|
||||
const res = [];
|
||||
try {
|
||||
for (const cudaInstallationPath of await getCudaInstallationPaths({ platform: "linux" })) {
|
||||
const cudaTargetsFolder = `${cudaInstallationPath}/targets`;
|
||||
if (!(await fs.pathExists(cudaTargetsFolder)))
|
||||
continue;
|
||||
for (const cudaTargetFolderName of await fs.readdir(cudaTargetsFolder)) {
|
||||
res.push(`${cudaTargetsFolder}/${cudaTargetFolderName}/lib`, `${cudaTargetsFolder}/${cudaTargetFolderName}/lib/stubs`);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
console.error(getConsoleLogPrefix() + 'Failed to search "/usr/local/" for CUDA library paths', err);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
async function getCudaInstallationPaths({ platform }) {
|
||||
if (platform === "win") {
|
||||
try {
|
||||
const programFilesPaths = await getWindowsProgramFilesPaths();
|
||||
const potentialCudaInstallationsContainerPaths = programFilesPaths
|
||||
.map((programFilesPath) => `${programFilesPath}/NVIDIA GPU Computing Toolkit/CUDA`);
|
||||
const cudaInstallationsContainerPaths = (await Promise.all(potentialCudaInstallationsContainerPaths.map(async (potentialCudaInstallationsContainerPath) => {
|
||||
if (await fs.pathExists(potentialCudaInstallationsContainerPath))
|
||||
return potentialCudaInstallationsContainerPath;
|
||||
return null;
|
||||
}))).filter((path) => path != null);
|
||||
const potentialCudaInstallations = (await Promise.all(cudaInstallationsContainerPaths.map(async (cudaInstallationsContainerPath) => {
|
||||
const cudaFolderPrefix = "v";
|
||||
return (await fs.pathExists(cudaInstallationsContainerPath)
|
||||
? await fs.readdir(cudaInstallationsContainerPath)
|
||||
: [])
|
||||
.filter((installationFolderName) => installationFolderName.toLowerCase()
|
||||
.startsWith(cudaFolderPrefix))
|
||||
.sort((a, b) => {
|
||||
const aVersion = a.slice(cudaFolderPrefix.length);
|
||||
const bVersion = b.slice(cudaFolderPrefix.length);
|
||||
try {
|
||||
const aVersionValid = semver.valid(semver.coerce(aVersion));
|
||||
const bVersionValid = semver.valid(semver.coerce(bVersion));
|
||||
if (aVersionValid && bVersionValid)
|
||||
return semver.compare(aVersionValid, bVersionValid);
|
||||
else if (aVersionValid)
|
||||
return -1;
|
||||
else if (bVersionValid)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
catch (err) {
|
||||
return 0;
|
||||
}
|
||||
})
|
||||
.reverse()
|
||||
.map((installationFolderName) => `${cudaInstallationsContainerPath}/${installationFolderName}`);
|
||||
}))).flat();
|
||||
if (process.env.CUDA_PATH != null && process.env.CUDA_PATH !== "")
|
||||
potentialCudaInstallations.unshift(process.env.CUDA_PATH);
|
||||
return (await Promise.all(potentialCudaInstallations.map(async (cudaFolder) => {
|
||||
if (await fs.pathExists(cudaFolder))
|
||||
return cudaFolder;
|
||||
return null;
|
||||
}))).filter((cudaFolder) => cudaFolder != null);
|
||||
}
|
||||
catch (err) {
|
||||
console.error(getConsoleLogPrefix() + 'Failed to search "Program Files" for CUDA installations', err);
|
||||
}
|
||||
return [];
|
||||
}
|
||||
else if (platform === "linux") {
|
||||
const res = [];
|
||||
try {
|
||||
const usrLocal = "/usr/local";
|
||||
const cudaFolderPrefix = "cuda-";
|
||||
const potentialCudaFolders = (await fs.pathExists(usrLocal)
|
||||
? await fs.readdir(usrLocal)
|
||||
: [])
|
||||
.filter((usrLocalFolderName) => usrLocalFolderName.toLowerCase().startsWith(cudaFolderPrefix))
|
||||
.sort((a, b) => {
|
||||
const aVersion = a.slice(cudaFolderPrefix.length);
|
||||
const bVersion = b.slice(cudaFolderPrefix.length);
|
||||
try {
|
||||
const aVersionValid = semver.valid(semver.coerce(aVersion));
|
||||
const bVersionValid = semver.valid(semver.coerce(bVersion));
|
||||
if (aVersionValid && bVersionValid)
|
||||
return semver.compare(aVersionValid, bVersionValid);
|
||||
else if (aVersionValid)
|
||||
return -1;
|
||||
else if (bVersionValid)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
catch (err) {
|
||||
return 0;
|
||||
}
|
||||
})
|
||||
.reverse()
|
||||
.map((usrLocalFolderName) => `${usrLocal}/${usrLocalFolderName}`);
|
||||
potentialCudaFolders.unshift(`${usrLocal}/cuda`);
|
||||
if (process.env.CUDA_PATH != null && process.env.CUDA_PATH !== "")
|
||||
potentialCudaFolders.unshift(process.env.CUDA_PATH);
|
||||
for (const cudaFolder of potentialCudaFolders) {
|
||||
const cudaTargetsFolder = `${cudaFolder}/targets`;
|
||||
if (!(await fs.pathExists(cudaTargetsFolder)))
|
||||
continue;
|
||||
res.push(cudaFolder);
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
console.error(getConsoleLogPrefix() + 'Failed to search "/usr/local/" for CUDA installations', err);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
return [];
|
||||
}
|
||||
export async function getCudaNvccPaths({ platform = getPlatform() } = {}) {
|
||||
const cudaInstallationPaths = await getCudaInstallationPaths({ platform });
|
||||
const nvccPotentialPaths = cudaInstallationPaths
|
||||
.map((cudaInstallationPath) => {
|
||||
if (platform === "win")
|
||||
return {
|
||||
nvccPath: path.join(cudaInstallationPath, "bin", "nvcc.exe"),
|
||||
cudaHomePath: cudaInstallationPath
|
||||
};
|
||||
return {
|
||||
nvccPath: path.join(cudaInstallationPath, "bin", "nvcc"),
|
||||
cudaHomePath: cudaInstallationPath
|
||||
};
|
||||
});
|
||||
try {
|
||||
const resolvedPaths = await Promise.all(nvccPotentialPaths.map(async ({ nvccPath, cudaHomePath }) => {
|
||||
if (await fs.pathExists(nvccPath))
|
||||
return { nvccPath, cudaHomePath };
|
||||
return null;
|
||||
}));
|
||||
return resolvedPaths.filter((resolvedPath) => resolvedPath != null);
|
||||
}
|
||||
catch (err) {
|
||||
console.error(getConsoleLogPrefix() + `Failed to search for "nvcc${platform === "win" ? ".exe" : ""}" in CUDA installation paths`, err);
|
||||
}
|
||||
return [];
|
||||
}
|
||||
function getWindir() {
|
||||
return process.env.windir || process.env.WINDIR || process.env.SystemRoot || process.env.systemroot || process.env.SYSTEMROOT ||
|
||||
"C:\\Windows";
|
||||
}
|
||||
export async function getWindowsProgramFilesPaths() {
|
||||
const potentialPaths = await Promise.all([
|
||||
process.env["ProgramFiles(Arm)"],
|
||||
process.env.ProgramFiles,
|
||||
process.env["ProgramFiles(x86)"],
|
||||
`${process.env.SystemDrive ?? "C:"}\\Program Files (Arm)`,
|
||||
`${process.env.SystemDrive ?? "C:"}\\Program Files`,
|
||||
`${process.env.SystemDrive ?? "C:"}\\Program Files (x86)`
|
||||
]
|
||||
.map(async (programFilesPath) => {
|
||||
if (programFilesPath == null)
|
||||
return null;
|
||||
if (await fs.pathExists(programFilesPath))
|
||||
return programFilesPath;
|
||||
return null;
|
||||
}));
|
||||
return Array.from(new Set(potentialPaths.filter((potentialPath) => potentialPath != null)));
|
||||
}
|
||||
//# sourceMappingURL=detectAvailableComputeLayers.js.map
|
||||
Reference in New Issue
Block a user