node-gpuinfo 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +674 -0
- package/README.md +336 -0
- package/binding.gyp +69 -0
- package/build/Release/gpu.exp +0 -0
- package/build/Release/gpu.lib +0 -0
- package/build/Release/gpu.node +0 -0
- package/build/Release/gpu.pdb +0 -0
- package/build/binding.sln +19 -0
- package/build/gpu.vcxproj +175 -0
- package/build/gpu.vcxproj.filters +169 -0
- package/example.js +69 -0
- package/index.js +33 -0
- package/package.json +68 -0
- package/src/binding.cpp +201 -0
- package/src/gpu_info.c +130 -0
- package/src/gpu_info.h +86 -0
- package/src/includes/adlx/ADLX.h +367 -0
- package/src/includes/adlx/ADLXDefines.h +1345 -0
- package/src/includes/adlx/ADLXHelper/ADLXHelper.c +175 -0
- package/src/includes/adlx/ADLXHelper/ADLXHelper.h +245 -0
- package/src/includes/adlx/ADLXHelper/WinAPIS.c +64 -0
- package/src/includes/adlx/ADLXStructures.h +206 -0
- package/src/includes/adlx/ADLXVersion.h +18 -0
- package/src/includes/adlx/I3DSettings.h +3476 -0
- package/src/includes/adlx/I3DSettings1.h +292 -0
- package/src/includes/adlx/I3DSettings2.h +317 -0
- package/src/includes/adlx/IApplications.h +397 -0
- package/src/includes/adlx/IChangedEvent.h +71 -0
- package/src/includes/adlx/ICollections.h +325 -0
- package/src/includes/adlx/IDesktops.h +918 -0
- package/src/includes/adlx/IDisplay3DLUT.h +663 -0
- package/src/includes/adlx/IDisplayGamma.h +683 -0
- package/src/includes/adlx/IDisplayGamut.h +760 -0
- package/src/includes/adlx/IDisplaySettings.h +3476 -0
- package/src/includes/adlx/IDisplays.h +2676 -0
- package/src/includes/adlx/IDisplays1.h +191 -0
- package/src/includes/adlx/IDisplays2.h +188 -0
- package/src/includes/adlx/IDisplays3.h +256 -0
- package/src/includes/adlx/IGPUAutoTuning.h +460 -0
- package/src/includes/adlx/IGPUManualFanTuning.h +1007 -0
- package/src/includes/adlx/IGPUManualGFXTuning.h +607 -0
- package/src/includes/adlx/IGPUManualPowerTuning.h +340 -0
- package/src/includes/adlx/IGPUManualVRAMTuning.h +576 -0
- package/src/includes/adlx/IGPUPresetTuning.h +469 -0
- package/src/includes/adlx/IGPUTuning.h +1239 -0
- package/src/includes/adlx/IGPUTuning1.h +197 -0
- package/src/includes/adlx/II2C.h +198 -0
- package/src/includes/adlx/ILog.h +72 -0
- package/src/includes/adlx/IMultiMedia.h +578 -0
- package/src/includes/adlx/IPerformanceMonitoring.h +2520 -0
- package/src/includes/adlx/IPerformanceMonitoring1.h +134 -0
- package/src/includes/adlx/IPerformanceMonitoring2.h +341 -0
- package/src/includes/adlx/IPerformanceMonitoring3.h +199 -0
- package/src/includes/adlx/IPowerTuning.h +473 -0
- package/src/includes/adlx/IPowerTuning1.h +515 -0
- package/src/includes/adlx/ISmartAccessMemory.h +114 -0
- package/src/includes/adlx/ISystem.h +1557 -0
- package/src/includes/adlx/ISystem1.h +237 -0
- package/src/includes/adlx/ISystem2.h +643 -0
- package/src/linux/amd_linux.c +269 -0
- package/src/linux/intel_linux.c +20 -0
- package/src/linux/nvidia_linux.c +257 -0
- package/src/macos/amd_mac.c +131 -0
- package/src/macos/intel_mac.c +131 -0
- package/src/macos/nvidia_mac.c +21 -0
- package/src/vendor/amd.c +37 -0
- package/src/vendor/intel.c +37 -0
- package/src/vendor/nvidia.c +37 -0
- package/src/windows/amd_windows.c +468 -0
- package/src/windows/intel_windows.c +157 -0
- package/src/windows/nvidia_windows.c +252 -0
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
3
|
+
<ItemGroup>
|
|
4
|
+
<Filter Include="..">
|
|
5
|
+
<UniqueIdentifier>{739DB09A-CC57-A953-A6CF-F64FA08E4FA7}</UniqueIdentifier>
|
|
6
|
+
</Filter>
|
|
7
|
+
<Filter Include="..\src">
|
|
8
|
+
<UniqueIdentifier>{8CDEE807-BC53-E450-C8B8-4DEBB66742D4}</UniqueIdentifier>
|
|
9
|
+
</Filter>
|
|
10
|
+
<Filter Include="..">
|
|
11
|
+
<UniqueIdentifier>{739DB09A-CC57-A953-A6CF-F64FA08E4FA7}</UniqueIdentifier>
|
|
12
|
+
</Filter>
|
|
13
|
+
<Filter Include="..\src">
|
|
14
|
+
<UniqueIdentifier>{8CDEE807-BC53-E450-C8B8-4DEBB66742D4}</UniqueIdentifier>
|
|
15
|
+
</Filter>
|
|
16
|
+
<Filter Include="..">
|
|
17
|
+
<UniqueIdentifier>{739DB09A-CC57-A953-A6CF-F64FA08E4FA7}</UniqueIdentifier>
|
|
18
|
+
</Filter>
|
|
19
|
+
<Filter Include="..\src">
|
|
20
|
+
<UniqueIdentifier>{8CDEE807-BC53-E450-C8B8-4DEBB66742D4}</UniqueIdentifier>
|
|
21
|
+
</Filter>
|
|
22
|
+
<Filter Include="..\src\vendor">
|
|
23
|
+
<UniqueIdentifier>{DB63429E-9D27-F281-39C4-285ED58EA02F}</UniqueIdentifier>
|
|
24
|
+
</Filter>
|
|
25
|
+
<Filter Include="..">
|
|
26
|
+
<UniqueIdentifier>{739DB09A-CC57-A953-A6CF-F64FA08E4FA7}</UniqueIdentifier>
|
|
27
|
+
</Filter>
|
|
28
|
+
<Filter Include="..\src">
|
|
29
|
+
<UniqueIdentifier>{8CDEE807-BC53-E450-C8B8-4DEBB66742D4}</UniqueIdentifier>
|
|
30
|
+
</Filter>
|
|
31
|
+
<Filter Include="..\src\vendor">
|
|
32
|
+
<UniqueIdentifier>{DB63429E-9D27-F281-39C4-285ED58EA02F}</UniqueIdentifier>
|
|
33
|
+
</Filter>
|
|
34
|
+
<Filter Include="..">
|
|
35
|
+
<UniqueIdentifier>{739DB09A-CC57-A953-A6CF-F64FA08E4FA7}</UniqueIdentifier>
|
|
36
|
+
</Filter>
|
|
37
|
+
<Filter Include="..\src">
|
|
38
|
+
<UniqueIdentifier>{8CDEE807-BC53-E450-C8B8-4DEBB66742D4}</UniqueIdentifier>
|
|
39
|
+
</Filter>
|
|
40
|
+
<Filter Include="..\src\vendor">
|
|
41
|
+
<UniqueIdentifier>{DB63429E-9D27-F281-39C4-285ED58EA02F}</UniqueIdentifier>
|
|
42
|
+
</Filter>
|
|
43
|
+
<Filter Include="..">
|
|
44
|
+
<UniqueIdentifier>{739DB09A-CC57-A953-A6CF-F64FA08E4FA7}</UniqueIdentifier>
|
|
45
|
+
</Filter>
|
|
46
|
+
<Filter Include="..\src">
|
|
47
|
+
<UniqueIdentifier>{8CDEE807-BC53-E450-C8B8-4DEBB66742D4}</UniqueIdentifier>
|
|
48
|
+
</Filter>
|
|
49
|
+
<Filter Include="..\src\windows">
|
|
50
|
+
<UniqueIdentifier>{C1450D01-C033-76F3-3763-6DE88AF48A77}</UniqueIdentifier>
|
|
51
|
+
</Filter>
|
|
52
|
+
<Filter Include="..">
|
|
53
|
+
<UniqueIdentifier>{739DB09A-CC57-A953-A6CF-F64FA08E4FA7}</UniqueIdentifier>
|
|
54
|
+
</Filter>
|
|
55
|
+
<Filter Include="..\src">
|
|
56
|
+
<UniqueIdentifier>{8CDEE807-BC53-E450-C8B8-4DEBB66742D4}</UniqueIdentifier>
|
|
57
|
+
</Filter>
|
|
58
|
+
<Filter Include="..\src\windows">
|
|
59
|
+
<UniqueIdentifier>{C1450D01-C033-76F3-3763-6DE88AF48A77}</UniqueIdentifier>
|
|
60
|
+
</Filter>
|
|
61
|
+
<Filter Include="..">
|
|
62
|
+
<UniqueIdentifier>{739DB09A-CC57-A953-A6CF-F64FA08E4FA7}</UniqueIdentifier>
|
|
63
|
+
</Filter>
|
|
64
|
+
<Filter Include="..\src">
|
|
65
|
+
<UniqueIdentifier>{8CDEE807-BC53-E450-C8B8-4DEBB66742D4}</UniqueIdentifier>
|
|
66
|
+
</Filter>
|
|
67
|
+
<Filter Include="..\src\windows">
|
|
68
|
+
<UniqueIdentifier>{C1450D01-C033-76F3-3763-6DE88AF48A77}</UniqueIdentifier>
|
|
69
|
+
</Filter>
|
|
70
|
+
<Filter Include="..">
|
|
71
|
+
<UniqueIdentifier>{739DB09A-CC57-A953-A6CF-F64FA08E4FA7}</UniqueIdentifier>
|
|
72
|
+
</Filter>
|
|
73
|
+
<Filter Include="..\src">
|
|
74
|
+
<UniqueIdentifier>{8CDEE807-BC53-E450-C8B8-4DEBB66742D4}</UniqueIdentifier>
|
|
75
|
+
</Filter>
|
|
76
|
+
<Filter Include="..\src\includes">
|
|
77
|
+
<UniqueIdentifier>{7D4666A0-7903-1110-FE31-54663A46932E}</UniqueIdentifier>
|
|
78
|
+
</Filter>
|
|
79
|
+
<Filter Include="..\src\includes\adlx">
|
|
80
|
+
<UniqueIdentifier>{00A4720B-62F7-E6BC-4A80-2DC4C97AFB43}</UniqueIdentifier>
|
|
81
|
+
</Filter>
|
|
82
|
+
<Filter Include="..\src\includes\adlx\ADLXHelper">
|
|
83
|
+
<UniqueIdentifier>{230812EB-C8DA-5D04-0516-B8E67106717E}</UniqueIdentifier>
|
|
84
|
+
</Filter>
|
|
85
|
+
<Filter Include="..">
|
|
86
|
+
<UniqueIdentifier>{739DB09A-CC57-A953-A6CF-F64FA08E4FA7}</UniqueIdentifier>
|
|
87
|
+
</Filter>
|
|
88
|
+
<Filter Include="..\src">
|
|
89
|
+
<UniqueIdentifier>{8CDEE807-BC53-E450-C8B8-4DEBB66742D4}</UniqueIdentifier>
|
|
90
|
+
</Filter>
|
|
91
|
+
<Filter Include="..\src\includes">
|
|
92
|
+
<UniqueIdentifier>{7D4666A0-7903-1110-FE31-54663A46932E}</UniqueIdentifier>
|
|
93
|
+
</Filter>
|
|
94
|
+
<Filter Include="..\src\includes\adlx">
|
|
95
|
+
<UniqueIdentifier>{00A4720B-62F7-E6BC-4A80-2DC4C97AFB43}</UniqueIdentifier>
|
|
96
|
+
</Filter>
|
|
97
|
+
<Filter Include="..\src\includes\adlx\ADLXHelper">
|
|
98
|
+
<UniqueIdentifier>{230812EB-C8DA-5D04-0516-B8E67106717E}</UniqueIdentifier>
|
|
99
|
+
</Filter>
|
|
100
|
+
<Filter Include="C:">
|
|
101
|
+
<UniqueIdentifier>{7B735499-E5DD-1C2B-6C26-70023832A1CF}</UniqueIdentifier>
|
|
102
|
+
</Filter>
|
|
103
|
+
<Filter Include="C:\Users">
|
|
104
|
+
<UniqueIdentifier>{E9F714C1-DA89-54E2-60CF-39FEB20BF756}</UniqueIdentifier>
|
|
105
|
+
</Filter>
|
|
106
|
+
<Filter Include="C:\Users\oxmc">
|
|
107
|
+
<UniqueIdentifier>{16C4EF74-13EA-84F4-1FCD-E855EF9CF51A}</UniqueIdentifier>
|
|
108
|
+
</Filter>
|
|
109
|
+
<Filter Include="C:\Users\oxmc\Documents">
|
|
110
|
+
<UniqueIdentifier>{87566BA0-CA33-1144-65F5-087C5F9D6C20}</UniqueIdentifier>
|
|
111
|
+
</Filter>
|
|
112
|
+
<Filter Include="C:\Users\oxmc\Documents\Github">
|
|
113
|
+
<UniqueIdentifier>{61AF0388-6A36-F721-D5C4-52DAD1BC98B5}</UniqueIdentifier>
|
|
114
|
+
</Filter>
|
|
115
|
+
<Filter Include="C:\Users\oxmc\Documents\Github\nodeGPU">
|
|
116
|
+
<UniqueIdentifier>{46CE6DFF-F029-A042-EDBA-2C316EC513C6}</UniqueIdentifier>
|
|
117
|
+
</Filter>
|
|
118
|
+
<Filter Include="C:\Users\oxmc\Documents\Github\nodeGPU\node_modules">
|
|
119
|
+
<UniqueIdentifier>{56DF7A98-063D-FB9D-485C-089023B4C16A}</UniqueIdentifier>
|
|
120
|
+
</Filter>
|
|
121
|
+
<Filter Include="C:\Users\oxmc\Documents\Github\nodeGPU\node_modules\node-gyp">
|
|
122
|
+
<UniqueIdentifier>{77348C0E-2034-7791-74D5-63C077DF5A3B}</UniqueIdentifier>
|
|
123
|
+
</Filter>
|
|
124
|
+
<Filter Include="C:\Users\oxmc\Documents\Github\nodeGPU\node_modules\node-gyp\src">
|
|
125
|
+
<UniqueIdentifier>{8CDEE807-BC53-E450-C8B8-4DEBB66742D4}</UniqueIdentifier>
|
|
126
|
+
</Filter>
|
|
127
|
+
<Filter Include="..">
|
|
128
|
+
<UniqueIdentifier>{739DB09A-CC57-A953-A6CF-F64FA08E4FA7}</UniqueIdentifier>
|
|
129
|
+
</Filter>
|
|
130
|
+
</ItemGroup>
|
|
131
|
+
<ItemGroup>
|
|
132
|
+
<ClCompile Include="..\src\binding.cpp">
|
|
133
|
+
<Filter>..\src</Filter>
|
|
134
|
+
</ClCompile>
|
|
135
|
+
<ClCompile Include="..\src\gpu_info.c">
|
|
136
|
+
<Filter>..\src</Filter>
|
|
137
|
+
</ClCompile>
|
|
138
|
+
<ClCompile Include="..\src\vendor\nvidia.c">
|
|
139
|
+
<Filter>..\src\vendor</Filter>
|
|
140
|
+
</ClCompile>
|
|
141
|
+
<ClCompile Include="..\src\vendor\amd.c">
|
|
142
|
+
<Filter>..\src\vendor</Filter>
|
|
143
|
+
</ClCompile>
|
|
144
|
+
<ClCompile Include="..\src\vendor\intel.c">
|
|
145
|
+
<Filter>..\src\vendor</Filter>
|
|
146
|
+
</ClCompile>
|
|
147
|
+
<ClCompile Include="..\src\windows\nvidia_windows.c">
|
|
148
|
+
<Filter>..\src\windows</Filter>
|
|
149
|
+
</ClCompile>
|
|
150
|
+
<ClCompile Include="..\src\windows\amd_windows.c">
|
|
151
|
+
<Filter>..\src\windows</Filter>
|
|
152
|
+
</ClCompile>
|
|
153
|
+
<ClCompile Include="..\src\windows\intel_windows.c">
|
|
154
|
+
<Filter>..\src\windows</Filter>
|
|
155
|
+
</ClCompile>
|
|
156
|
+
<ClCompile Include="..\src\includes\adlx\ADLXHelper\ADLXHelper.c">
|
|
157
|
+
<Filter>..\src\includes\adlx\ADLXHelper</Filter>
|
|
158
|
+
</ClCompile>
|
|
159
|
+
<ClCompile Include="..\src\includes\adlx\ADLXHelper\WinAPIS.c">
|
|
160
|
+
<Filter>..\src\includes\adlx\ADLXHelper</Filter>
|
|
161
|
+
</ClCompile>
|
|
162
|
+
<ClCompile Include="C:\Users\oxmc\Documents\Github\nodeGPU\node_modules\node-gyp\src\win_delay_load_hook.cc">
|
|
163
|
+
<Filter>C:\Users\oxmc\Documents\Github\nodeGPU\node_modules\node-gyp\src</Filter>
|
|
164
|
+
</ClCompile>
|
|
165
|
+
<None Include="..\binding.gyp">
|
|
166
|
+
<Filter>..</Filter>
|
|
167
|
+
</None>
|
|
168
|
+
</ItemGroup>
|
|
169
|
+
</Project>
|
package/example.js
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Example usage of node-gpu
|
|
3
|
+
*
|
|
4
|
+
* This demonstrates how to retrieve GPU information from the system.
|
|
5
|
+
* Run with: node example.js
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const gpu = require('./index');
|
|
9
|
+
|
|
10
|
+
console.log('=== node-gpu Example ===\n');
|
|
11
|
+
|
|
12
|
+
try {
|
|
13
|
+
// Get GPU count
|
|
14
|
+
console.log('--- GPU Count ---');
|
|
15
|
+
const gpuCount = gpu.getGpuCount();
|
|
16
|
+
console.log('Number of GPUs:', gpuCount);
|
|
17
|
+
console.log();
|
|
18
|
+
|
|
19
|
+
if (gpuCount === 0) {
|
|
20
|
+
console.log('No GPUs detected in the system.');
|
|
21
|
+
process.exit(0);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// Get information for each GPU
|
|
25
|
+
for (let i = 0; i < gpuCount; i++) {
|
|
26
|
+
console.log(`--- GPU ${i} Information ---`);
|
|
27
|
+
const gpuInfo = gpu.getGpuInfo(i);
|
|
28
|
+
|
|
29
|
+
console.log('Index:', gpuInfo.index);
|
|
30
|
+
console.log('Vendor:', gpuInfo.vendor);
|
|
31
|
+
console.log('Name:', gpuInfo.name || 'N/A');
|
|
32
|
+
console.log('UUID:', gpuInfo.uuid || 'N/A');
|
|
33
|
+
console.log('PCI Bus ID:', gpuInfo.pciBusId || 'N/A');
|
|
34
|
+
console.log();
|
|
35
|
+
|
|
36
|
+
console.log('Memory:');
|
|
37
|
+
console.log(' Total:', gpuInfo.memoryTotal ? `${gpuInfo.memoryTotal} MB` : 'N/A');
|
|
38
|
+
console.log(' Used:', gpuInfo.memoryUsed ? `${gpuInfo.memoryUsed} MB` : 'N/A');
|
|
39
|
+
console.log(' Free:', gpuInfo.memoryFree ? `${gpuInfo.memoryFree} MB` : 'N/A');
|
|
40
|
+
console.log();
|
|
41
|
+
|
|
42
|
+
console.log('Utilization:');
|
|
43
|
+
console.log(' GPU:', gpuInfo.gpuUtilization !== undefined ? `${gpuInfo.gpuUtilization.toFixed(1)}%` : 'N/A');
|
|
44
|
+
console.log(' Memory:', gpuInfo.memoryUtilization !== undefined ? `${gpuInfo.memoryUtilization.toFixed(1)}%` : 'N/A');
|
|
45
|
+
console.log();
|
|
46
|
+
|
|
47
|
+
console.log('Temperature:', gpuInfo.temperature !== undefined ? `${gpuInfo.temperature.toFixed(1)}°C` : 'N/A');
|
|
48
|
+
console.log('Power Usage:', gpuInfo.powerUsage !== undefined ? `${gpuInfo.powerUsage.toFixed(1)} W` : 'N/A');
|
|
49
|
+
console.log();
|
|
50
|
+
|
|
51
|
+
console.log('Clocks:');
|
|
52
|
+
console.log(' Core Clock:', gpuInfo.coreClock ? `${gpuInfo.coreClock} MHz` : 'N/A');
|
|
53
|
+
console.log(' Memory Clock:', gpuInfo.memoryClock ? `${gpuInfo.memoryClock} MHz` : 'N/A');
|
|
54
|
+
console.log();
|
|
55
|
+
|
|
56
|
+
console.log('Fan Speed:', gpuInfo.fanSpeed !== undefined ? `${gpuInfo.fanSpeed.toFixed(1)}%` : 'N/A');
|
|
57
|
+
console.log();
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Get all GPU information at once
|
|
61
|
+
console.log('--- All GPU Information (Single Call) ---');
|
|
62
|
+
const allGpuInfo = gpu.getAllGpuInfo();
|
|
63
|
+
console.log(JSON.stringify(allGpuInfo, null, 2));
|
|
64
|
+
|
|
65
|
+
} catch (error) {
|
|
66
|
+
console.error('Error:', error.message);
|
|
67
|
+
console.error('\nNote: Some information may require elevated privileges (administrator/root) or specific GPU drivers.');
|
|
68
|
+
process.exit(1);
|
|
69
|
+
}
|
package/index.js
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* node-gpu - Cross-platform GPU information reader
|
|
3
|
+
*
|
|
4
|
+
* This module provides a simple interface to read GPU information
|
|
5
|
+
* from the system using native C++ code.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
try {
|
|
9
|
+
// Try to load prebuilt binary via node-pre-gyp
|
|
10
|
+
const binding_path = require('@mapbox/node-pre-gyp').find(
|
|
11
|
+
require('path').resolve(__dirname, './package.json')
|
|
12
|
+
);
|
|
13
|
+
module.exports = require(binding_path);
|
|
14
|
+
} catch (err) {
|
|
15
|
+
try {
|
|
16
|
+
// Fall back to Release build
|
|
17
|
+
module.exports = require('./build/Release/gpu.node');
|
|
18
|
+
} catch (err2) {
|
|
19
|
+
try {
|
|
20
|
+
// Fall back to Debug build
|
|
21
|
+
module.exports = require('./build/Debug/gpu.node');
|
|
22
|
+
} catch (err3) {
|
|
23
|
+
// If no build is available, throw a helpful error
|
|
24
|
+
throw new Error(
|
|
25
|
+
'Native addon not found. Please run "npm install" or "npm run build" to compile the native addon.\n' +
|
|
26
|
+
'Original error: ' + err.message
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// Add version information
|
|
33
|
+
module.exports.version = require('./package.json').version;
|
package/package.json
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "node-gpuinfo",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "A cross-platform Node.js native addon for retrieving detailed GPU information.",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"install": "node-pre-gyp install --fallback-to-build",
|
|
8
|
+
"build": "node-gyp rebuild",
|
|
9
|
+
"clean": "node-gyp clean",
|
|
10
|
+
"test": "node example.js",
|
|
11
|
+
"package": "node-pre-gyp package",
|
|
12
|
+
"publish-binary": "node-pre-gyp-github publish",
|
|
13
|
+
"prepublishOnly": "npm run build"
|
|
14
|
+
},
|
|
15
|
+
"binary": {
|
|
16
|
+
"module_name": "gpu",
|
|
17
|
+
"module_path": "./build/Release/",
|
|
18
|
+
"package_name": "{module_name}-v{version}-{node_abi}-{platform}-{arch}.tar.gz",
|
|
19
|
+
"host": "https://github.com/oxmc/node-gpu/releases/download/",
|
|
20
|
+
"remote_path": "v{version}"
|
|
21
|
+
},
|
|
22
|
+
"keywords": [
|
|
23
|
+
"gpu",
|
|
24
|
+
"nvidia",
|
|
25
|
+
"amd",
|
|
26
|
+
"intel",
|
|
27
|
+
"graphics",
|
|
28
|
+
"hardware",
|
|
29
|
+
"monitoring",
|
|
30
|
+
"performance",
|
|
31
|
+
"temperature",
|
|
32
|
+
"memory",
|
|
33
|
+
"utilization",
|
|
34
|
+
"native",
|
|
35
|
+
"addon",
|
|
36
|
+
"cross-platform",
|
|
37
|
+
"windows",
|
|
38
|
+
"linux",
|
|
39
|
+
"macos"
|
|
40
|
+
],
|
|
41
|
+
"author": "Seth Olivarez <me@oxmc.me> (https://oxmc.me)",
|
|
42
|
+
"license": "GPL-3.0-only",
|
|
43
|
+
"repository": {
|
|
44
|
+
"type": "git",
|
|
45
|
+
"url": "git+https://github.com/oxmc/node-gpu.git"
|
|
46
|
+
},
|
|
47
|
+
"bugs": {
|
|
48
|
+
"url": "https://github.com/oxmc/node-gpu/issues"
|
|
49
|
+
},
|
|
50
|
+
"homepage": "https://github.com/oxmc/node-gpu#readme",
|
|
51
|
+
"engines": {
|
|
52
|
+
"node": ">=18.0.0"
|
|
53
|
+
},
|
|
54
|
+
"gypfile": true,
|
|
55
|
+
"dependencies": {
|
|
56
|
+
"@mapbox/node-pre-gyp": "^2.0.3",
|
|
57
|
+
"node-addon-api": "^8.0.0"
|
|
58
|
+
},
|
|
59
|
+
"devDependencies": {
|
|
60
|
+
"node-gyp": "^10.0.0",
|
|
61
|
+
"node-pre-gyp-github": "^2.0.0"
|
|
62
|
+
},
|
|
63
|
+
"os": [
|
|
64
|
+
"darwin",
|
|
65
|
+
"linux",
|
|
66
|
+
"win32"
|
|
67
|
+
]
|
|
68
|
+
}
|
package/src/binding.cpp
ADDED
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
#include <napi.h>
|
|
2
|
+
extern "C" {
|
|
3
|
+
#include "gpu_info.h"
|
|
4
|
+
}
|
|
5
|
+
#include <string>
|
|
6
|
+
|
|
7
|
+
namespace gpu {
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Convert gpu_info_t struct to JavaScript object
|
|
11
|
+
*/
|
|
12
|
+
Napi::Object GpuInfoToObject(Napi::Env env, const gpu_info_t& info) {
|
|
13
|
+
Napi::Object obj = Napi::Object::New(env);
|
|
14
|
+
|
|
15
|
+
obj.Set("index", Napi::Number::New(env, info.index));
|
|
16
|
+
|
|
17
|
+
// Vendor
|
|
18
|
+
std::string vendor_str;
|
|
19
|
+
switch (info.vendor) {
|
|
20
|
+
case GPU_VENDOR_NVIDIA: vendor_str = "NVIDIA"; break;
|
|
21
|
+
case GPU_VENDOR_AMD: vendor_str = "AMD"; break;
|
|
22
|
+
case GPU_VENDOR_INTEL: vendor_str = "Intel"; break;
|
|
23
|
+
default: vendor_str = "Unknown"; break;
|
|
24
|
+
}
|
|
25
|
+
obj.Set("vendor", Napi::String::New(env, vendor_str));
|
|
26
|
+
|
|
27
|
+
obj.Set("name", Napi::String::New(env, info.name));
|
|
28
|
+
obj.Set("uuid", Napi::String::New(env, info.uuid));
|
|
29
|
+
obj.Set("pciBusId", Napi::String::New(env, info.pci_bus_id));
|
|
30
|
+
|
|
31
|
+
// Memory (in MB)
|
|
32
|
+
obj.Set("memoryTotal", Napi::Number::New(env, info.memory_total));
|
|
33
|
+
obj.Set("memoryUsed", Napi::Number::New(env, info.memory_used));
|
|
34
|
+
obj.Set("memoryFree", Napi::Number::New(env, info.memory_free));
|
|
35
|
+
|
|
36
|
+
// Utilization (percentage)
|
|
37
|
+
obj.Set("gpuUtilization", Napi::Number::New(env, info.gpu_utilization));
|
|
38
|
+
obj.Set("memoryUtilization", Napi::Number::New(env, info.memory_utilization));
|
|
39
|
+
|
|
40
|
+
// Temperature (Celsius)
|
|
41
|
+
obj.Set("temperature", Napi::Number::New(env, info.temperature));
|
|
42
|
+
|
|
43
|
+
// Power (Watts)
|
|
44
|
+
obj.Set("powerUsage", Napi::Number::New(env, info.power_usage));
|
|
45
|
+
|
|
46
|
+
// Clocks (MHz)
|
|
47
|
+
obj.Set("coreClock", Napi::Number::New(env, info.core_clock));
|
|
48
|
+
obj.Set("memoryClock", Napi::Number::New(env, info.memory_clock));
|
|
49
|
+
|
|
50
|
+
// Fan speed (percentage)
|
|
51
|
+
obj.Set("fanSpeed", Napi::Number::New(env, info.fan_speed));
|
|
52
|
+
|
|
53
|
+
return obj;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Node.js binding: initialize()
|
|
58
|
+
* Initialize the GPU information library
|
|
59
|
+
*/
|
|
60
|
+
Napi::Value Initialize(const Napi::CallbackInfo& info) {
|
|
61
|
+
Napi::Env env = info.Env();
|
|
62
|
+
|
|
63
|
+
gpu_error_t result = gpu_info_init();
|
|
64
|
+
|
|
65
|
+
if (result != GPU_SUCCESS) {
|
|
66
|
+
Napi::Error::New(env, "Failed to initialize GPU library")
|
|
67
|
+
.ThrowAsJavaScriptException();
|
|
68
|
+
return env.Null();
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return Napi::Boolean::New(env, true);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Node.js binding: cleanup()
|
|
76
|
+
* Cleanup the GPU information library
|
|
77
|
+
*/
|
|
78
|
+
Napi::Value Cleanup(const Napi::CallbackInfo& info) {
|
|
79
|
+
Napi::Env env = info.Env();
|
|
80
|
+
|
|
81
|
+
gpu_error_t result = gpu_info_cleanup();
|
|
82
|
+
|
|
83
|
+
if (result != GPU_SUCCESS) {
|
|
84
|
+
Napi::Error::New(env, "Failed to cleanup GPU library")
|
|
85
|
+
.ThrowAsJavaScriptException();
|
|
86
|
+
return env.Null();
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return Napi::Boolean::New(env, true);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Node.js binding: getGpuCount()
|
|
94
|
+
* Get the number of GPUs in the system
|
|
95
|
+
*/
|
|
96
|
+
Napi::Value GetGpuCount(const Napi::CallbackInfo& info) {
|
|
97
|
+
Napi::Env env = info.Env();
|
|
98
|
+
|
|
99
|
+
int32_t count = 0;
|
|
100
|
+
gpu_error_t result = gpu_get_count(&count);
|
|
101
|
+
|
|
102
|
+
if (result != GPU_SUCCESS) {
|
|
103
|
+
if (result == GPU_ERROR_NO_GPU) {
|
|
104
|
+
return Napi::Number::New(env, 0);
|
|
105
|
+
}
|
|
106
|
+
Napi::Error::New(env, "Failed to get GPU count")
|
|
107
|
+
.ThrowAsJavaScriptException();
|
|
108
|
+
return env.Null();
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return Napi::Number::New(env, count);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Node.js binding: getGpuInfo(index)
|
|
116
|
+
* Get information about a specific GPU by index
|
|
117
|
+
*/
|
|
118
|
+
Napi::Value GetGpuInfo(const Napi::CallbackInfo& info) {
|
|
119
|
+
Napi::Env env = info.Env();
|
|
120
|
+
|
|
121
|
+
// Check arguments
|
|
122
|
+
if (info.Length() < 1 || !info[0].IsNumber()) {
|
|
123
|
+
Napi::TypeError::New(env, "Expected GPU index as number")
|
|
124
|
+
.ThrowAsJavaScriptException();
|
|
125
|
+
return env.Null();
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
int32_t index = info[0].As<Napi::Number>().Int32Value();
|
|
129
|
+
|
|
130
|
+
gpu_info_t gpu_info;
|
|
131
|
+
gpu_error_t result = gpu_get_info(index, &gpu_info);
|
|
132
|
+
|
|
133
|
+
if (result != GPU_SUCCESS) {
|
|
134
|
+
std::string error_msg = "Failed to get GPU info for index " + std::to_string(index);
|
|
135
|
+
Napi::Error::New(env, error_msg)
|
|
136
|
+
.ThrowAsJavaScriptException();
|
|
137
|
+
return env.Null();
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
return GpuInfoToObject(env, gpu_info);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Node.js binding: getAllGpuInfo()
|
|
145
|
+
* Get information about all GPUs in the system
|
|
146
|
+
*/
|
|
147
|
+
Napi::Value GetAllGpuInfo(const Napi::CallbackInfo& info) {
|
|
148
|
+
Napi::Env env = info.Env();
|
|
149
|
+
|
|
150
|
+
// Get GPU count
|
|
151
|
+
int32_t count = 0;
|
|
152
|
+
gpu_error_t result = gpu_get_count(&count);
|
|
153
|
+
|
|
154
|
+
if (result != GPU_SUCCESS || count == 0) {
|
|
155
|
+
return Napi::Array::New(env, 0);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// Create array to hold all GPU info
|
|
159
|
+
Napi::Array gpuArray = Napi::Array::New(env, count);
|
|
160
|
+
|
|
161
|
+
// Get info for each GPU
|
|
162
|
+
for (int32_t i = 0; i < count; i++) {
|
|
163
|
+
gpu_info_t gpu_info;
|
|
164
|
+
result = gpu_get_info(i, &gpu_info);
|
|
165
|
+
|
|
166
|
+
if (result == GPU_SUCCESS) {
|
|
167
|
+
gpuArray[i] = GpuInfoToObject(env, gpu_info);
|
|
168
|
+
} else {
|
|
169
|
+
// Add null for failed GPUs
|
|
170
|
+
gpuArray[i] = env.Null();
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
return gpuArray;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Initialize the Node.js addon
|
|
179
|
+
*/
|
|
180
|
+
Napi::Object Init(Napi::Env env, Napi::Object exports) {
|
|
181
|
+
// Auto-initialize on module load
|
|
182
|
+
gpu_info_init();
|
|
183
|
+
|
|
184
|
+
// Export functions
|
|
185
|
+
exports.Set("initialize", Napi::Function::New(env, Initialize));
|
|
186
|
+
exports.Set("cleanup", Napi::Function::New(env, Cleanup));
|
|
187
|
+
exports.Set("getGpuCount", Napi::Function::New(env, GetGpuCount));
|
|
188
|
+
exports.Set("getGpuInfo", Napi::Function::New(env, GetGpuInfo));
|
|
189
|
+
exports.Set("getAllGpuInfo", Napi::Function::New(env, GetAllGpuInfo));
|
|
190
|
+
|
|
191
|
+
return exports;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
} // namespace gpu
|
|
195
|
+
|
|
196
|
+
// Register the addon (must be outside namespace)
|
|
197
|
+
Napi::Object InitModule(Napi::Env env, Napi::Object exports) {
|
|
198
|
+
return gpu::Init(env, exports);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
NODE_API_MODULE(gpu, InitModule)
|
package/src/gpu_info.c
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
#include "gpu_info.h"
|
|
2
|
+
#include <stdlib.h>
|
|
3
|
+
#include <string.h>
|
|
4
|
+
|
|
5
|
+
#ifdef _WIN32
|
|
6
|
+
#include <windows.h>
|
|
7
|
+
#else
|
|
8
|
+
#include <dlfcn.h>
|
|
9
|
+
#endif
|
|
10
|
+
|
|
11
|
+
// Forward declarations for vendor functions
|
|
12
|
+
gpu_error_t nvidia_get_gpu_count(int32_t* count);
|
|
13
|
+
gpu_error_t nvidia_get_gpu_info(int32_t index, gpu_info_t* info);
|
|
14
|
+
gpu_error_t amd_get_gpu_count(int32_t* count);
|
|
15
|
+
gpu_error_t amd_get_gpu_info(int32_t index, gpu_info_t* info);
|
|
16
|
+
gpu_error_t intel_get_gpu_count(int32_t* count);
|
|
17
|
+
gpu_error_t intel_get_gpu_info(int32_t index, gpu_info_t* info);
|
|
18
|
+
|
|
19
|
+
static bool g_initialized = false;
|
|
20
|
+
|
|
21
|
+
gpu_error_t gpu_info_init(void) {
|
|
22
|
+
if (g_initialized) {
|
|
23
|
+
return GPU_SUCCESS;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Platform-specific initialization
|
|
27
|
+
#ifdef _WIN32
|
|
28
|
+
// Windows-specific init
|
|
29
|
+
#else
|
|
30
|
+
// Linux-specific init
|
|
31
|
+
#endif
|
|
32
|
+
|
|
33
|
+
g_initialized = true;
|
|
34
|
+
return GPU_SUCCESS;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
gpu_error_t gpu_info_cleanup(void) {
|
|
38
|
+
if (!g_initialized) {
|
|
39
|
+
return GPU_SUCCESS;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Platform-specific cleanup
|
|
43
|
+
|
|
44
|
+
g_initialized = false;
|
|
45
|
+
return GPU_SUCCESS;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
gpu_error_t gpu_get_count(int32_t* count) {
|
|
49
|
+
if (!g_initialized) {
|
|
50
|
+
return GPU_ERROR_API_FAILED;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (!count) {
|
|
54
|
+
return GPU_ERROR_INVALID_PARAM;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
int32_t total_count = 0;
|
|
58
|
+
int32_t nvidia_count = 0;
|
|
59
|
+
int32_t amd_count = 0;
|
|
60
|
+
int32_t intel_count = 0;
|
|
61
|
+
|
|
62
|
+
// Get counts from all vendors
|
|
63
|
+
if (nvidia_get_gpu_count(&nvidia_count) == GPU_SUCCESS) {
|
|
64
|
+
total_count += nvidia_count;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (amd_get_gpu_count(&amd_count) == GPU_SUCCESS) {
|
|
68
|
+
total_count += amd_count;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (intel_get_gpu_count(&intel_count) == GPU_SUCCESS) {
|
|
72
|
+
total_count += intel_count;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
*count = total_count;
|
|
76
|
+
return total_count > 0 ? GPU_SUCCESS : GPU_ERROR_NO_GPU;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
gpu_error_t gpu_get_info(int32_t index, gpu_info_t* info) {
|
|
80
|
+
if (!g_initialized || !info) {
|
|
81
|
+
return GPU_ERROR_INVALID_PARAM;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
int32_t nvidia_count = 0;
|
|
85
|
+
int32_t amd_count = 0;
|
|
86
|
+
int32_t intel_count = 0;
|
|
87
|
+
|
|
88
|
+
// Get vendor counts
|
|
89
|
+
nvidia_get_gpu_count(&nvidia_count);
|
|
90
|
+
amd_get_gpu_count(&amd_count);
|
|
91
|
+
intel_get_gpu_count(&intel_count);
|
|
92
|
+
|
|
93
|
+
if (index < nvidia_count) {
|
|
94
|
+
// NVIDIA GPU
|
|
95
|
+
return nvidia_get_gpu_info(index, info);
|
|
96
|
+
} else if (index < nvidia_count + amd_count) {
|
|
97
|
+
// AMD GPU
|
|
98
|
+
int32_t amd_index = index - nvidia_count;
|
|
99
|
+
return amd_get_gpu_info(amd_index, info);
|
|
100
|
+
} else if (index < nvidia_count + amd_count + intel_count) {
|
|
101
|
+
// Intel GPU
|
|
102
|
+
int32_t intel_index = index - nvidia_count - amd_count;
|
|
103
|
+
return intel_get_gpu_info(intel_index, info);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return GPU_ERROR_INVALID_PARAM;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const char* gpu_error_string(gpu_error_t error) {
|
|
110
|
+
switch (error) {
|
|
111
|
+
case GPU_SUCCESS: return "Success";
|
|
112
|
+
case GPU_ERROR_NOT_SUPPORTED: return "Operation not supported";
|
|
113
|
+
case GPU_ERROR_NO_GPU: return "No GPU found";
|
|
114
|
+
case GPU_ERROR_ACCESS_DENIED: return "Access denied";
|
|
115
|
+
case GPU_ERROR_INVALID_PARAM: return "Invalid parameter";
|
|
116
|
+
case GPU_ERROR_API_FAILED: return "API call failed";
|
|
117
|
+
default: return "Unknown error";
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
bool gpu_vendor_supported(gpu_vendor_t vendor) {
|
|
122
|
+
switch (vendor) {
|
|
123
|
+
case GPU_VENDOR_NVIDIA:
|
|
124
|
+
case GPU_VENDOR_AMD:
|
|
125
|
+
case GPU_VENDOR_INTEL:
|
|
126
|
+
return true;
|
|
127
|
+
default:
|
|
128
|
+
return false;
|
|
129
|
+
}
|
|
130
|
+
}
|