A comprehensive, reusable GPU testing framework for Java projects with automatic backend selection, performance benchmarking, and CI/CD compatibility. Built with LWJGL 3.3.6 for multi-platform GPU compute testing.
- Multi-Backend Support: OpenCL, OpenGL Compute, Metal 3 (via bgfx)
- Headless Operation: Runs without display or windowing systems - perfect for CI/CD
- CI/CD Compatible: Automatic mock fallback in CI environments
- Performance Benchmarking: Built-in CPU vs GPU comparison with JMH
- Memory Analysis: Transfer overhead profiling and optimization guidance
- Cross-Validation: Ensure GPU and CPU implementations match
- Platform Detection: Automatic capability discovery across OS and architectures
- GPU Discovery: Automatic device enumeration and selection
- Graceful Degradation: Tests skip gracefully when GPU hardware is unavailable
- Mock Platform Support: Provides mock platforms when real hardware is unavailable
LWJGLHeadlessTest- Abstract base class for all LWJGL headless testsOpenCLHeadlessTest- OpenCL-specific base class with initialization and cleanupGPUComputeHeadlessTest- GPU compute testing with platform/device discoveryCICompatibleGPUTest- CI-compatible base class with automatic OpenCL detectionMockPlatform- Mock platform/device system for CI environments without OpenCLPlatformTestSupport- Utilities for platform-conditional test execution
HeadlessPlatformValidationTest- Platform validation (run this FIRST!)BasicGPUComputeTest- Example implementation showing framework usage
First, run the platform validation test to ensure your environment is properly configured:
mvn test -Dtest=HeadlessPlatformValidationTestExpected output on macOS M4:
=== LWJGL Headless Platform Validation ===
Platform: macOS (MACOSX)
Architecture: ARM64 (64-bit: true)
✅ Headless platform validation PASSED - Framework safe to use!
For CI-Compatible Tests (Recommended):
Extend CICompatibleGPUTest for automatic CI compatibility:
public class MyGPUTest extends CICompatibleGPUTest {
@Test
void testMyGPUKernel() {
var platforms = discoverPlatforms();
// CICompatibleGPUTest automatically skips when OpenCL unavailable
var platform = platforms.get(0);
var gpuDevices = discoverDevices(platform.platformId(), CL_DEVICE_TYPE_GPU);
if (MockPlatform.isMockPlatform(platform)) {
// Skip actual GPU operations with mock platforms
log.info("Using mock platform - skipping GPU kernel test");
return;
}
var device = gpuDevices.get(0);
testGPUVectorAddition(platform.platformId(), device.deviceId());
}
}For Direct GPU Testing:
Extend GPUComputeHeadlessTest with manual assumptions:
public class DirectGPUTest extends GPUComputeHeadlessTest {
@Test
void testMyGPUKernel() {
var platforms = discoverPlatforms();
assumeTrue(!platforms.isEmpty(), "No OpenCL platforms available");
var platform = platforms.get(0);
var gpuDevices = discoverDevices(platform.platformId(), CL_DEVICE_TYPE_GPU);
assumeTrue(!gpuDevices.isEmpty(), "No GPU devices available");
var device = gpuDevices.get(0);
testGPUVectorAddition(platform.platformId(), device.deviceId());
}
}Use PlatformTestSupport for conditional execution:
@Test
void testLinuxSpecificFeature() {
PlatformTestSupport.requirePlatform(Platform.LINUX);
// Test code here
}
@Test
void testWith64BitArch() {
PlatformTestSupport.require64Bit();
// Test code here
}
@Test
void testSkippingARM() {
PlatformTestSupport.skipOnARMForStackTests(); // For JVM stack tests
// Test code here
}The framework automatically handles platform-specific native libraries:
<dependency>
<groupId>com.hellblazer.luciferase</groupId>
<artifactId>gpu-test-framework</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>test</scope>
</dependency>- macOS: ARM64 (Apple Silicon), x86_64 (Intel)
- Linux: AMD64, ARM64
- Windows: AMD64
Native libraries are automatically selected based on your platform.
Tests run with headless configuration by default:
<systemPropertyVariables>
<java.awt.headless>true</java.awt.headless>
<lwjgl.opencl.explicitInit>true</lwjgl.opencl.explicitInit>
</systemPropertyVariables>The framework sets these JVM arguments automatically:
-Djava.awt.headless=true- Headless operation--add-modules jdk.incubator.vector- Vector API support- LWJGL debug settings for memory tracking
- Platform Validation - Verify LWJGL and OpenCL work on current platform
- Device Discovery - Enumerate available compute devices
- Compute Testing - Run actual GPU kernels with verification
- Memory Testing - Validate memory allocation patterns
Tests use JUnit 5's @EnabledIf and Assumptions for graceful handling:
@Test
@EnabledIf("hasGPUDevice") // Only run if GPU available
void testGPUKernel() { ... }
@Test
void testWithGracefulFallback() {
var devices = discoverDevices(platformId, CL_DEVICE_TYPE_GPU);
assumeTrue(!devices.isEmpty(), "No GPU - skipping test");
// Test code here
}- name: Run GPU Tests
run: mvn test -Dtest="*GPUTest"
env:
JAVA_TOOL_OPTIONS: -Djava.awt.headless=true- With GPU: All tests run and validate GPU compute functionality
- Without GPU: Tests skip gracefully with informative messages
- CI Systems: Framework detects headless environment and adapts accordingly
- "No OpenCL platforms found" - Normal on systems without OpenCL drivers
- ARM64 JVM stack tests fail - Expected limitation, library functions work fine
- macOS windowing errors - Use headless tests, or add
-XstartOnFirstThreadfor windowing
Enable debug logging for detailed GPU discovery information:
<systemPropertyVariables>
<org.lwjgl.util.Debug>true</org.lwjgl.util.Debug>
<org.lwjgl.util.DebugAllocator>true</org.lwjgl.util.DebugAllocator>
</systemPropertyVariables>If tests fail, first run the platform validation:
mvn test -Dtest=HeadlessPlatformValidationTestThis will provide detailed information about what's working and what isn't.
Successful GPU discovery and testing:
[INFO] Found 1 OpenCL platform(s):
[INFO] Apple - Apple (OpenCL 1.2 (Aug 25 2024 22:07:56))
[INFO] Found 1 device(s) on platform Apple:
[INFO] Apple M4 [GPU] - 10 CUs, 21474.8 MB mem
[INFO] Testing GPU vector addition on: Apple M4 [GPU] - 10 CUs, 21474.8 MB mem
[INFO] ✅ GPU vector addition test PASSED - 1024 elements processed
- GPU Implementation Details - Technical implementation reference for GPU testing patterns
- GPU Acceleration Guide - Setup and usage guide
This framework is designed for testing GPU acceleration in the Luciferase project:
- ESVO ray traversal - Efficient sparse voxel octree GPU kernels
- Spatial index operations - Parallel tree traversal and queries
- Collision detection - GPU-accelerated broad and narrow phase
- Rendering pipeline - Compute shaders for voxel rendering
- Memory bandwidth testing - Profiling large octree structures
The framework provides the foundation for testing GPU-accelerated spatial algorithms in a headless CI/CD environment.