mirror of
https://github.com/macaodha/batdetect2.git
synced 2026-08-22 03:00:10 +02:00
test: cover compile idempotency paths
This commit is contained in:
parent
8166db8f9c
commit
bad5d4f4fc
@ -1,4 +1,5 @@
|
|||||||
import uuid
|
import uuid
|
||||||
|
from dataclasses import dataclass
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Any, Callable, List, Optional, cast
|
from typing import Any, Callable, List, Optional, cast
|
||||||
from uuid import uuid4
|
from uuid import uuid4
|
||||||
@ -32,6 +33,12 @@ from batdetect2.train.lightning import build_training_module
|
|||||||
from batdetect2.train.types import ClipLabeller
|
from batdetect2.train.types import ClipLabeller
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class DetectorCompileRecorder:
|
||||||
|
compile_count: int = 0
|
||||||
|
call_count: int = 0
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def example_data_dir() -> Path:
|
def example_data_dir() -> Path:
|
||||||
pkg_dir = Path(__file__).parent.parent
|
pkg_dir = Path(__file__).parent.parent
|
||||||
@ -368,23 +375,25 @@ def sample_audio_loader() -> AudioLoader:
|
|||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def record_compiled_detector_calls(
|
def record_detector_compilation(
|
||||||
monkeypatch: pytest.MonkeyPatch,
|
monkeypatch: pytest.MonkeyPatch,
|
||||||
) -> Callable[[ModelProtocol], list[None]]:
|
) -> Callable[[ModelProtocol], DetectorCompileRecorder]:
|
||||||
def factory(model: ModelProtocol) -> list[None]:
|
def factory(model: ModelProtocol) -> DetectorCompileRecorder:
|
||||||
compiled_calls: list[None] = []
|
recorder = DetectorCompileRecorder()
|
||||||
detector = cast(Any, model.detector)
|
detector = cast(Any, model.detector)
|
||||||
original_call_impl = detector._call_impl
|
original_call_impl = detector._call_impl
|
||||||
|
|
||||||
def compile_detector() -> None:
|
def compile_detector() -> None:
|
||||||
|
recorder.compile_count += 1
|
||||||
|
|
||||||
def compiled_call(*args, **kwargs):
|
def compiled_call(*args, **kwargs):
|
||||||
compiled_calls.append(None)
|
recorder.call_count += 1
|
||||||
return original_call_impl(*args, **kwargs)
|
return original_call_impl(*args, **kwargs)
|
||||||
|
|
||||||
detector._compiled_call_impl = compiled_call
|
detector._compiled_call_impl = compiled_call
|
||||||
|
|
||||||
monkeypatch.setattr(detector, "compile", compile_detector)
|
monkeypatch.setattr(detector, "compile", compile_detector)
|
||||||
return compiled_calls
|
return recorder
|
||||||
|
|
||||||
return factory
|
return factory
|
||||||
|
|
||||||
|
|||||||
@ -156,9 +156,9 @@ def test_process_spectrogram_rejects_batched_input(
|
|||||||
def test_user_can_compile_api_detector(
|
def test_user_can_compile_api_detector(
|
||||||
api_v2: BatDetect2API,
|
api_v2: BatDetect2API,
|
||||||
example_audio_files: list[Path],
|
example_audio_files: list[Path],
|
||||||
record_compiled_detector_calls,
|
record_detector_compilation,
|
||||||
) -> None:
|
) -> None:
|
||||||
compiled_calls = record_compiled_detector_calls(api_v2.model)
|
recorder = record_detector_compilation(api_v2.model)
|
||||||
audio = api_v2.load_audio(example_audio_files[0])
|
audio = api_v2.load_audio(example_audio_files[0])
|
||||||
spec = api_v2.generate_spectrogram(audio)
|
spec = api_v2.generate_spectrogram(audio)
|
||||||
|
|
||||||
@ -166,7 +166,8 @@ def test_user_can_compile_api_detector(
|
|||||||
api_v2.compile()
|
api_v2.compile()
|
||||||
api_v2.process_spectrogram(spec)
|
api_v2.process_spectrogram(spec)
|
||||||
|
|
||||||
assert len(compiled_calls) == 1
|
assert recorder.compile_count == 1
|
||||||
|
assert recorder.call_count == 1
|
||||||
|
|
||||||
|
|
||||||
def test_api_from_config_compiles_detector_when_requested(
|
def test_api_from_config_compiles_detector_when_requested(
|
||||||
@ -187,6 +188,26 @@ def test_api_from_config_compiles_detector_when_requested(
|
|||||||
assert compiled_models == [api.model]
|
assert compiled_models == [api.model]
|
||||||
|
|
||||||
|
|
||||||
|
def test_api_from_checkpoint_compiles_detector_when_requested(
|
||||||
|
tiny_checkpoint_path: Path,
|
||||||
|
monkeypatch: pytest.MonkeyPatch,
|
||||||
|
) -> None:
|
||||||
|
compiled_models = []
|
||||||
|
|
||||||
|
def compile_model(model):
|
||||||
|
compiled_models.append(model)
|
||||||
|
return model
|
||||||
|
|
||||||
|
monkeypatch.setattr("batdetect2.models.compile_model", compile_model)
|
||||||
|
|
||||||
|
api = BatDetect2API.from_checkpoint(
|
||||||
|
tiny_checkpoint_path,
|
||||||
|
compile_model=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
assert compiled_models == [api.model]
|
||||||
|
|
||||||
|
|
||||||
def test_user_can_read_top_class_and_other_class_scores(
|
def test_user_can_read_top_class_and_other_class_scores(
|
||||||
api_v2: BatDetect2API,
|
api_v2: BatDetect2API,
|
||||||
example_audio_files: list[Path],
|
example_audio_files: list[Path],
|
||||||
|
|||||||
@ -59,10 +59,35 @@ def test_run_batch_inference_matches_single_clip_inference(
|
|||||||
|
|
||||||
def test_run_batch_inference_compiles_detector_when_config_requests_compile(
|
def test_run_batch_inference_compiles_detector_when_config_requests_compile(
|
||||||
example_annotations: list[data.ClipAnnotation],
|
example_annotations: list[data.ClipAnnotation],
|
||||||
record_compiled_detector_calls,
|
record_detector_compilation,
|
||||||
) -> None:
|
) -> None:
|
||||||
api = BatDetect2API.from_config()
|
api = BatDetect2API.from_config()
|
||||||
compiled_calls = record_compiled_detector_calls(api.model)
|
recorder = record_detector_compilation(api.model)
|
||||||
|
|
||||||
|
predictions = run_batch_inference(
|
||||||
|
api.model,
|
||||||
|
[example_annotations[0].clip],
|
||||||
|
targets=api.targets,
|
||||||
|
roi_mapper=api.roi_mapper,
|
||||||
|
audio_loader=api.audio_loader,
|
||||||
|
preprocessor=api.preprocessor,
|
||||||
|
output_transform=api.output_transform,
|
||||||
|
inference_config=InferenceConfig(compile_model=True),
|
||||||
|
batch_size=1,
|
||||||
|
num_workers=0,
|
||||||
|
)
|
||||||
|
|
||||||
|
assert predictions
|
||||||
|
assert recorder.compile_count == 1
|
||||||
|
assert recorder.call_count > 0
|
||||||
|
|
||||||
|
|
||||||
|
def test_run_batch_inference_does_not_recompile_compiled_detector(
|
||||||
|
example_annotations: list[data.ClipAnnotation],
|
||||||
|
record_detector_compilation,
|
||||||
|
) -> None:
|
||||||
|
api = BatDetect2API.from_config()
|
||||||
|
recorder = record_detector_compilation(api.model)
|
||||||
api.compile()
|
api.compile()
|
||||||
|
|
||||||
predictions = run_batch_inference(
|
predictions = run_batch_inference(
|
||||||
@ -79,4 +104,5 @@ def test_run_batch_inference_compiles_detector_when_config_requests_compile(
|
|||||||
)
|
)
|
||||||
|
|
||||||
assert predictions
|
assert predictions
|
||||||
assert compiled_calls
|
assert recorder.compile_count == 1
|
||||||
|
assert recorder.call_count > 0
|
||||||
|
|||||||
@ -312,7 +312,7 @@ def test_train_smoke_produces_loadable_checkpoint(
|
|||||||
def test_run_train_compiles_detector_when_train_config_requests_compile(
|
def test_run_train_compiles_detector_when_train_config_requests_compile(
|
||||||
tmp_path: Path,
|
tmp_path: Path,
|
||||||
example_annotations: list[data.ClipAnnotation],
|
example_annotations: list[data.ClipAnnotation],
|
||||||
record_compiled_detector_calls,
|
record_detector_compilation,
|
||||||
) -> None:
|
) -> None:
|
||||||
targets_config = TargetConfig()
|
targets_config = TargetConfig()
|
||||||
targets = build_targets(targets_config)
|
targets = build_targets(targets_config)
|
||||||
@ -324,7 +324,7 @@ def test_run_train_compiles_detector_when_train_config_requests_compile(
|
|||||||
)
|
)
|
||||||
train_config = build_fast_train_config()
|
train_config = build_fast_train_config()
|
||||||
train_config.compile_model = True
|
train_config.compile_model = True
|
||||||
compiled_calls = record_compiled_detector_calls(model)
|
recorder = record_detector_compilation(model)
|
||||||
|
|
||||||
module = run_train(
|
module = run_train(
|
||||||
train_annotations=example_annotations[:1],
|
train_annotations=example_annotations[:1],
|
||||||
@ -345,7 +345,8 @@ def test_run_train_compiles_detector_when_train_config_requests_compile(
|
|||||||
assert (
|
assert (
|
||||||
getattr(module.model.detector, "_compiled_call_impl", None) is not None
|
getattr(module.model.detector, "_compiled_call_impl", None) is not None
|
||||||
)
|
)
|
||||||
assert compiled_calls
|
assert recorder.compile_count == 1
|
||||||
|
assert recorder.call_count > 0
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.slow
|
@pytest.mark.slow
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user