Plugin System Documentation¶
The minitensor plugin system allows you to extend the library with custom operations, layers, and functionality while maintaining safety and version compatibility.
Overview¶
The plugin system provides:
Safe Plugin Loading: Version compatibility checking and error isolation
Custom Operations: Extend minitensor with your own tensor operations
Custom Layers: Create new neural network layers that integrate seamlessly
Python Integration: Write plugins in Python or load compiled extensions
Version Management: Automatic compatibility checking between plugins and minitensor
Core Concepts¶
Version Compatibility¶
Plugins specify minimum and maximum minitensor versions they support. The system automatically checks compatibility when loading plugins:
import minitensor.plugins as plugins
# Check current minitensor version
current_version = plugins.VersionInfo.current()
print(f"Minitensor version: {current_version}")
# Create version info
plugin_version = plugins.VersionInfo(1, 0, 0)
min_required = plugins.VersionInfo(0, 1, 0)
# Check compatibility
if current_version.is_compatible_with(min_required):
print("Compatible!")
Plugin Information¶
Every plugin must provide metadata:
import minitensor.plugins as plugins
plugin = (
plugins.PluginBuilder()
.name("my_custom_plugin")
.version(plugins.VersionInfo(1, 0, 0))
.description("A custom plugin for special operations")
.author("Your Name")
.min_minitensor_version(plugins.VersionInfo(0, 1, 0))
.build()
)
info = plugin.info
print(f"Plugin: {info.name} v{info.version}")
Creating Python Plugins¶
Basic Plugin Structure¶
import minitensor as mt
import minitensor.plugins as plugins
# Create a plugin using the builder pattern
plugin = (plugins.PluginBuilder()
.name("example_plugin")
.version(plugins.VersionInfo(1, 0, 0))
.description("An example plugin demonstrating custom operations")
.author("Plugin Developer")
.min_minitensor_version(plugins.VersionInfo(0, 1, 0))
.build())
# Define initialization function
def initialize_plugin(registry):
print("Plugin initialized!")
# Register custom operations here
pass
# Define cleanup function
def cleanup_plugin(registry):
print("Plugin cleaned up!")
# Unregister operations here
pass
# Define custom operations
def get_custom_operations():
# Return list of custom operations
return []
# Set plugin functions
plugin.set_initialize_fn(initialize_plugin)
plugin.set_cleanup_fn(cleanup_plugin)
plugin.set_custom_operations_fn(get_custom_operations)
Custom Operations in Plugins¶
import minitensor as mt
import minitensor.plugins as plugins
def create_square_operation():
"""Create a custom square operation"""
def forward(inputs):
# Forward pass: square the input
x = inputs[0]
return x * x
def backward(grad_output, input_ids, input_shapes, input_dtypes, input_devices):
# Backward pass: gradient of x^2 is 2x
gradients = {}
if input_ids:
gradients[input_ids[0]] = grad_output * 2
return gradients
def validate(inputs):
if len(inputs) != 1:
raise ValueError("square operation requires a single input")
# Create the custom operation
op = (
mt.CustomOpBuilder("square", 1)
.forward(forward)
.backward(backward)
.validate(validate)
.build()
)
return op
# Plugin with custom operation
def create_math_plugin():
plugin = (plugins.PluginBuilder()
.name("math_extensions")
.version(plugins.VersionInfo(1, 0, 0))
.description("Additional mathematical operations")
.author("Math Team")
.min_minitensor_version(plugins.VersionInfo(0, 1, 0))
.build())
def get_operations():
return [create_square_operation()]
plugin.set_custom_operations_fn(get_operations)
return plugin
Plugin Management¶
Loading and Managing Plugins¶
import minitensor.plugins as plugins
# Create plugin registry
registry = plugins.PluginRegistry()
# Register a plugin
plugin = create_math_plugin()
registry.register(plugin)
# List registered plugins
for plugin_info in registry.list_plugins():
print(f"Plugin: {plugin_info.name} v{plugin_info.version}")
print(f" Author: {plugin_info.author}")
print(f" Description: {plugin_info.description}")
# Check if plugin is registered
if registry.is_registered("math_extensions"):
print("Math extensions plugin is available")
# Get specific plugin
math_plugin = registry.get_plugin("math_extensions")
# Unregister plugin
registry.unregister("math_extensions")
Global Plugin Management¶
import minitensor.plugins as plugins
# Load plugin from shared library (requires dynamic-loading feature)
try:
plugins.load_plugin("./my_plugin.so")
print("Plugin loaded successfully")
except Exception as e:
print(f"Failed to load plugin: {e}")
# List all loaded plugins
for plugin_info in plugins.list_plugins():
print(f"Loaded: {plugin_info}")
# Get plugin information
try:
info = plugins.get_plugin_info("my_plugin")
print(f"Plugin info: {info}")
except Exception as e:
print(f"Plugin not found: {e}")
# Check if plugin is loaded
if plugins.is_plugin_loaded("my_plugin"):
print("Plugin is active")
# Unload plugin
try:
plugins.unload_plugin("my_plugin")
print("Plugin unloaded")
except Exception as e:
print(f"Failed to unload: {e}")
Dynamic Plugin Loading (C/C++/Rust)¶
For compiled plugins, you need to implement the plugin interface in your native code:
Rust Plugin Example¶
// plugin_example/src/lib.rs
use minitensor_engine::{Plugin, PluginInfo, VersionInfo, CustomOp, CustomOpRegistry, Result};
use std::sync::Arc;
pub struct ExamplePlugin {
info: PluginInfo,
}
impl ExamplePlugin {
pub fn new() -> Self {
Self {
info: PluginInfo {
name: "example_rust_plugin".to_string(),
version: VersionInfo::new(1, 0, 0),
description: "Example Rust plugin".to_string(),
author: "Rust Developer".to_string(),
min_minitensor_version: VersionInfo::new(0, 1, 0),
max_minitensor_version: None,
},
}
}
}
impl Plugin for ExamplePlugin {
fn info(&self) -> &PluginInfo {
&self.info
}
fn initialize(&self, _registry: &CustomOpRegistry) -> Result<()> {
println!("Rust plugin initialized!");
Ok(())
}
fn cleanup(&self, _registry: &CustomOpRegistry) -> Result<()> {
println!("Rust plugin cleaned up!");
Ok(())
}
fn custom_operations(&self) -> Vec<Arc<dyn CustomOp>> {
// Return your custom operations here
vec![]
}
}
// Export function for dynamic loading
#[no_mangle]
pub extern "C" fn create_plugin() -> *mut dyn Plugin {
let plugin = ExamplePlugin::new();
Box::into_raw(Box::new(plugin))
}
Building the Plugin¶
# plugin_example/Cargo.toml
[package]
name = "plugin_example"
version = "0.1.0"
edition = "2024"
[lib]
crate-type = ["cdylib"]
[dependencies]
minitensor-engine = { path = "../engine" }
Build with:
cargo build --release
Best Practices¶
Plugin Development¶
Version Compatibility: Always specify minimum and maximum supported versions
Error Handling: Provide clear error messages and handle failures gracefully
Documentation: Document your plugin’s operations and usage
Testing: Include comprehensive tests for your plugin functionality
Performance: Profile your operations and optimize for common use cases
Safety Considerations¶
Input Validation: Always validate tensor inputs in custom operations
Memory Management: Ensure proper cleanup in plugin cleanup functions
Thread Safety: Make sure your operations are thread-safe
Error Isolation: Don’t let plugin errors crash the main application
Example Plugin Structure¶
my_plugin/
├── src/
│ ├── lib.rs # Main plugin implementation
│ ├── operations.rs # Custom operations
│ └── layers.rs # Custom layers
├── tests/
│ └── integration.rs # Plugin tests
├── examples/
│ └── usage.py # Usage examples
├── Cargo.toml # Rust configuration
├── README.md # Plugin documentation
└── plugin.json # Plugin metadata
Troubleshooting¶
Common Issues¶
Version Mismatch: Ensure your plugin supports the current minitensor version
Loading Failures: Check that shared libraries are in the correct format
Missing Dependencies: Verify all required dependencies are available
Permission Errors: Ensure proper file permissions for plugin files
Debugging¶
import minitensor.plugins as plugins
# Enable debug logging
import logging
logging.basicConfig(level=logging.DEBUG)
# Try loading with error handling
try:
plugins.load_plugin("./my_plugin.so")
except Exception as e:
print(f"Error details: {e}")
# Check plugin compatibility
current = plugins.VersionInfo.current()
print(f"Current minitensor version: {current}")
API Reference¶
Classes¶
VersionInfo: Version information and compatibility checkingPluginInfo: Plugin metadata and informationCustomPlugin: Python plugin implementationPluginRegistry: Plugin registration and managementCustomLayer: Base class for custom neural network layersPluginBuilder: Builder pattern for creating plugins
Functions¶
load_plugin(path): Load plugin from shared libraryunload_plugin(name): Unload plugin by namelist_plugins(): List all loaded pluginsget_plugin_info(name): Get plugin informationis_plugin_loaded(name): Check if plugin is loaded
Features¶
dynamic-loading: Enable dynamic plugin loading from shared libraries
This plugin system provides a powerful and safe way to extend minitensor while maintaining compatibility and performance.