nodepyx 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 +22 -0
- package/README.md +399 -0
- package/binding.gyp +73 -0
- package/dist/core/PyCallable.d.ts +65 -0
- package/dist/core/PyCallable.d.ts.map +1 -0
- package/dist/core/PyCallable.js +109 -0
- package/dist/core/PyCallable.js.map +1 -0
- package/dist/core/PyContext.d.ts +76 -0
- package/dist/core/PyContext.d.ts.map +1 -0
- package/dist/core/PyContext.js +228 -0
- package/dist/core/PyContext.js.map +1 -0
- package/dist/core/PyIterator.d.ts +84 -0
- package/dist/core/PyIterator.d.ts.map +1 -0
- package/dist/core/PyIterator.js +243 -0
- package/dist/core/PyIterator.js.map +1 -0
- package/dist/core/PyModule.d.ts +55 -0
- package/dist/core/PyModule.d.ts.map +1 -0
- package/dist/core/PyModule.js +172 -0
- package/dist/core/PyModule.js.map +1 -0
- package/dist/core/PyProxy.d.ts +65 -0
- package/dist/core/PyProxy.d.ts.map +1 -0
- package/dist/core/PyProxy.js +483 -0
- package/dist/core/PyProxy.js.map +1 -0
- package/dist/core/PyRuntime.d.ts +105 -0
- package/dist/core/PyRuntime.d.ts.map +1 -0
- package/dist/core/PyRuntime.js +438 -0
- package/dist/core/PyRuntime.js.map +1 -0
- package/dist/env/CondaManager.d.ts +118 -0
- package/dist/env/CondaManager.d.ts.map +1 -0
- package/dist/env/CondaManager.js +401 -0
- package/dist/env/CondaManager.js.map +1 -0
- package/dist/env/PackageInstaller.d.ts +233 -0
- package/dist/env/PackageInstaller.d.ts.map +1 -0
- package/dist/env/PackageInstaller.js +609 -0
- package/dist/env/PackageInstaller.js.map +1 -0
- package/dist/env/PythonDetector.d.ts +103 -0
- package/dist/env/PythonDetector.d.ts.map +1 -0
- package/dist/env/PythonDetector.js +381 -0
- package/dist/env/PythonDetector.js.map +1 -0
- package/dist/env/VenvManager.d.ts +117 -0
- package/dist/env/VenvManager.d.ts.map +1 -0
- package/dist/env/VenvManager.js +331 -0
- package/dist/env/VenvManager.js.map +1 -0
- package/dist/index.d.ts +169 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +393 -0
- package/dist/index.js.map +1 -0
- package/dist/plugins/Plugin.interface.d.ts +41 -0
- package/dist/plugins/Plugin.interface.d.ts.map +1 -0
- package/dist/plugins/Plugin.interface.js +12 -0
- package/dist/plugins/Plugin.interface.js.map +1 -0
- package/dist/plugins/PluginManager.d.ts +26 -0
- package/dist/plugins/PluginManager.d.ts.map +1 -0
- package/dist/plugins/PluginManager.js +174 -0
- package/dist/plugins/PluginManager.js.map +1 -0
- package/dist/plugins/builtin/NumpyPlugin.d.ts +17 -0
- package/dist/plugins/builtin/NumpyPlugin.d.ts.map +1 -0
- package/dist/plugins/builtin/NumpyPlugin.js +41 -0
- package/dist/plugins/builtin/NumpyPlugin.js.map +1 -0
- package/dist/plugins/builtin/PandasPlugin.d.ts +19 -0
- package/dist/plugins/builtin/PandasPlugin.d.ts.map +1 -0
- package/dist/plugins/builtin/PandasPlugin.js +57 -0
- package/dist/plugins/builtin/PandasPlugin.js.map +1 -0
- package/dist/plugins/builtin/TorchPlugin.d.ts +23 -0
- package/dist/plugins/builtin/TorchPlugin.d.ts.map +1 -0
- package/dist/plugins/builtin/TorchPlugin.js +50 -0
- package/dist/plugins/builtin/TorchPlugin.js.map +1 -0
- package/dist/plugins/index.d.ts +7 -0
- package/dist/plugins/index.d.ts.map +1 -0
- package/dist/plugins/index.js +12 -0
- package/dist/plugins/index.js.map +1 -0
- package/dist/serialization/DataFrameBridge.d.ts +141 -0
- package/dist/serialization/DataFrameBridge.d.ts.map +1 -0
- package/dist/serialization/DataFrameBridge.js +355 -0
- package/dist/serialization/DataFrameBridge.js.map +1 -0
- package/dist/serialization/MsgPackSerializer.d.ts +45 -0
- package/dist/serialization/MsgPackSerializer.d.ts.map +1 -0
- package/dist/serialization/MsgPackSerializer.js +242 -0
- package/dist/serialization/MsgPackSerializer.js.map +1 -0
- package/dist/serialization/NumpyBridge.d.ts +96 -0
- package/dist/serialization/NumpyBridge.d.ts.map +1 -0
- package/dist/serialization/NumpyBridge.js +323 -0
- package/dist/serialization/NumpyBridge.js.map +1 -0
- package/dist/serialization/Serializer.d.ts +78 -0
- package/dist/serialization/Serializer.d.ts.map +1 -0
- package/dist/serialization/Serializer.js +281 -0
- package/dist/serialization/Serializer.js.map +1 -0
- package/dist/types/PythonTypeMapper.d.ts +87 -0
- package/dist/types/PythonTypeMapper.d.ts.map +1 -0
- package/dist/types/PythonTypeMapper.js +449 -0
- package/dist/types/PythonTypeMapper.js.map +1 -0
- package/dist/types/StubCache.d.ts +109 -0
- package/dist/types/StubCache.d.ts.map +1 -0
- package/dist/types/StubCache.js +333 -0
- package/dist/types/StubCache.js.map +1 -0
- package/dist/types/TypeGenerator.d.ts +139 -0
- package/dist/types/TypeGenerator.d.ts.map +1 -0
- package/dist/types/TypeGenerator.js +372 -0
- package/dist/types/TypeGenerator.js.map +1 -0
- package/dist/types/addon.d.ts +114 -0
- package/dist/types/addon.d.ts.map +1 -0
- package/dist/types/addon.js +32 -0
- package/dist/types/addon.js.map +1 -0
- package/dist/types/config.d.ts +175 -0
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/config.js +35 -0
- package/dist/types/config.js.map +1 -0
- package/dist/types/index.d.ts +10 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +12 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/python.d.ts +235 -0
- package/dist/types/python.d.ts.map +1 -0
- package/dist/types/python.js +7 -0
- package/dist/types/python.js.map +1 -0
- package/dist/utils/ErrorTranslator.d.ts +83 -0
- package/dist/utils/ErrorTranslator.d.ts.map +1 -0
- package/dist/utils/ErrorTranslator.js +210 -0
- package/dist/utils/ErrorTranslator.js.map +1 -0
- package/dist/utils/Logger.d.ts +27 -0
- package/dist/utils/Logger.d.ts.map +1 -0
- package/dist/utils/Logger.js +115 -0
- package/dist/utils/Logger.js.map +1 -0
- package/dist/utils/MemoryMonitor.d.ts +44 -0
- package/dist/utils/MemoryMonitor.d.ts.map +1 -0
- package/dist/utils/MemoryMonitor.js +143 -0
- package/dist/utils/MemoryMonitor.js.map +1 -0
- package/package.json +177 -0
- package/python/error_handler.py +433 -0
- package/python/nodepyx_runtime.py +575 -0
- package/python/serializer.py +379 -0
- package/python/type_inspector.py +288 -0
- package/scripts/build-native.js +68 -0
- package/scripts/download-prebuilds.js +99 -0
- package/scripts/generate-stubs.js +405 -0
- package/scripts/install.js +260 -0
- package/src/core/PyCallable.ts +137 -0
- package/src/core/PyContext.ts +296 -0
- package/src/core/PyIterator.ts +294 -0
- package/src/core/PyModule.ts +194 -0
- package/src/core/PyProxy.ts +605 -0
- package/src/core/PyRuntime.ts +504 -0
- package/src/env/CondaManager.ts +451 -0
- package/src/env/PackageInstaller.ts +738 -0
- package/src/env/PythonDetector.ts +414 -0
- package/src/env/VenvManager.ts +396 -0
- package/src/index.ts +425 -0
- package/src/native/gil_guard.cpp +26 -0
- package/src/native/gil_guard.h +175 -0
- package/src/native/nodepyx_addon.cpp +886 -0
- package/src/native/python_bridge.cpp +790 -0
- package/src/native/python_bridge.h +257 -0
- package/src/native/thread_pool.cpp +336 -0
- package/src/native/thread_pool.h +175 -0
- package/src/native/type_converter.cpp +901 -0
- package/src/native/type_converter.h +272 -0
- package/src/nextjs/PyProvider.tsx +123 -0
- package/src/nextjs/index.ts +21 -0
- package/src/nextjs/usePython.ts +106 -0
- package/src/nextjs/withnodepyx.ts +88 -0
- package/src/plugins/Plugin.interface.ts +51 -0
- package/src/plugins/PluginManager.ts +155 -0
- package/src/plugins/builtin/NumpyPlugin.ts +36 -0
- package/src/plugins/builtin/PandasPlugin.ts +49 -0
- package/src/plugins/builtin/TorchPlugin.ts +56 -0
- package/src/plugins/index.ts +7 -0
- package/src/serialization/DataFrameBridge.ts +398 -0
- package/src/serialization/MsgPackSerializer.ts +220 -0
- package/src/serialization/NumpyBridge.ts +332 -0
- package/src/serialization/Serializer.ts +320 -0
- package/src/types/PythonTypeMapper.ts +495 -0
- package/src/types/StubCache.ts +340 -0
- package/src/types/TypeGenerator.ts +491 -0
- package/src/types/addon.ts +170 -0
- package/src/types/config.ts +226 -0
- package/src/types/index.ts +55 -0
- package/src/types/python.ts +309 -0
- package/src/types/stubs/numpy.d.ts +441 -0
- package/src/types/stubs/pandas.d.ts +575 -0
- package/src/types/stubs/sklearn.d.ts +728 -0
- package/src/types/stubs/torch.d.ts +694 -0
- package/src/utils/ErrorTranslator.ts +220 -0
- package/src/utils/Logger.ts +119 -0
- package/src/utils/MemoryMonitor.ts +175 -0
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* nodepyx — PluginManager
|
|
3
|
+
*
|
|
4
|
+
* Manages registration, lifecycle, and dispatch of nodepyx plugins.
|
|
5
|
+
* PyRuntime holds a single PluginManager instance.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { Logger } from '../utils/Logger';
|
|
9
|
+
import type {
|
|
10
|
+
nodepyxPlugin,
|
|
11
|
+
PluginRegistration,
|
|
12
|
+
PluginInitContext,
|
|
13
|
+
TypeTransformHandler,
|
|
14
|
+
PythonTypeName,
|
|
15
|
+
} from './Plugin.interface';
|
|
16
|
+
import type { SerializedValue } from '../types/python';
|
|
17
|
+
|
|
18
|
+
const logger = new Logger('PluginManager');
|
|
19
|
+
|
|
20
|
+
export class PluginManager {
|
|
21
|
+
private readonly _plugins = new Map<string, PluginRegistration>();
|
|
22
|
+
private readonly _typeMap = new Map<PythonTypeName, TypeTransformHandler[]>();
|
|
23
|
+
private readonly _moduleMap = new Map<string, nodepyxPlugin[]>();
|
|
24
|
+
|
|
25
|
+
// ── Registration ────────────────────────────────────────────────────────────
|
|
26
|
+
|
|
27
|
+
register(plugin: nodepyxPlugin): this {
|
|
28
|
+
if (this._plugins.has(plugin.name)) {
|
|
29
|
+
logger.debug(`Plugin already registered: ${plugin.name} — skipping`);
|
|
30
|
+
return this;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const entry: PluginRegistration = {
|
|
34
|
+
plugin,
|
|
35
|
+
active: false,
|
|
36
|
+
loadedAt: Date.now(),
|
|
37
|
+
modulesBound: new Set(),
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
this._plugins.set(plugin.name, entry);
|
|
41
|
+
|
|
42
|
+
for (const typeName of plugin.handledTypes ?? []) {
|
|
43
|
+
const handlers = this._typeMap.get(typeName) ?? [];
|
|
44
|
+
if (plugin.transformResult) {handlers.push(plugin.transformResult.bind(plugin));}
|
|
45
|
+
this._typeMap.set(typeName, handlers);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
for (const mod of plugin.supportedModules) {
|
|
49
|
+
const list = this._moduleMap.get(mod) ?? [];
|
|
50
|
+
list.push(plugin);
|
|
51
|
+
this._moduleMap.set(mod, list);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
logger.debug(`Registered plugin: ${plugin.name} v${plugin.version}`);
|
|
55
|
+
return this;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
async registerBuiltins(): Promise<void> {
|
|
59
|
+
const [{ PandasPlugin }, { NumpyPlugin }, { TorchPlugin }] = await Promise.all([
|
|
60
|
+
import('./builtin/PandasPlugin'),
|
|
61
|
+
import('./builtin/NumpyPlugin'),
|
|
62
|
+
import('./builtin/TorchPlugin'),
|
|
63
|
+
]);
|
|
64
|
+
this.register(new PandasPlugin());
|
|
65
|
+
this.register(new NumpyPlugin());
|
|
66
|
+
this.register(new TorchPlugin());
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// ── Lifecycle ────────────────────────────────────────────────────────────────
|
|
70
|
+
|
|
71
|
+
async initAll(ctx: PluginInitContext): Promise<void> {
|
|
72
|
+
const extCtx: PluginInitContext = {
|
|
73
|
+
...ctx,
|
|
74
|
+
registerTypeHandler: (typeName, handler) => {
|
|
75
|
+
const handlers = this._typeMap.get(typeName) ?? [];
|
|
76
|
+
handlers.push(handler);
|
|
77
|
+
this._typeMap.set(typeName, handlers);
|
|
78
|
+
},
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
for (const [name, entry] of this._plugins) {
|
|
82
|
+
try {
|
|
83
|
+
await entry.plugin.onInit?.(extCtx);
|
|
84
|
+
entry.active = true;
|
|
85
|
+
logger.debug(`Initialised plugin: ${name}`);
|
|
86
|
+
} catch (err) {
|
|
87
|
+
logger.warn(`Plugin ${name} init failed (non-fatal): ${err}`);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
async shutdownAll(): Promise<void> {
|
|
93
|
+
for (const [name, entry] of this._plugins) {
|
|
94
|
+
if (!entry.active) {continue;}
|
|
95
|
+
try {
|
|
96
|
+
await entry.plugin.onShutdown?.();
|
|
97
|
+
entry.active = false;
|
|
98
|
+
} catch (err) {
|
|
99
|
+
logger.warn(`Plugin ${name} shutdown error (non-fatal): ${err}`);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
async onModuleImported(moduleName: string, moduleOid: number): Promise<void> {
|
|
105
|
+
const plugins = this._moduleMap.get(moduleName) ?? [];
|
|
106
|
+
for (const plugin of plugins) {
|
|
107
|
+
try {
|
|
108
|
+
await plugin.onModuleImported?.(moduleName, moduleOid);
|
|
109
|
+
} catch (err) {
|
|
110
|
+
logger.warn(`Plugin ${plugin.name} onModuleImported error: ${err}`);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// ── Transform chain ──────────────────────────────────────────────────────────
|
|
116
|
+
|
|
117
|
+
transformResult(
|
|
118
|
+
value: SerializedValue,
|
|
119
|
+
typeName: string,
|
|
120
|
+
metadata: Record<string, unknown> = {}
|
|
121
|
+
): unknown | null {
|
|
122
|
+
const handlers = this._typeMap.get(typeName) ?? [];
|
|
123
|
+
for (const handler of handlers) {
|
|
124
|
+
try {
|
|
125
|
+
const result = handler(value, typeName, metadata);
|
|
126
|
+
if (result !== null) {return result;}
|
|
127
|
+
} catch (err) {
|
|
128
|
+
logger.warn(`Type transform error for ${typeName}: ${err}`);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
return null;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
serializeValue(value: unknown, targetTypeName?: string): SerializedValue | null {
|
|
135
|
+
for (const [, entry] of this._plugins) {
|
|
136
|
+
if (!entry.active || !entry.plugin.serializeValue) {continue;}
|
|
137
|
+
try {
|
|
138
|
+
const result = entry.plugin.serializeValue(value, targetTypeName);
|
|
139
|
+
if (result !== null) {return result;}
|
|
140
|
+
} catch (err) {
|
|
141
|
+
logger.warn(`Plugin serialize error: ${err}`);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
return null;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// ── Introspection ────────────────────────────────────────────────────────────
|
|
148
|
+
|
|
149
|
+
get names(): string[] { return [...this._plugins.keys()]; }
|
|
150
|
+
getPlugin(name: string): PluginRegistration | undefined { return this._plugins.get(name); }
|
|
151
|
+
get active(): PluginRegistration[] { return [...this._plugins.values()].filter((e) => e.active); }
|
|
152
|
+
get all(): PluginRegistration[] { return [...this._plugins.values()]; }
|
|
153
|
+
isActive(name: string): boolean { return this._plugins.get(name)?.active === true; }
|
|
154
|
+
}
|
|
155
|
+
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* nodepyx — NumpyPlugin (built-in)
|
|
3
|
+
* Routes ndarray wire objects through NumpyBridge.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { nodepyxPlugin, PluginInitContext } from '../Plugin.interface';
|
|
7
|
+
import type { SerializedValue, NumPyArrayResult } from '../../types/python';
|
|
8
|
+
import { NumpyBridge } from '../../serialization/NumpyBridge';
|
|
9
|
+
import { Logger } from '../../utils/Logger';
|
|
10
|
+
|
|
11
|
+
const logger = new Logger('NumpyPlugin');
|
|
12
|
+
const bridge = new NumpyBridge();
|
|
13
|
+
|
|
14
|
+
export class NumpyPlugin implements nodepyxPlugin {
|
|
15
|
+
readonly name = 'numpy';
|
|
16
|
+
readonly version = '1.0.0';
|
|
17
|
+
readonly description = 'Enhanced NumPy ndarray → TypedArray mapping';
|
|
18
|
+
readonly supportedModules = ['numpy', 'np'] as const;
|
|
19
|
+
readonly handledTypes = ['ndarray', 'matrix', 'MaskedArray'] as const;
|
|
20
|
+
|
|
21
|
+
onInit(ctx: PluginInitContext): void {
|
|
22
|
+
for (const t of this.handledTypes) {ctx.registerTypeHandler(t, this._handle.bind(this));}
|
|
23
|
+
logger.debug('NumpyPlugin initialised');
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
transformResult(raw: SerializedValue, typeHint: string): NumPyArrayResult | null {
|
|
27
|
+
if ((this.handledTypes as readonly string[]).includes(typeHint)) {return this._handle(raw, typeHint, {});}
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
private _handle(raw: SerializedValue, _type?: string, _meta?: Record<string, unknown>): NumPyArrayResult | null {
|
|
32
|
+
try { return bridge.deserialize(raw); }
|
|
33
|
+
catch (err) { logger.warn(`ndarray deserialization error: ${err}`); return null; }
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* nodepyx — PandasPlugin (built-in)
|
|
3
|
+
* Intercepts DataFrame/Series wire objects and routes through DataFrameBridge.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { nodepyxPlugin, PluginInitContext } from '../Plugin.interface';
|
|
7
|
+
import type { SerializedValue, DataFrameResult, SeriesResult } from '../../types/python';
|
|
8
|
+
import { DataFrameBridge } from '../../serialization/DataFrameBridge';
|
|
9
|
+
import { Logger } from '../../utils/Logger';
|
|
10
|
+
|
|
11
|
+
const logger = new Logger('PandasPlugin');
|
|
12
|
+
const bridge = new DataFrameBridge();
|
|
13
|
+
|
|
14
|
+
export class PandasPlugin implements nodepyxPlugin {
|
|
15
|
+
readonly name = 'pandas';
|
|
16
|
+
readonly version = '1.0.0';
|
|
17
|
+
readonly description = 'Enhanced pandas DataFrame and Series support';
|
|
18
|
+
readonly supportedModules = ['pandas', 'pd'] as const;
|
|
19
|
+
readonly handledTypes = ['DataFrame', 'Series', 'DataFrameGroupBy', 'SeriesGroupBy'] as const;
|
|
20
|
+
|
|
21
|
+
onInit(ctx: PluginInitContext): void {
|
|
22
|
+
ctx.registerTypeHandler('DataFrame', this._handleDF.bind(this));
|
|
23
|
+
ctx.registerTypeHandler('DataFrameGroupBy', this._handleDF.bind(this));
|
|
24
|
+
ctx.registerTypeHandler('Series', this._handleSeries.bind(this));
|
|
25
|
+
ctx.registerTypeHandler('SeriesGroupBy', this._handleSeries.bind(this));
|
|
26
|
+
logger.debug('PandasPlugin initialised');
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
onModuleImported(moduleName: string): void {
|
|
30
|
+
logger.debug(`pandas module imported: ${moduleName}`);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
transformResult(raw: SerializedValue, typeHint: string): DataFrameResult | SeriesResult | null {
|
|
34
|
+
if (typeHint === 'DataFrame' || typeHint === 'DataFrameGroupBy') {return this._handleDF(raw, typeHint, {});}
|
|
35
|
+
if (typeHint === 'Series' || typeHint === 'SeriesGroupBy') {return this._handleSeries(raw, typeHint, {});}
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
private _handleDF(raw: SerializedValue, _typeHint?: string, _meta?: Record<string, unknown>): DataFrameResult | null {
|
|
40
|
+
try { return bridge.deserializeDataFrame(raw); }
|
|
41
|
+
catch (err) { logger.warn(`DataFrame deserialization error: ${err}`); return null; }
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
private _handleSeries(raw: SerializedValue, _typeHint?: string, _meta?: Record<string, unknown>): SeriesResult | null {
|
|
45
|
+
try { return bridge.deserializeSeries(raw); }
|
|
46
|
+
catch (err) { logger.warn(`Series deserialization error: ${err}`); return null; }
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* nodepyx — TorchPlugin (built-in)
|
|
3
|
+
* Handles PyTorch Tensor objects — delegates to NumpyBridge (tensors are NumPy-compatible).
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { nodepyxPlugin, PluginInitContext } from '../Plugin.interface';
|
|
7
|
+
import type { SerializedValue, NumPyArrayResult } from '../../types/python';
|
|
8
|
+
import { NumpyBridge } from '../../serialization/NumpyBridge';
|
|
9
|
+
import { Logger } from '../../utils/Logger';
|
|
10
|
+
|
|
11
|
+
const logger = new Logger('TorchPlugin');
|
|
12
|
+
const bridge = new NumpyBridge();
|
|
13
|
+
|
|
14
|
+
export type TensorResult = NumPyArrayResult & {
|
|
15
|
+
requiresGrad: boolean;
|
|
16
|
+
isCuda: boolean;
|
|
17
|
+
device: string;
|
|
18
|
+
gradFn: string | null;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export class TorchPlugin implements nodepyxPlugin {
|
|
22
|
+
readonly name = 'torch';
|
|
23
|
+
readonly version = '1.0.0';
|
|
24
|
+
readonly description = 'Enhanced PyTorch Tensor support';
|
|
25
|
+
readonly supportedModules = ['torch'] as const;
|
|
26
|
+
readonly handledTypes = ['Tensor'] as const;
|
|
27
|
+
|
|
28
|
+
onInit(ctx: PluginInitContext): void {
|
|
29
|
+
ctx.registerTypeHandler('Tensor', this._handle.bind(this));
|
|
30
|
+
logger.debug('TorchPlugin initialised');
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
transformResult(raw: SerializedValue, typeHint: string, meta: Record<string, unknown>): TensorResult | null {
|
|
34
|
+
return typeHint === 'Tensor' ? this._handle(raw, typeHint, meta) : null;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
private _handle(raw: SerializedValue, _t?: string, meta?: Record<string, unknown>): TensorResult | null {
|
|
38
|
+
try {
|
|
39
|
+
const base = bridge.deserialize(raw);
|
|
40
|
+
if (!base) {return null;}
|
|
41
|
+
const isCuda = Boolean(meta?.['isCuda']);
|
|
42
|
+
if (isCuda) {logger.warn('CUDA Tensor: data was copied to CPU for transfer.');}
|
|
43
|
+
return {
|
|
44
|
+
...base,
|
|
45
|
+
requiresGrad: Boolean(meta?.['requiresGrad']),
|
|
46
|
+
isCuda,
|
|
47
|
+
device: String(meta?.['device'] ?? 'cpu'),
|
|
48
|
+
gradFn: meta?.['gradFn'] !== null && meta?.['gradFn'] !== undefined ? String(meta?.['gradFn']) : null,
|
|
49
|
+
} as TensorResult;
|
|
50
|
+
} catch (err) {
|
|
51
|
+
logger.warn(`Tensor deserialization error: ${err}`);
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export type { nodepyxPlugin, PluginRegistration, PluginInitContext, TypeTransformHandler, PythonTypeName } from './Plugin.interface';
|
|
2
|
+
export { PluginManager } from './PluginManager';
|
|
3
|
+
export { PandasPlugin } from './builtin/PandasPlugin';
|
|
4
|
+
export { NumpyPlugin } from './builtin/NumpyPlugin';
|
|
5
|
+
export { TorchPlugin } from './builtin/TorchPlugin';
|
|
6
|
+
export type { TensorResult } from './builtin/TorchPlugin';
|
|
7
|
+
|