Skip to content
Draft
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
25 changes: 16 additions & 9 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,7 @@ Start here, then use the narrower docs for the task in front of you:

## Repo Map

- `flashdreams/flashdreams/core/`: reusable numerical primitives, checkpoint loading, distributed helpers, attention, and I/O. Keep it model-agnostic.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we referring to "Ignore .claude/worktrees/ when scanning the source tree; those are nested worktree artifacts, not the repo's current source." and not other AI specific hidden directories?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No good reason. I missed that. It points at .gitignore now instead of naming one tool. Thanks for pointing it out

- `flashdreams/flashdreams/infra/`: framework contracts and orchestration for configs, pipelines, encoders, decoders, diffusion models, schedulers, runners, profiling, and CUDA graph wrapping.
- `flashdreams/flashdreams/recipes/`: built-in reusable recipe code such as WAN, Cosmos, TAEHV, and template wiring.
- `flashdreams/flashdreams/configs/`, `plugins/`, and `scripts/`: runner registry, plugin discovery, and CLI entry points.
- `integrations/<name>/`: workspace-member model/plugin packages with their own configs, runners, tests, README files, and `pyproject.toml` entry points.
- `docs/source/`: Sphinx sources for quickstart, models, developer guides, API, and community docs.
- `tests/`: root test helpers plus package/integration tests. Ignore `.claude/worktrees/` when scanning the source tree; those are nested worktree artifacts, not the repo's current source.
File structure is in [CONTRIBUTING.md's File Tree Of FlashDreams](CONTRIBUTING.md#file-tree-of-flashdreams). Ignore gitignored AI-tool directories (see `.gitignore`) when scanning the source tree; they hold tool state, not the repo's current source.

## Skill Map

Expand Down Expand Up @@ -91,9 +85,22 @@ Use `--no-instantiate` before GPU work to inspect the resolved runner config wit

Every pytest test must carry exactly one of `ci_cpu`, `ci_gpu`, or `manual`; `CONTRIBUTING.md` has the exact rules. Use module-level `pytestmark = pytest.mark.ci_cpu` for pure Python/metadata tests. Keep GPU, `libGL`/`cv2`, large-checkpoint, credential, and download-heavy checks out of `ci_cpu`.

## Boundaries
**v2 test ownership** — put a new test next to the thing it validates:

Keep dependency direction strict: `core` -> `infra` -> recipes/integrations. `core` and `infra` must not import from `integrations/`; expose a generic config slot or override hook instead of adding model-specific branches. Built-in reusable model pieces belong in `flashdreams/flashdreams/recipes/`; standalone plugin packages belong in `integrations/<name>/`.
| You are testing… | Test lives in… |
| --- | --- |
| FlashDreams Runtime/Protocol (window, threads, presentation) | `flashdreams/test_v2/` |
| An app (flags, WASD, physics) | `apps/<name>/tests/` |
| A model or its adapter | `integrations_v2/<model>/tests/` |

## Dependencies

- `infra` depends on `core` — never the other way around. `core` stays model-agnostic.
- `recipes`/`integrations_v2` depend on `infra` and `core` — never the other way around. Expose a generic config slot or override hook in `core`/`infra` instead of adding model-specific branches. Built-in reusable model pieces belong in `flashdreams/flashdreams/recipes/`; standalone plugin packages belong in `integrations_v2/<name>/`.
- `apps/<name>/` depends on `flashdreams` — never the other way around. An app is written against the framework, not against any one model: it must run against a stub network, and binding a real model is the adapter's job.
- `integrations_v2/<model>/` depends on `flashdreams` and on the app it adapts for (via its own `integrations_v2/<model>/apps/<demo>/adapter.py`) — never the other way around.

Because of this direction, tests in `apps/<name>/tests/` must not import from `integrations_v2/` — an app's tests run against a stub, and model-specific checks belong in `integrations_v2/<model>/tests/`. CI enforcement of this is a separate follow-up, not yet built.

## Known Pitfalls

Expand Down
68 changes: 57 additions & 11 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,14 @@ issue and we'll fix it.
3. [Developer Certificate of Origin (DCO)](#developer-certificate-of-origin-dco)
4. [Submitting a pull request](#submitting-a-pull-request)
5. [Code review and merge](#code-review-and-merge)
6. [Coding conventions](#coding-conventions)
7. [Testing](#testing)
8. [Dependency version bounds](#dependency-version-bounds)
9. [Working with a single integration package](#working-with-a-single-integration-package)
10. [Licensing of contributions](#licensing-of-contributions)
11. [Reporting issues](#reporting-issues)
12. [Code of Conduct](#code-of-conduct)
6. [File Tree Of FlashDreams](#file-tree-of-flashdreams)
7. [Coding conventions](#coding-conventions)
8. [Testing](#testing)
9. [Dependency version bounds](#dependency-version-bounds)
10. [Working with a single integration package](#working-with-a-single-integration-package)
11. [Licensing of contributions](#licensing-of-contributions)
12. [Reporting issues](#reporting-issues)
13. [Code of Conduct](#code-of-conduct)

## Ways to contribute

Expand Down Expand Up @@ -223,6 +224,51 @@ We aim for an initial review on every PR within two business days. If
your PR has been quiet longer than that, please feel free to leave a
short ping comment.

## File Tree Of FlashDreams

```text
apps/<app_slug>/ # apps (Drive, T2V, Cam2V, ...)
<app_slug>/ # app implementation
tests/ # validate app implementation
pyproject.toml
README.md

integrations_v2/<model>/ # model integrations + demo bindings
config.py # collection of pipeline definitions for a particular `<model>`
impl/ # implementation details of a model
tests/ # validate model implementation
apps/<demo>/adapter.py # contains all entry point definitions (ex: `create_app`) for a particular `<demo>`
pyproject.toml
README.md

flashdreams/flashdreams/ # the framework package
core/ # numerical primitives, checkpoint loading, attention, I/O
infra/ # framework contracts: configs, pipelines, encoders/decoders, schedulers, runners
recipes/ # built-in reusable recipe code (WAN, Cosmos, TAEHV, ...)
api_v2/ # protocols an application implements
runtime_v2/ # the two-thread loop that runs an application
runtime/ # experimental inference runtime API envelope (v0, pre-v2)
serving/ # optional serving utilities (WebRTC, network, launch)
demo/ # transport-neutral application hosting and I/O API
accelerated/ # accelerated kernels (quantization, multi-head attention)
quality/ # output-quality regression utilities (video, CLIP compare)
configs/ # runner registry and CLI aggregator
plugins/ # external-runner plugin layer (RunnerConfig discovery)
scripts/ # console-script entry points (flashdreams-run)
_pytest_plugins/ # pytest plugins (e.g. CI-tier marker enforcement)

flashdreams/test_v2/ # FlashDreams Runtime/Protocol tests (window, run_session, threads)
flashdreams/tests/ # framework tests not yet migrated to test_v2/
tests/ # repo-wide test-runner scripts + meta checks, not package tests
docs/source/ # Sphinx sources
```

The `integrations_v2/<model>/` shape above is the layout for a model
integration. The smaller demo and fixture packages (`color_fade`,
`red_screen`, `null_model`, `imgui_ui_demo`, `slangpy_ui_demo`) carry a flat
`<name>/` package instead; see
[`integrations_v2/README.md`](https://github.com/NVIDIA/flashdreams/blob/main/integrations_v2/README.md) for what each one is.

## Coding conventions

- Python 3.10+. Type-annotate new code; the project type-checks with
Expand All @@ -232,9 +278,9 @@ short ping comment.
locally is the easiest way to avoid surprises.
- Prefer small, well-named functions over long functions with comments
explaining each block. Comments should explain *why*, not *what*.
- Tests live in `flashdreams/tests/`, `integrations/*/tests/`, and
`integrations_v2/*/tests/`. Use
`pytest` and prefer existing fixtures over hand-rolled setup. See
- Tests live next to the thing they validate — see the File Tree Of
FlashDreams above. Use `pytest` and prefer existing fixtures over
hand-rolled setup. See
[Testing](#testing) for marker requirements.
- Every source file added by a contribution must include the SPDX
header used elsewhere in the project:
Expand Down Expand Up @@ -321,7 +367,7 @@ the declared minimums. This means:

## Working with a single integration package

The workspace contains many integration packages under `integrations/`.
The workspace contains many integration packages under `integrations_v2/`.
A full `uv sync` installs dependencies for *all* of them. If you only
need one (e.g. you're working on `omnidreams`), use the distribution
package name with `--package` to sync only that package's dependencies:
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ Drive a world model in real time with the unified OmniDreams `local-window` or
## Supported models

FlashDreams ships first-party integrations under
[`integrations/`](integrations/). Each model has a dedicated docs page with
[`integrations_v2/`](integrations_v2/). Each model has a dedicated docs page with
runner slugs, multi-GPU commands, and (where available) profiling benchmarks.

| Model | Family |
Expand Down
197 changes: 57 additions & 140 deletions apps/crazy_robotaxi/tests/test_application.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

"""CPU tests for Crazy Robotaxi's application boundary against FlashDreams V2."""

from dataclasses import replace
from dataclasses import dataclass, field, replace
from pathlib import Path
from types import SimpleNamespace
from typing import Any, cast
Expand All @@ -29,30 +29,6 @@
_taxi_driver_command,
)
from crazy_robotaxi.ui import CrazyRobotaxiImGuiUILoop
from omnidreams.apps.crazy_robotaxi.adapter import (
OMNIDREAMS_CRAZY_ROBOTAXI_DEFAULTS,
OMNIDREAMS_CRAZY_ROBOTAXI_FAST_PERF_DEFAULTS,
OMNIDREAMS_CRAZY_ROBOTAXI_FAST_PERF_RESPONSIVE_DEFAULTS,
OMNIDREAMS_CRAZY_ROBOTAXI_OPTIMIZED_GB300_DEFAULTS,
OMNIDREAMS_CRAZY_ROBOTAXI_OPTIMIZED_GB300_RESPONSIVE_DEFAULTS,
OMNIDREAMS_CRAZY_ROBOTAXI_OPTIMIZED_RTX_PRO_6000_DEFAULTS,
OMNIDREAMS_CRAZY_ROBOTAXI_OPTIMIZED_RTX_PRO_6000_RESPONSIVE_DEFAULTS,
OMNIDREAMS_CRAZY_ROBOTAXI_PERF_DEFAULTS,
OMNIDREAMS_CRAZY_ROBOTAXI_PERF_RESPONSIVE_DEFAULTS,
OMNIDREAMS_CRAZY_ROBOTAXI_RESPONSIVE_DEFAULTS,
)
from omnidreams.config import (
OMNIDREAMS_FAST_PERF_PIPELINE_CONFIG,
OMNIDREAMS_FAST_PERF_RESPONSIVE_PIPELINE_CONFIG,
OMNIDREAMS_OPTIMIZED_GB300_PIPELINE_CONFIG,
OMNIDREAMS_OPTIMIZED_GB300_RESPONSIVE_PIPELINE_CONFIG,
OMNIDREAMS_OPTIMIZED_RTX_PRO_6000_PIPELINE_CONFIG,
OMNIDREAMS_OPTIMIZED_RTX_PRO_6000_RESPONSIVE_PIPELINE_CONFIG,
OMNIDREAMS_PERF_PIPELINE_CONFIG,
OMNIDREAMS_PERF_RESPONSIVE_PIPELINE_CONFIG,
OMNIDREAMS_PIPELINE_CONFIG,
OMNIDREAMS_RESPONSIVE_PIPELINE_CONFIG,
)
from omnidreams_game_engine.config import BevConfig, RasterConfig
from omnidreams_game_engine.input import DriverInput
from omnidreams_game_engine.renderer_settings import RendererSettings
Expand All @@ -63,11 +39,12 @@
SceneDefinition,
)

from flashdreams.runtime_v2.native_window_client_window import (
NativeWindowClientWindow,
)
from flashdreams.infra.diffusion.model import DiffusionModelConfig
from flashdreams.infra.diffusion.scheduler.base import SchedulerConfig
from flashdreams.infra.diffusion.transformer.base import TransformerConfig
from flashdreams.infra.encoder.base import EncoderConfig
from flashdreams.infra.pipeline import StreamInferencePipelineConfig
from flashdreams.runtime_v2.session_desc import PresentationMode
from flashdreams.runtime_v2.step_result import StepResult
from flashdreams.runtime_v2.user_input_event import (
GamepadUserInputEvent,
KeyboardInputState,
Expand All @@ -86,9 +63,58 @@
)


@dataclass(kw_only=True)
class _StubTransformerConfig(TransformerConfig):
"""Adds the fields CrazyRobotaxiApplication logs unconditionally.

Placeholder values only; no test in this file inspects them (tests that
care about real acceleration/backend settings live under
integrations_v2/omnidreams/tests/, since apps/ must not import
integrations_v2/).
"""

native_dit_acceleration: str | None = None
native_dit_backend: str | None = None
native_dit_attention_backend: str | None = None
skip_finalize_kv_cache: bool = False
compile_network: bool = False


@dataclass(kw_only=True)
class _StubEncoderConfig(EncoderConfig):
"""Adds the fields CrazyRobotaxiApplication logs unconditionally."""

native_vae_acceleration: str | None = None
native_vae_backend: str | None = None


@dataclass(kw_only=True)
class _StubSchedulerConfig(SchedulerConfig):
"""Adds the field CrazyRobotaxiApplication logs unconditionally."""

denoising_timesteps: list[int] = field(default_factory=list)


_STUB_PIPELINE_CONFIG = StreamInferencePipelineConfig(
name="crazy-robotaxi-test-stub",
diffusion_model=DiffusionModelConfig(
transformer=_StubTransformerConfig(),
scheduler=_StubSchedulerConfig(),
),
encoder=_StubEncoderConfig(),
)
"""A pipeline config with no model behind it, built from base flashdreams
config classes only. CrazyRobotaxiApplication reads ``.name``, derives
``.enable_sync_and_profile``, and logs several transformer/encoder fields
unconditionally, so app-level tests need a real, structured pipeline config,
not a real *model*."""

_STUB_DEFAULTS = CrazyRobotaxiApplicationDefaults(pipeline_config=_STUB_PIPELINE_CONFIG)


def _application(
*,
defaults: CrazyRobotaxiApplicationDefaults = OMNIDREAMS_CRAZY_ROBOTAXI_DEFAULTS,
defaults: CrazyRobotaxiApplicationDefaults = _STUB_DEFAULTS,
**kwargs: Any,
) -> CrazyRobotaxiApplication:
return CrazyRobotaxiApplication(defaults=defaults, **kwargs)
Expand Down Expand Up @@ -464,70 +490,6 @@ def test_pipeline_profiling_is_an_app_local_opt_in(
assert configured[0].enable_sync_and_profile is expected
assert app._config is not None
assert app._config.pipeline_profiling is expected
assert OMNIDREAMS_PIPELINE_CONFIG.enable_sync_and_profile


def test_model_adapters_keep_their_packaged_pipeline_configs() -> None:
for defaults, pipeline_config in (
(OMNIDREAMS_CRAZY_ROBOTAXI_DEFAULTS, OMNIDREAMS_PIPELINE_CONFIG),
(
OMNIDREAMS_CRAZY_ROBOTAXI_PERF_DEFAULTS,
OMNIDREAMS_PERF_PIPELINE_CONFIG,
),
(
OMNIDREAMS_CRAZY_ROBOTAXI_FAST_PERF_DEFAULTS,
OMNIDREAMS_FAST_PERF_PIPELINE_CONFIG,
),
(
OMNIDREAMS_CRAZY_ROBOTAXI_OPTIMIZED_GB300_DEFAULTS,
OMNIDREAMS_OPTIMIZED_GB300_PIPELINE_CONFIG,
),
(
OMNIDREAMS_CRAZY_ROBOTAXI_OPTIMIZED_RTX_PRO_6000_DEFAULTS,
OMNIDREAMS_OPTIMIZED_RTX_PRO_6000_PIPELINE_CONFIG,
),
(
OMNIDREAMS_CRAZY_ROBOTAXI_RESPONSIVE_DEFAULTS,
OMNIDREAMS_RESPONSIVE_PIPELINE_CONFIG,
),
(
OMNIDREAMS_CRAZY_ROBOTAXI_PERF_RESPONSIVE_DEFAULTS,
OMNIDREAMS_PERF_RESPONSIVE_PIPELINE_CONFIG,
),
(
OMNIDREAMS_CRAZY_ROBOTAXI_FAST_PERF_RESPONSIVE_DEFAULTS,
OMNIDREAMS_FAST_PERF_RESPONSIVE_PIPELINE_CONFIG,
),
(
OMNIDREAMS_CRAZY_ROBOTAXI_OPTIMIZED_GB300_RESPONSIVE_DEFAULTS,
OMNIDREAMS_OPTIMIZED_GB300_RESPONSIVE_PIPELINE_CONFIG,
),
(
OMNIDREAMS_CRAZY_ROBOTAXI_OPTIMIZED_RTX_PRO_6000_RESPONSIVE_DEFAULTS,
OMNIDREAMS_OPTIMIZED_RTX_PRO_6000_RESPONSIVE_PIPELINE_CONFIG,
),
):
assert defaults.pipeline_config is pipeline_config


def test_fast_perf_combines_native_dit_and_native_vae_paths() -> None:
pipeline: Any = OMNIDREAMS_FAST_PERF_PIPELINE_CONFIG
perf_pipeline: Any = OMNIDREAMS_PERF_PIPELINE_CONFIG
assert pipeline.name == "omnidreams-fast-perf"
assert pipeline.diffusion_model.seed is None
assert pipeline.decoder.use_compile is perf_pipeline.decoder.use_compile
assert pipeline.decoder.use_cuda_graph is True
assert pipeline.image_encoder.native_vae_acceleration == "required"
assert pipeline.image_encoder.native_vae_backend == "fp8"
assert pipeline.image_encoder.native_vae_fp8_auto_export is True
assert pipeline.encoder.native_vae_acceleration == "required"
assert pipeline.encoder.native_vae_backend == "fp8"
assert pipeline.encoder.native_vae_fp8_auto_export is True
assert pipeline.diffusion_model.transformer.native_dit_acceleration == "required"
assert (
pipeline.diffusion_model.transformer.native_dit_backend == "fp8_kvcache_cudnn"
)
assert pipeline.diffusion_model.transformer.native_dit_attention_backend == "cudnn"


@pytest.mark.parametrize("resolution_wh", [(1280, 704), (1168, 640)])
Expand All @@ -548,7 +510,7 @@ def load_test_scene(request: object, raster: RasterConfig) -> SceneDefinition:

app = _application(
defaults=replace(
OMNIDREAMS_CRAZY_ROBOTAXI_FAST_PERF_DEFAULTS,
_STUB_DEFAULTS,
width=resolution_wh[0],
height=resolution_wh[1],
),
Expand Down Expand Up @@ -584,51 +546,6 @@ def load_test_scene(request: object, raster: RasterConfig) -> SceneDefinition:
)


def test_fast_perf_honors_explicit_pipeline_overrides() -> None:
app = _application(
defaults=OMNIDREAMS_CRAZY_ROBOTAXI_FAST_PERF_DEFAULTS,
)

app.init(
[
"--seed",
"7",
"--no-compile",
"--profile-pipeline",
]
)

pipeline = cast(Any, app._pipeline_config)
transformer = pipeline.diffusion_model.transformer
assert pipeline.diffusion_model.seed == 7
assert transformer.compile_network is False
assert transformer.native_dit_acceleration == "required"
assert transformer.skip_finalize_kv_cache is True
assert pipeline.diffusion_model.scheduler.denoising_timesteps == [1000, 100]
assert pipeline.enable_sync_and_profile is True


def test_map_context_disables_only_native_dit_on_selected_preset() -> None:
app = _application(defaults=OMNIDREAMS_CRAZY_ROBOTAXI_FAST_PERF_DEFAULTS)

app.init(["--live-edit-map-context"])

pipeline = cast(Any, app._pipeline_config)
original: Any = OMNIDREAMS_FAST_PERF_PIPELINE_CONFIG
transformer = pipeline.diffusion_model.transformer
assert app._config is not None
assert app._config.scene_request.use_prompt_context
assert pipeline.name == original.name
assert transformer.native_dit_acceleration == "disabled"
assert transformer.native_dit_backend == (
original.diffusion_model.transformer.native_dit_backend
)
assert transformer.skip_finalize_kv_cache is True
assert pipeline.diffusion_model.scheduler == original.diffusion_model.scheduler
assert pipeline.image_encoder.native_vae_acceleration == "required"
assert pipeline.encoder.native_vae_acceleration == "required"


def test_bev_render_fit_preserves_authored_aspect_ratio_and_smaller_sources() -> None:
raster = RasterConfig()
wide = RendererSettings(raster=raster, bev=BevConfig(width=800, height=400))
Expand Down
Loading
Loading