Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 78 additions & 0 deletions tests/test_jax_tracer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
"""Tests for the JAX tracer."""

import pytest


class TestJAXTracer:
"""Test suite for JAXTracer."""

@pytest.fixture
def simple_jax_model(self):
"""Create a simple JAX function for testing."""
import jax.numpy as jnp

def my_function(x):
# Using simple operations that don't depend on specific shapes like dot
return x * 2.0 + jnp.ones_like(x)

return my_function

@pytest.fixture
def tracer(self):
"""Create a JAXTracer instance."""
from neuroscope.tracers.jax import JAXTracer

# Disable error suppression to catch issues during testing
return JAXTracer(suppress_errors=False)

def test_attach_detach(self, tracer, simple_jax_model):
"""Test attaching and detaching from a function."""
assert not tracer.is_attached

tracer.attach(simple_jax_model)
assert tracer.is_attached

tracer.detach()
assert not tracer.is_attached

def test_double_attach_raises(self, tracer, simple_jax_model):
"""Test that attaching twice raises an error."""
tracer.attach(simple_jax_model)

with pytest.raises(RuntimeError, match="Already attached"):
tracer.attach(simple_jax_model)

tracer.detach()

def test_attach_invalid_type(self, tracer):
"""Test that attaching to non-callable raises ValueError."""
with pytest.raises(ValueError, match="Expected callable"):
tracer.attach("not a function")

def test_forward_capture(self, tracer, simple_jax_model):
"""Test that forward pass captures nodes and tensor metadata."""
import jax.numpy as jnp

traced_fn = tracer.attach(simple_jax_model)
tracer.reset_graph()

x = jnp.ones((4, 10))
_ = traced_fn(x)

graph = tracer.get_graph()

# Should have input nodes and operation nodes
assert len(graph.nodes) > 0

# Check that nodes have tensor metadata
has_tensors = False
for node in graph.nodes.values():
if node.output_tensors:
has_tensors = True
tensor_meta = node.output_tensors[0]
assert len(tensor_meta.shape) > 0
assert tensor_meta.dtype != ""

assert has_tensors, "No output tensors found in graph nodes"

tracer.detach()