Skip to main content

Cyfra

GPU compute pipelines in pure Scala 3.
Run anywhere.

⚠️ Beta release - not production ready. For experimentation and feedback.

Why Cyfra?

GPU programming with the expressiveness of Scala

Pure Scala 3 DSL

Write GPU code using familiar Scala syntax. Case classes become GPU structs, functions compile to shaders.

Vulkan Backend

Direct execution on Vulkan-compatible GPUs. NVIDIA, AMD, Intel, and Apple via MoltenVK.

Composable Pipelines

Chain GPU programs together. Intermediate data stays on the GPU. No round-trips to CPU.

Type-Safe

Scala's type system catches GPU programming errors at compile time.

Cross-Platform

Linux, Windows, macOS. Write once, run on any Vulkan-capable hardware.

Zero Overhead

Direct compilation to SPIR-V. Your Scala code runs at native GPU speeds.

See It In Action

Real projects built with Cyfra

Ray traced animation showing reflective spheres
GPU programming

GPU Ray Traced Scenes

Ray-traced animations with reflections and shadows. The Foton library provides a clean API for scenes, materials, and camera paths.

Navier-Stokes fluid simulation
Complex GPU pipelines

Navier-Stokes Solver

Real-time fluid dynamics on the GPU. Multi-stage pipeline solving Navier-Stokes equations with pressure projection.

Code That Runs on GPU

Write Scala. Execute on thousands of GPU cores.

Vector Operations
val normalize = GFunction[Vec4[Float32], Vec4[Float32]]:
  v => v / length(v)

val dot = GFunction[Vec4[Float32], Float32]:
  v => v dot (1f, 0f, 0f, 0f)
Built-in vector types map to GPU hardware.
Sequence Comprehensions
val iterations = GSeq
  .gen(vec2(0f, 0f), z =>
    vec2(z.x*z.x - z.y*z.y + cx, 2f*z.x*z.y + cy))
  .limit(256)
  .takeWhile(z => z.x*z.x + z.y*z.y < 4f)
  .count
Lazy sequences with map, filter, fold.
Custom GPU Structs
case class Physics(gravity: Float32, dt: Float32)
  extends GStruct[Physics]

val step = GFunction.forEachIndex[Physics, Vec4, Vec4]:
  (cfg, i, buf) =>
    val p = buf.read(i)
    (p.x, p.y + cfg.gravity * cfg.dt, p.z, p.w)
Case classes become GPU structs.
Monadic GPU Effects
for
  value = layout.input.read(idx)
  _ <- layout.bufferA.write(idx, value + 1f)
  _ <- layout.bufferB.write(idx, value * 2f)
yield value
Composable GIO monad for effectful computation.
GPU Pipelines
val pipeline = GExecution[Int, Layout]()
  .addProgram(multiply):
    size => size
    l => MulLayout(l.input, l.temp, l.mulParams)
  .addProgram(add):
    size => size
    l => AddLayout(l.temp, l.output, l.addParams)
Chain programs. Data stays on GPU.
GPU Memory Management
GBufferRegion
  .allocate[MyLayout]
  .map: layout =>
    pipeline.execute(params, layout)
  .runUnsafe(
    init = MyLayout(GBuffer(data), ...),
    onDone = l => l.output.readArray(results))
Allocate, execute, and read back GPU buffers.

Runs Everywhere

Any platform with Vulkan support

🐧Linux
🪟Windows
🍎macOS
🎮NVIDIA
🔴AMD
🔵Intel

Try Cyfra Today

Clone the repo, run the examples, and see what GPU programming in Scala feels like.

Read the Docs