Skip to content
Merged
Show file tree
Hide file tree
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
26 changes: 22 additions & 4 deletions motrix_env_core/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,37 @@ authors = [{ name = "Motphys", email = "developers@motphys.com" }]
requires-python = "==3.10.*"
readme = "README.md"
license = "Apache-2.0"
# Heavy runtime deps (numba/scipy for manager kernel compilation, imageio for
# video recording) are optional extras so deployment-side installs
# (motrix-deploy and its backend plugins) only pull the lightweight config,
# registry and input layers of this package. gymnasium stays in the base
# dependencies because ``motrix_env_core.base`` (on the bare package import
# path) types observation/action spaces with it, and it is a small
# pure-Python distribution. array-api-compat is only used by the frontend
# helper module and is likewise small.
dependencies = [
"array-api-compat==1.15.0",
"gymnasium==1.1.1",
"imageio>=2.30",
"imageio-ffmpeg>=0.5",
"numba==0.61.2",
"numpy>=1.26",
"scipy==1.15.3", # numba requires scipy at compile time for np.linalg in kernels
"omegaconf>=2.3,<2.4",
"typing-extensions>=4.1",
]

[project.optional-dependencies]
# Manager kernel compilation and numba-accelerated mdp terms.
numba = [
"numba==0.61.2",
"scipy==1.15.3", # numba requires scipy at compile time for np.linalg in kernels
]
# Headless video recording via VideoRecorder.
video = [
"imageio>=2.30",
"imageio-ffmpeg>=0.5",
]
# Everything the training-side workspace needs from this package.
all = [
"motrix-env-core[numba,video]",
]
Comment thread
wlgys8 marked this conversation as resolved.
# TBB threading layer for numba parallel kernels: on many-core machines the
# default OpenMP layer pays a per-region thread-wakeup storm that dominates
# short kernels. The wheel drops libtbb.so.12 into <venv>/lib, so the runtime
Expand Down
12 changes: 11 additions & 1 deletion motrix_env_core/src/motrix_env_core/renderer.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
from pathlib import Path
from typing import Protocol

import imageio.v2 as imageio
import numpy as np

from motrix_env_core.base import EnvCfg
Expand Down Expand Up @@ -104,6 +103,17 @@ def close(self) -> None:

def _write_frame(self, frame: np.ndarray) -> None:
if self._writer is None:
# imageio is an optional dependency (``motrix-env-core[video]``):
# importing it lazily keeps this module importable in installs
# that only run headless training without video recording.
try:
import imageio.v2 as imageio
except ImportError as e:
raise ImportError(
"VideoRecorder requires the optional video dependencies; "
"install them with `pip install motrix-env-core[video]`"
) from e

self._path.parent.mkdir(parents=True, exist_ok=True)
# macro_block_size=None keeps the configured frame size untouched;
# the yuv420p pixel format still requires even dimensions, which
Expand Down
8 changes: 6 additions & 2 deletions motrix_env_core/tests/test_rendering.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
import numpy as np
import pytest

from motrix_env_core import renderer as core_renderer
from motrix_env_core.renderer import VideoRecorder, create_renderer
from motrix_env_core.sim.backend import RenderConfig, SimRenderer

Expand Down Expand Up @@ -58,7 +57,12 @@ def test_video_recorder_paces_frames_and_closes_frame_source(tmp_path, monkeypat
frames.capture.return_value = np.zeros((4, 4, 3), dtype=np.uint8)
writer = MagicMock()
get_writer = MagicMock(return_value=writer)
monkeypatch.setattr(core_renderer, "imageio", MagicMock(get_writer=get_writer))
# renderer imports imageio lazily inside _write_frame, so patch the real
# module attribute the function resolves on import. imageio is optional
# (motrix-env-core[video]); skip cleanly on minimal core installs.
imageio = pytest.importorskip("imageio.v2", reason="video recording requires motrix-env-core[video]")

monkeypatch.setattr(imageio, "get_writer", get_writer)

recorder = VideoRecorder(
frames,
Expand Down
2 changes: 1 addition & 1 deletion motrix_envs/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ readme = "README.md"
license = "Apache-2.0"
dependencies = [
"gymnasium==1.1.1",
"motrix-env-core",
"motrix-env-core[numba,video]",
"motrix-env-motrixsim",
"numpy>=1.26",
"omegaconf>=2.3,<2.4",
Expand Down
2 changes: 1 addition & 1 deletion motrix_rl/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ license = "Apache-2.0"
dependencies = [
"gymnasium==1.1.1",
"python-abc>=0.2.0",
"motrix-env-core",
"motrix-env-core[numba,video]",
"motrix-env-motrixsim",
"rich>=13",
"hydra-core>=1.3,<1.4",
Expand Down
Loading
Loading