Add GPU image primitives (gpu-make-image, gpu-gradient)
Some checks are pending
GPU Worker CI/CD / test (push) Waiting to run
GPU Worker CI/CD / deploy (push) Blocked by required conditions

This commit is contained in:
giles
2026-02-04 10:05:09 +00:00
parent 76bf19b8ab
commit 70530e5c92
2 changed files with 74 additions and 3 deletions

View File

@@ -1035,7 +1035,78 @@ def prim_autonomous_pipeline(img, effects_list, dynamic_expressions, frame_num,
return pipeline(gpu_img, int(frame_num), float(fps)) return pipeline(gpu_img, int(frame_num), float(fps))
# ============================================================
# GPU Image Primitives (keep images on GPU)
# ============================================================
def gpu_make_image(w, h, color=None):
"""Create a new image on GPU filled with color (default black).
Unlike image:make-image, this keeps the image on GPU memory,
avoiding CPU<->GPU transfers in the pipeline.
"""
if not GPU_AVAILABLE:
# Fallback to CPU
import numpy as np
if color is None:
color = [0, 0, 0]
img = np.zeros((int(h), int(w), 3), dtype=np.uint8)
img[:] = color
return img
w, h = int(w), int(h)
if color is None:
color = [0, 0, 0]
# Create on GPU directly
img = cp.zeros((h, w, 3), dtype=cp.uint8)
img[:, :, 0] = int(color[0]) if len(color) > 0 else 0
img[:, :, 1] = int(color[1]) if len(color) > 1 else 0
img[:, :, 2] = int(color[2]) if len(color) > 2 else 0
return img
def gpu_gradient_image(w, h, color1=None, color2=None, direction='horizontal'):
"""Create a gradient image on GPU.
Args:
w, h: Dimensions
color1, color2: Start and end colors [r, g, b]
direction: 'horizontal', 'vertical', 'diagonal'
"""
if not GPU_AVAILABLE:
return gpu_make_image(w, h, color1)
w, h = int(w), int(h)
if color1 is None:
color1 = [0, 0, 0]
if color2 is None:
color2 = [255, 255, 255]
img = cp.zeros((h, w, 3), dtype=cp.uint8)
if direction == 'horizontal':
for c in range(3):
grad = cp.linspace(color1[c], color2[c], w, dtype=cp.float32)
img[:, :, c] = grad[cp.newaxis, :].astype(cp.uint8)
elif direction == 'vertical':
for c in range(3):
grad = cp.linspace(color1[c], color2[c], h, dtype=cp.float32)
img[:, :, c] = grad[:, cp.newaxis].astype(cp.uint8)
elif direction == 'diagonal':
for c in range(3):
x_grad = cp.linspace(0, 1, w, dtype=cp.float32)[cp.newaxis, :]
y_grad = cp.linspace(0, 1, h, dtype=cp.float32)[:, cp.newaxis]
combined = (x_grad + y_grad) / 2
img[:, :, c] = (color1[c] + (color2[c] - color1[c]) * combined).astype(cp.uint8)
return img
# Add GPU-specific primitives # Add GPU-specific primitives
PRIMITIVES['fused-pipeline'] = prim_fused_pipeline PRIMITIVES['fused-pipeline'] = prim_fused_pipeline
PRIMITIVES['autonomous-pipeline'] = prim_autonomous_pipeline PRIMITIVES['autonomous-pipeline'] = prim_autonomous_pipeline
PRIMITIVES['gpu-make-image'] = gpu_make_image
PRIMITIVES['gpu-gradient'] = gpu_gradient_image
# (The GPU video source will be added by create_cid_primitives in the task) # (The GPU video source will be added by create_cid_primitives in the task)

View File

@@ -27,10 +27,10 @@
:ripple_phase "t * 2.0f" :ripple_phase "t * 2.0f"
:brightness_factor "0.8f + 0.4f * sinf(t * 2.0f)"}) :brightness_factor "0.8f + 0.4f * sinf(t * 2.0f)"})
;; Frame pipeline - creates image and applies autonomous pipeline ;; Frame pipeline - creates image ON GPU and applies autonomous pipeline
(frame (frame
(let [;; Create base gradient (still needs Python for now) (let [;; Create base image ON GPU (no CPU involvement!)
base (image:make-image 1920 1080 [128 100 200])] base (streaming_gpu:gpu-make-image 1920 1080 [128 100 200])]
;; Apply autonomous pipeline - ALL EFFECTS + ALL MATH ON GPU! ;; Apply autonomous pipeline - ALL EFFECTS + ALL MATH ON GPU!
(streaming_gpu:autonomous-pipeline base effects expressions frame-num 30.0)))) (streaming_gpu:autonomous-pipeline base effects expressions frame-num 30.0))))