| 265 | |
| 266 | |
| 267 | class _AttentionBackendRegistry: |
| 268 | _backends = {} |
| 269 | _constraints = {} |
| 270 | _supported_arg_names = {} |
| 271 | _supports_context_parallel = set() |
| 272 | _active_backend = AttentionBackendName(DIFFUSERS_ATTN_BACKEND) |
| 273 | _checks_enabled = DIFFUSERS_ATTN_CHECKS |
| 274 | |
| 275 | @classmethod |
| 276 | def register( |
| 277 | cls, |
| 278 | backend: AttentionBackendName, |
| 279 | constraints: list[Callable] | None = None, |
| 280 | supports_context_parallel: bool = False, |
| 281 | ): |
| 282 | logger.debug(f"Registering attention backend: {backend} with constraints: {constraints}") |
| 283 | |
| 284 | def decorator(func): |
| 285 | cls._backends[backend] = func |
| 286 | cls._constraints[backend] = constraints or [] |
| 287 | cls._supported_arg_names[backend] = set(inspect.signature(func).parameters.keys()) |
| 288 | if supports_context_parallel: |
| 289 | cls._supports_context_parallel.add(backend.value) |
| 290 | |
| 291 | return func |
| 292 | |
| 293 | return decorator |
| 294 | |
| 295 | @classmethod |
| 296 | def get_active_backend(cls): |
| 297 | return cls._active_backend, cls._backends[cls._active_backend] |
| 298 | |
| 299 | @classmethod |
| 300 | def set_active_backend(cls, backend: str): |
| 301 | cls._active_backend = backend |
| 302 | |
| 303 | @classmethod |
| 304 | def list_backends(cls): |
| 305 | return list(cls._backends.keys()) |
| 306 | |
| 307 | @classmethod |
| 308 | def _is_context_parallel_available( |
| 309 | cls, |
| 310 | backend: AttentionBackendName, |
| 311 | ) -> bool: |
| 312 | supports_context_parallel = backend.value in cls._supports_context_parallel |
| 313 | return supports_context_parallel |
| 314 | |
| 315 | |
| 316 | @dataclass |
nothing calls this directly
no test coverage detected
searching dependent graphs…