{"id":50619768,"url":"https://github.com/lene/optix-jni","last_synced_at":"2026-06-06T10:01:03.827Z","repository":{"id":362649138,"uuid":"1258582788","full_name":"lene/optix-jni","owner":"lene","description":"JNI bindings and native resources for NVIDIA OptiX ray tracing","archived":false,"fork":false,"pushed_at":"2026-06-05T08:32:13.000Z","size":2784,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-05T09:07:07.132Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Jupyter Notebook","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lene.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-03T18:07:16.000Z","updated_at":"2026-06-05T08:32:17.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/lene/optix-jni","commit_stats":null,"previous_names":["lene/optix-jni"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/lene/optix-jni","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lene%2Foptix-jni","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lene%2Foptix-jni/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lene%2Foptix-jni/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lene%2Foptix-jni/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lene","download_url":"https://codeload.github.com/lene/optix-jni/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lene%2Foptix-jni/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33977371,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-06T02:00:07.033Z","response_time":107,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-06-06T10:01:03.288Z","updated_at":"2026-06-06T10:01:03.820Z","avatar_url":"https://github.com/lene.png","language":"Jupyter Notebook","funding_links":[],"categories":[],"sub_categories":[],"readme":"# OptiX JNI Module\n\nThis module provides JNI bindings for NVIDIA OptiX ray tracing API.\n\n## Standalone Usage\n\n`optix-jni` publishes JNI bindings and native resources for Linux x86_64.\nIt depends on `menger-common` for shared scene types such as `Color`, `Vector`,\n`ImageSize`, and `Material`.\n\nCurrent test publication target: GitLab Package Registry.\n\n### sbt\n\n```scala\nThisBuild / scalaVersion := \"3.8.3\"\n\nresolvers += \"GitLab Menger\" at\n  \"https://gitlab.com/api/v4/projects/lilacashes%2Fmenger/packages/maven\"\n\ncredentials += Credentials(\n  \"GitLab Packages Registry\",\n  \"gitlab.com\",\n  \"Private-Token\",\n  sys.env(\"GITLAB_PAT\")\n)\n\nlibraryDependencies ++= Seq(\n  \"io.github.lene\" %% \"menger-common\" % \"0.1.0\",\n  \"io.github.lene\" % \"optix-jni\" % \"0.1.0\"\n)\n```\n\nIn GitLab CI, use username `gitlab-ci-token` with `CI_JOB_TOKEN` instead of a\npersonal access token.\n\n### Maven\n\n```xml\n\u003crepositories\u003e\n  \u003crepository\u003e\n    \u003cid\u003egitlab-menger\u003c/id\u003e\n    \u003curl\u003ehttps://gitlab.com/api/v4/projects/lilacashes%2Fmenger/packages/maven\u003c/url\u003e\n  \u003c/repository\u003e\n\u003c/repositories\u003e\n\n\u003cdependencies\u003e\n  \u003cdependency\u003e\n    \u003cgroupId\u003eio.github.lene\u003c/groupId\u003e\n    \u003cartifactId\u003emenger-common_3\u003c/artifactId\u003e\n    \u003cversion\u003e0.1.0\u003c/version\u003e\n  \u003c/dependency\u003e\n  \u003cdependency\u003e\n    \u003cgroupId\u003eio.github.lene\u003c/groupId\u003e\n    \u003cartifactId\u003eoptix-jni\u003c/artifactId\u003e\n    \u003cversion\u003e0.1.0\u003c/version\u003e\n  \u003c/dependency\u003e\n\u003c/dependencies\u003e\n```\n\nConfigure Maven credentials for repository id `gitlab-menger` in `settings.xml`.\nFor GitLab Package Registry, authenticate with a private token or CI job token.\n\n### Gradle Kotlin DSL\n\n```kotlin\nrepositories {\n    maven {\n        url = uri(\"https://gitlab.com/api/v4/projects/lilacashes%2Fmenger/packages/maven\")\n        credentials(HttpHeaderCredentials::class) {\n            name = \"Private-Token\"\n            value = System.getenv(\"GITLAB_PAT\")\n        }\n        authentication {\n            create\u003cHttpHeaderAuthentication\u003e(\"header\")\n        }\n    }\n}\n\ndependencies {\n    implementation(\"io.github.lene:menger-common_3:0.1.0\")\n    implementation(\"io.github.lene:optix-jni:0.1.0\")\n}\n```\n\n### Runtime Requirements\n\n- Linux x86_64.\n- NVIDIA GPU with OptiX support.\n- NVIDIA driver new enough for CUDA 12.8 runtime and OptiX SDK 9.0.\n- CUDA runtime libraries available to the dynamic linker. In local shells this is\n  usually `LD_LIBRARY_PATH=/usr/local/cuda/lib64` unless the system linker cache\n  already contains CUDA.\n- For containerized execution, expose GPU devices and set\n  `NVIDIA_DRIVER_CAPABILITIES=graphics,compute,utility`.\n\n### JVM Flags and Native Library Loading\n\nPublished `optix-jni` artifacts bundle `liboptixjni.so` and `optix_shaders.ptx`\nas classpath resources. In that case no `java.library.path` flag is normally\nneeded.\n\nFor local unpublished builds, point the JVM at the native build output:\n\n```bash\njava \\\n  -Djava.library.path=/path/to/menger/optix-jni/target/native/x86_64-linux/bin \\\n  -cp your-app.jar your.Main\n```\n\nWhen running through sbt:\n\n```bash\nsbt -Djava.library.path=/path/to/menger/optix-jni/target/native/x86_64-linux/bin run\n```\n\nIf CUDA libraries are not in the system linker cache, also set:\n\n```bash\nexport LD_LIBRARY_PATH=/usr/local/cuda/lib64:$LD_LIBRARY_PATH\n```\n\n### Basic sphere render\n\n```scala\nimport io.github.lene.optix.OptiXRenderer\nimport menger.common.Color\nimport menger.common.ImageSize\nimport menger.common.Vector\n\nif !OptiXRenderer.isLibraryLoaded then\n  sys.error(\"OptiX native library failed to load; check CUDA and OptiX setup\")\n\nval renderer = new OptiXRenderer()\ntry\n  if !renderer.initialize() then\n    sys.error(\"OptiX renderer failed to initialize\")\n\n  renderer.setSphere(Vector[3](0f, 0f, 0f), radius = 1f)\n  renderer.setSphereColor(Color(1f, 0.5f, 0.2f, 1f))\n  renderer.setCamera(\n    eye = Vector[3](0f, 0f, 5f),\n    lookAt = Vector[3](0f, 0f, 0f),\n    up = Vector[3](0f, 1f, 0f),\n    horizontalFovDegrees = 45f\n  )\n\n  val result = renderer.renderWithStats(ImageSize(800, 600))\n  if result == null then\n    sys.error(\"render failed\")\n\n  println(s\"Rendered ${result.image.length} RGBA bytes\")\nfinally\n  renderer.dispose()\n```\n\n### Alpha convention\n\n`alpha = 0.0` → fully transparent. `alpha = 1.0` → fully opaque.\n\n---\n\n## CI Configuration\n\n### Docker Image\n\nThe CI uses a pre-built Docker image based on NVIDIA's official CUDA image with OptiX SDK, Java 25, and sbt pre-installed. This avoids 15-20 minutes of installation time on every job run.\n\n**Image Versioning:**\n\nImages are tagged with version numbers of all pre-installed components:\n- Format: `{CUDA}-{OptiX}-{Java}-{sbt}`\n- Example: `12.8-9.0-25-1.11.7` = CUDA 12.8, OptiX 9.0, Java 25, sbt 1.11.7\n- The `latest` tag always points to the newest stable version\n- Scala version is NOT in the tag (managed by sbt from build.sbt at runtime)\n\n### GitLab Runner Setup\n\n**IMPORTANT**: The OptiX JNI CI tests require a GitLab Runner with GPU support. The Docker image alone is not sufficient - the runner itself must be configured to expose GPU access to containers.\n\nSee [RUNNER_SETUP.md](RUNNER_SETUP.md) for complete instructions on configuring a GitLab Runner with NVIDIA GPU support.\n\n### Building and Pushing the Docker Image\n\n**Build the image locally** (one-time setup, or when Dockerfile changes):\n\n```bash\n# Set version tag (update when upgrading CUDA/OptiX/Java/sbt)\nexport VERSION=12.8-9.0-25-1.11.7\n\n# Build the image (uses NVIDIA CUDA base image, faster than manual install)\ndocker build -t registry.gitlab.com/lilacashes/menger/optix-cuda:$VERSION -f optix-jni/Dockerfile optix-jni/\n\n# Tag as 'latest'\ndocker tag registry.gitlab.com/lilacashes/menger/optix-cuda:$VERSION registry.gitlab.com/lilacashes/menger/optix-cuda:latest\n\n# Login to GitLab container registry\ndocker login registry.gitlab.com\n# Username: your GitLab username\n# Password: use a Personal Access Token with 'write_registry' scope\n\n# Push both tags\ndocker push registry.gitlab.com/lilacashes/menger/optix-cuda:$VERSION\ndocker push registry.gitlab.com/lilacashes/menger/optix-cuda:latest\n```\n\n**After pushing a new version**, update `OPTIX_DOCKER_VERSION` in `.gitlab-ci.yml` to match.\n\n#### Building the CUDA 13 variant\n\nThe Dockerfile accepts a `CUDA_VERSION` build arg (default `12.8.0`):\n\n```bash\nexport VERSION13=13.2-9.0-25-1.12.0\n\ndocker build --build-arg CUDA_VERSION=13.2.0 \\\n  -t registry.gitlab.com/lilacashes/menger/optix-cuda:$VERSION13 \\\n  -f optix-jni/Dockerfile optix-jni/\n\ndocker push registry.gitlab.com/lilacashes/menger/optix-cuda:$VERSION13\n```\n\nAfter pushing, update `OPTIX_DOCKER_VERSION_CUDA13` in `.gitlab-ci.yml` if the tag changed.\n\n### Updating the Image\n\nWhen you need to update components (e.g., new CUDA/Java/sbt version):\n\n1. Edit `Dockerfile` (update FROM line, version numbers)\n2. Update version tag in build commands above\n3. Update `OPTIX_DOCKER_VERSION` in `.gitlab-ci.yml`\n4. Rebuild and push both tags\n5. The CI will automatically use the new image on the next run\n\n**Layer optimization:** The image uses NVIDIA's official CUDA base image and separates components into distinct layers. When upgrading:\n- Only Java: Only rebuild/push Java + sbt layers (~500MB)\n- Only sbt: Only rebuild/push sbt layer (~100MB)\n- CUDA from DockerHub is never pushed to our registry (saves 9GB)\n\n### Image Contents\n\n- Base: `nvidia/cuda:12.8.0-devel-ubuntu24.04` (~9GB, pulled from DockerHub)\n- Layer 2: Build tools (cmake, g++, wget, ~200MB)\n- Layer 3: OptiX SDK 9.0 (~500MB)\n- Layer 4: Java 25 LTS from Eclipse Temurin (~400MB)\n- Layer 5: sbt 1.11.7 and git (~100MB)\n\nTotal image size: ~11GB (but CUDA layer shared across all NVIDIA images)\n\n## Architecture\n\n### Two-Layer Design\n\n**Low-Level (OptiXContext):**\n- Pure OptiX API wrapper, stateless (only holds device context)\n- Explicit resource management (create/destroy pairs)\n- 1:1 mapping to OptiX operations\n- 16 Google Test C++ unit tests\n\n**High-Level (OptiXWrapper):**\n- Scene state management (sphere, camera, light, plane, material)\n- Convenience methods for scene setup\n- Performance: scene data in Params (not SBT) for fast parameter updates\n- Uses OptiXContext via composition\n\n### Directory Structure\n\n```\noptix-jni/src/main/\n  native/\n    CMakeLists.txt          # CMake build config\n    OptiXContext.cpp        # Low-level OptiX wrapper\n    OptiXWrapper.cpp        # High-level scene renderer\n    JNIBindings.cpp         # JNI interface\n    include/\n      OptiXContext.h\n      OptiXWrapper.h\n      OptiXData.h           # Shared data structures (Params, SBT)\n      OptiXConstants.h      # Magic number constants\n    shaders/\n      sphere_combined.cu    # Combined CUDA shaders (ONLY this file is compiled)\n    tests/\n      OptiXContextTest.cpp  # Google Test suite (16 tests)\n\n  scala/menger/optix/\n    OptiXRenderer.scala     # Main Scala API\n\ntarget/native/x86_64-linux/\n  bin/\n    liboptixjni.so          # Compiled JNI shared library\n    sphere_combined.ptx     # Compiled CUDA kernels\n```\n\n**IMPORTANT:** Only `sphere_combined.cu` is compiled. Separate shader files (`sphere_miss.cu`, `sphere_closesthit.cu`, `sphere_raygen.cu`) are outdated and NOT used. Check `CMakeLists.txt` to verify.\n\n### Key Components\n\n**OptiXContext** (`OptiXContext.h/.cpp`):\n- `initialize()`/`destroy()` - Device context lifecycle\n- `createModuleFromPTX()`/`destroyModule()` - Shader compilation\n- `createRaygenProgramGroup()`, `createMissProgramGroup()`, `createHitgroupProgramGroup()`\n- `createPipeline()`/`destroyPipeline()` - Pipeline assembly\n- `buildCustomPrimitiveGAS()`/`destroyGAS()` - Geometry acceleration\n- `createRaygenSBTRecord()`, `createMissSBTRecord()`, `createHitgroupSBTRecord()`\n- `launch()` - OptiX kernel execution\n\n**OptiXWrapper** (`OptiXWrapper.h/.cpp`):\n- `setSphere()`, `setSphereColor()`, `setIOR()`, `setScale()` - Scene config\n- `setCamera()`, `setLight()`, `setPlane()` - Environment\n- `render()` - High-level rendering (builds pipeline if needed, returns RGBA image)\n\n**JNI Interface** (`JNIBindings.cpp`, `OptiXRenderer.scala`):\n- Per-instance native handles (multiple renderer instances supported)\n- Error propagation via return codes\n- Functional-style library loading with Try monad\n\n**Shaders** (`sphere_combined.cu`):\n- Ray generation, miss, closest hit, custom sphere intersection\n- Reads scene data from Params struct (not SBT) for performance\n- Compiled to PTX at build time\n\n### Build Process\n\n1. sbt-jni plugin detects `CMakeLists.txt`\n2. CMake compiles C++/CUDA to PTX\n3. Google Test suite runs (16 C++ tests)\n4. Artifacts copied to `target/native/*/bin/`\n5. Scala loads native library via functional loader with Try monad\n\n**Note:** sbt-jni runs CMake every compile, but CMake skips unchanged files. Minimal output via `-Wno-dev`, `--log-level=WARNING`, `CMAKE_INSTALL_MESSAGE LAZY`.\n\n## Local Development\n\nFor local development with OptiX support, see the main project's `GPU_DEVELOPMENT.md`.\n\n## Environment Variables\n\n| Variable | Description | Default |\n|----------|-------------|---------|\n| `MENGER_OPTIX_CACHE` | Custom OptiX cache directory path | `/var/tmp/OptixCache_\u003cusername\u003e` |\n\n### Cache Management\n\nOptiX uses a disk cache to speed up pipeline compilation. The cache is stored in `/var/tmp/OptixCache_\u003cusername\u003e/` by default.\n\n**Cache Corruption Recovery:**\nThe renderer automatically detects cache corruption (SQLite database errors) and clears the corrupted cache. A fresh cache is rebuilt on the next render.\n\n**Custom Cache Location:**\nSet `MENGER_OPTIX_CACHE` to use a different cache directory:\n```bash\nexport MENGER_OPTIX_CACHE=/path/to/cache\n```\n\n**Manual Cache Clearing:**\nIf you encounter persistent issues, manually clear the cache:\n```bash\nrm -rf /var/tmp/OptixCache_$(whoami)\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flene%2Foptix-jni","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flene%2Foptix-jni","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flene%2Foptix-jni/lists"}