Professional and Enterprise Tiers Only
Bravura provides comprehensive GPU detection and acceleration capabilities for Professional and Enterprise tier customers. This guide shows you how to implement GPU acceleration in your applications.
---
from bravura.components import GPUDetector
# Create detector
detector = GPUDetector()
# Detect GPU
gpu_info = detector.detect_gpu()
if gpu_info['available']:
print(f"GPU Found: {gpu_info['name']}")
print(f"Vendor: {gpu_info['vendor']}")
print(f"Memory: {gpu_info.get('memory', 'Unknown')} MB")
else:
print(f"No GPU detected: {gpu_info.get('reason')}")
from bravura.components import check_gpu_capabilities
# Get capabilities
caps = check_gpu_capabilities()
print(f"CUDA Available: {caps['cuda_available']}")
print(f"OpenCL Available: {caps['opencl_available']}")
print(f"Metal Available: {caps['metal_available']}")
print(f"DirectX Available: {caps['directx_available']}")
print(f"Compute Capable: {caps['compute_capable']}")
---
The GPUDetector class provides the primary interface for GPU detection:
from bravura.components import GPUDetector
detector = GPUDetector()
# Detect GPU (cached result)
gpu_info = detector.detect_gpu()
# Force refresh
gpu_info = detector.detect_gpu(force_refresh=True)
# Get capabilities
capabilities = detector.get_capabilities()
# Check specific capabilities
if detector.is_cuda_available():
print("CUDA acceleration available!")
if detector.is_compute_capable():
print("GPU can be used for computation!")
# Get GPU name for display
gpu_name = detector.get_gpu_name() # Returns "CPU Mode" if no GPU
from bravura.components import detect_gpus, check_gpu_capabilities
# Detect all GPUs
result = detect_gpus()
if result['detected']:
print(f"Found {len(result['detected'])} GPU(s)")
print(f"Primary GPU: {result['primary']['name']}")
print(f"Detection method: {result['method']}")
# Check capabilities
caps = check_gpu_capabilities(result['primary'])
else:
print(f"Detection failed: {result.get('error')}")
---
from bravura import ToolkitApp
from bravura.components import GPUDetector
import numpy as np
class GPUAcceleratedApp(ToolkitApp):
def __init__(self):
super().__init__()
self.gpu_detector = GPUDetector()
def on_start(self, inputs):
"""Process data with GPU if available."""
# Detect GPU
gpu_info = self.gpu_detector.detect_gpu()
use_gpu = gpu_info.get('available', False)
if use_gpu:
self.log_info(f"Using GPU: {gpu_info['name']}")
results = self._process_with_gpu(inputs)
else:
self.log_info("Using CPU processing")
results = self._process_with_cpu(inputs)
return results
def _process_with_gpu(self, inputs):
"""GPU-accelerated processing."""
# Check for GPU libraries
try:
import cupy as cp # GPU-accelerated NumPy
self.log_info("Using CuPy for GPU acceleration")
# Convert data to GPU arrays
data = cp.array(inputs['data'])
# Perform GPU computation
result = cp.fft.fft(data)
result = cp.abs(result)
# Convert back to CPU
return {'result': cp.asnumpy(result)}
except ImportError:
self.log_warning("CuPy not installed, falling back to CPU")
return self._process_with_cpu(inputs)
def _process_with_cpu(self, inputs):
"""CPU fallback processing."""
data = np.array(inputs['data'])
result = np.fft.fft(data)
result = np.abs(result)
return {'result': result}
---
For NVIDIA GPUs:
pip install cupy-cuda12x # For CUDA 12.x
# or
pip install cupy-cuda11x # For CUDA 11.x
import cupy as cp
# Check CUDA availability
cuda_available = cp.is_available()
if cuda_available:
# Use CuPy like NumPy
arr = cp.array([1, 2, 3, 4, 5])
result = cp.sum(arr)
# GPU memory info
mempool = cp.get_default_memory_pool()
print(f"Used GPU memory: {mempool.used_bytes() / 1024**2} MB")
Cross-platform GPU support:
pip install torch torchvision torchaudio
import torch
# Check GPU availability
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
# Use GPU tensors
tensor = torch.randn(1000, 1000).to(device)
result = torch.matmul(tensor, tensor)
print(f"Processing on: {device}")
Machine learning with GPU:
pip install tensorflow
import tensorflow as tf
# Check GPU availability
gpus = tf.config.list_physical_devices('GPU')
if gpus:
print(f"Found {len(gpus)} GPU(s)")
# Use GPU acceleration
with tf.device('/GPU:0'):
a = tf.constant([[1.0, 2.0], [3.0, 4.0]])
b = tf.constant([[5.0, 6.0], [7.0, 8.0]])
c = tf.matmul(a, b)
Works with NVIDIA, AMD, Intel:
pip install pyopencl
import pyopencl as cl
# Get available platforms
platforms = cl.get_platforms()
for platform in platforms:
devices = platform.get_devices()
for device in devices:
print(f"Device: {device.name}")
print(f"Type: {cl.device_type.to_string(device.type)}")
---
def process_data(data, use_gpu=True):
"""Always have a CPU fallback."""
if use_gpu:
try:
return gpu_process(data)
except Exception as e:
logger.warning(f"GPU processing failed: {e}")
return cpu_process(data)
else:
return cpu_process(data)
# Good: Process in batches
batch_size = 1000
for i in range(0, len(data), batch_size):
batch = data[i:i+batch_size]
result = gpu_process_batch(batch)
# Bad: Process item-by-item
for item in data: # Too slow, overhead dominates
result = gpu_process_single(item)
import cupy as cp
# Good: Clear GPU memory when done
def process_with_cleanup():
data = cp.array(large_dataset)
result = cp.fft.fft(data)
# Clear memory
del data
cp.get_default_memory_pool().free_all_blocks()
return cp.asnumpy(result)
class GPUProcessor(ToolkitApp):
def process_large_dataset(self, data):
"""Process with progress updates."""
batch_size = 1000
total_batches = len(data) // batch_size
results = []
for i, batch_start in enumerate(range(0, len(data), batch_size)):
# Process batch
batch = data[batch_start:batch_start+batch_size]
result = self._gpu_process_batch(batch)
results.append(result)
# Update progress
progress = ((i + 1) / total_batches) * 100
self.update_progress(
progress,
f"Processing batch {i+1}/{total_batches} on GPU"
)
return results
---
# macOS Apple Silicon example
import torch
if torch.backends.mps.is_available():
device = torch.device("mps")
print("Using Apple Silicon GPU")
else:
device = torch.device("cpu")
---
import time
import numpy as np
def benchmark_processing(size=10000):
"""Compare CPU vs GPU performance."""
data = np.random.randn(size)
# CPU benchmark
start = time.time()
cpu_result = np.fft.fft(data)
cpu_time = time.time() - start
# GPU benchmark (if available)
try:
import cupy as cp
gpu_data = cp.array(data)
start = time.time()
gpu_result = cp.fft.fft(gpu_data)
cp.cuda.Stream.null.synchronize() # Wait for GPU
gpu_time = time.time() - start
speedup = cpu_time / gpu_time
print(f"CPU time: {cpu_time:.4f}s")
print(f"GPU time: {gpu_time:.4f}s")
print(f"Speedup: {speedup:.2f}x")
except ImportError:
print("CuPy not available, skipping GPU benchmark")
---
- NVIDIA: Install CUDA Toolkit and drivers
- AMD: Install ROCm drivers
- Intel: Install compute runtime
```python
from bravura.components import detect_gpus
result = detect_gpus()
print(f"Detection method: {result.get('method')}")
print(f"Error (if any): {result.get('error')}")
```
```python
# Check CuPy
try:
import cupy
print(f"CuPy version: {cupy.__version__}")
except ImportError:
print("CuPy not installed")
```
# Reduce batch size
batch_size = 500 # Instead of 1000
# Or process in chunks
for chunk in chunks(data, chunk_size=1000):
result = process(chunk)
# Clear memory between chunks
cp.get_default_memory_pool().free_all_blocks()
# Bad: Too much transfer
for item in data:
gpu_item = cp.array(item) # Transfer
result = process(gpu_item)
cpu_result = cp.asnumpy(result) # Transfer back
# Good: Batch transfer
gpu_data = cp.array(data) # One transfer
gpu_results = batch_process(gpu_data)
cpu_results = cp.asnumpy(gpu_results) # One transfer back
---
API_REFERENCE.mdBEST_PRACTICES.md---
#!/usr/bin/env python3
"""
GPU-Accelerated Data Processor
Professional Edition Example
"""
from bravura import Toolkit, ToolkitApp
from bravura.components import GPUDetector
import numpy as np
class GPUDataProcessor(ToolkitApp):
def __init__(self):
super().__init__()
self.detector = GPUDetector()
def on_start(self, inputs):
"""Process data with GPU acceleration."""
# Detect GPU
gpu_info = self.detector.detect_gpu()
self.log_info(f"GPU: {gpu_info.get('name', 'Not detected')}")
# Generate sample data
data_size = inputs.get('data_size', 100000)
self.update_progress(10, "Generating dataset...")
data = np.random.randn(data_size)
# Process
if gpu_info.get('available'):
results = self._process_gpu(data)
else:
results = self._process_cpu(data)
self.update_progress(100, "Complete!")
return results
def _process_gpu(self, data):
"""GPU processing path."""
try:
import cupy as cp
self.update_progress(30, "Transferring to GPU...")
gpu_data = cp.array(data)
self.update_progress(50, "Processing on GPU...")
result = cp.fft.fft(gpu_data)
result = cp.abs(result)
self.update_progress(80, "Transferring from GPU...")
cpu_result = cp.asnumpy(result)
return {'result': cpu_result, 'mode': 'GPU'}
except Exception as e:
self.log_error(f"GPU failed: {e}")
return self._process_cpu(data)
def _process_cpu(self, data):
"""CPU fallback."""
self.update_progress(50, "Processing on CPU...")
result = np.fft.fft(data)
result = np.abs(result)
return {'result': result, 'mode': 'CPU'}
# Run application
if __name__ == "__main__":
toolkit = Toolkit(app_name="GPU Processor", use_gpu=True)
root = toolkit.create_main_window(title="GPU Data Processor")
processor = GPUDataProcessor()
# Run your processing logic here
toolkit.run()
---
Bravura - Professional GUI Framework
Version 1.0.0 | Copyright © 2025 Wigley Studios LLC
GPU Detection and Acceleration requires Professional or Enterprise tier license.