diff --git a/cspell.config.yaml b/cspell.config.yaml index 170864c..7af4591 100644 --- a/cspell.config.yaml +++ b/cspell.config.yaml @@ -52,6 +52,7 @@ words: - gcornut - giteeai - gltf + - gpuu - grammyjs - groq - guiiai diff --git a/packages/gpuu/package.json b/packages/gpuu/package.json new file mode 100644 index 0000000..62fd8f7 --- /dev/null +++ b/packages/gpuu/package.json @@ -0,0 +1,50 @@ +{ + "name": "@proj-airi/gpuu", + "type": "module", + "private": true, + "description": "A collection of utilities for working with GPUs, especially for WebGPU.", + "author": { + "name": "Neko Ayaka", + "email": "neko@ayaka.moe", + "url": "https://github.com/nekomeowww" + }, + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/moeru-ai/airi.git", + "directory": "packages/gpuu" + }, + "exports": { + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.mjs", + "require": "./dist/index.cjs" + }, + "./webgpu": { + "types": "./dist/webgpu/index.d.ts", + "import": "./dist/webgpu/index.mjs", + "require": "./dist/webgpu/index.cjs" + } + }, + "main": "./dist/index.cjs", + "module": "./dist/index.mjs", + "types": "./dist/index.d.ts", + "files": [ + "README.md", + "dist", + "package.json" + ], + "scripts": { + "dev": "pnpm run stub", + "stub": "unbuild --stub", + "build": "unbuild", + "typecheck": "tsc --noEmit" + }, + "dependencies": { + "defu": "^6.1.4" + }, + "devDependencies": { + "@types/node": "^22.13.8", + "@webgpu/types": "^0.1.54" + } +} diff --git a/packages/gpuu/src/index.ts b/packages/gpuu/src/index.ts new file mode 100644 index 0000000..9013cfe --- /dev/null +++ b/packages/gpuu/src/index.ts @@ -0,0 +1 @@ +console.warn('Please import \'@proj-airi/gpuu\' instead.') diff --git a/packages/gpuu/src/webgpu/checker.ts b/packages/gpuu/src/webgpu/checker.ts new file mode 100644 index 0000000..778e570 --- /dev/null +++ b/packages/gpuu/src/webgpu/checker.ts @@ -0,0 +1,36 @@ +export interface WebGPUCheckResult { + supported: boolean + fp16Supported: boolean + isNode: boolean + reason: string + adapter?: GPUAdapter +} + +export async function check(): Promise { + try { + if (isInNodejsRuntime()) + return { supported: false, isNode: true, reason: '', fp16Supported: false } + + if (typeof navigator === 'undefined' || !navigator.gpu) + return { supported: false, isNode: false, reason: 'WebGPU is not available (navigator.gpu is undefined)', fp16Supported: false } + + const adapter = await navigator.gpu.requestAdapter() + if (!adapter) + return { supported: false, isNode: false, reason: 'WebGPU is not supported (no adapter found)', fp16Supported: false } + + return { supported: true, isNode: false, reason: '', adapter, fp16Supported: adapter.features.has('shader-f16') } + } + catch (error) { + const errorMessage = error instanceof Error ? error.toString() : String(error) + return { supported: false, isNode: false, reason: errorMessage, fp16Supported: false } + } +} + +function isInNodejsRuntime() { + // eslint-disable-next-line node/prefer-global/process + return typeof process !== 'undefined' + // eslint-disable-next-line node/prefer-global/process + && 'versions' in process && process.versions != null && typeof process.versions === 'object' + // eslint-disable-next-line node/prefer-global/process + && 'node' in process.versions && process.versions.node != null +} diff --git a/packages/gpuu/src/webgpu/index.ts b/packages/gpuu/src/webgpu/index.ts new file mode 100644 index 0000000..484b939 --- /dev/null +++ b/packages/gpuu/src/webgpu/index.ts @@ -0,0 +1,2 @@ +export { check } from './checker' +export type { WebGPUCheckResult } from './checker' diff --git a/packages/gpuu/tsconfig.json b/packages/gpuu/tsconfig.json new file mode 100644 index 0000000..30180dc --- /dev/null +++ b/packages/gpuu/tsconfig.json @@ -0,0 +1,29 @@ +{ + "compilerOptions": { + "target": "ESNext", + "lib": [ + "ESNext", + "DOM", + "DOM.Iterable", + "WebWorker" + ], + "module": "ESNext", + "moduleResolution": "bundler", + "types": [ + "node", + // @webgpu/types + // https://www.npmjs.com/package/@webgpu/types + "@webgpu/types" + ], + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "isolatedModules": true, + "verbatimModuleSyntax": true, + "skipLibCheck": true + }, + "include": [ + "src/**/*.ts", + "src/**/*.d.ts", + "src/**/*.mts" + ] +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 260d10f..6e6d026 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -707,6 +707,9 @@ importers: '@shikijs/markdown-it': specifier: ^3.1.0 version: 3.1.0(markdown-it-async@2.0.0) + '@types/json-schema': + specifier: ^7.0.15 + version: 7.0.15 '@types/markdown-it-link-attributes': specifier: ^3.0.5 version: 3.0.5 @@ -927,6 +930,19 @@ importers: specifier: ^1.52.0 version: 1.52.0(encoding@0.1.13) + packages/gpuu: + dependencies: + defu: + specifier: ^6.1.4 + version: 6.1.4 + devDependencies: + '@types/node': + specifier: ^22.13.8 + version: 22.13.8 + '@webgpu/types': + specifier: ^0.1.54 + version: 0.1.54 + packages/hfup: dependencies: defu: