"tests/vscode:/vscode.git/clone" did not exist on "e0e8736fa0d685715c2d7e217eb98928ce81c7f7"
Commit 39fe9df6 authored by moto's avatar moto Committed by Facebook GitHub Bot
Browse files

Add `is_ffmpeg_available` in test (#2170)

Summary:
Part of https://github.com/pytorch/audio/issues/2164.
To make the tests introduced in https://github.com/pytorch/audio/issues/2164 skippable if ffmpeg features are not available,
this commit adds `is_ffmpeg_available`.

The availability of the features depend on two factors;
1. If it was enabled at build.
2. If the ffmpeg libraries are found at runtime.

A simple way (for OSS workflow) to detect these is simply checking if
`libtorchaudio_ffmpeg` presents and can be loaded without a failure.

To facilitate this, this commit changes the
`torchaudio._extension._load_lib` to return boolean result.

Pull Request resolved: https://github.com/pytorch/audio/pull/2170

Reviewed By: carolineechen

Differential Revision: D33797695

Pulled By: mthrok

fbshipit-source-id: 85e767fc06350b8f99de255bc965b8c92b8cfe97
parent bcf04839
...@@ -7,6 +7,7 @@ from .case_utils import ( ...@@ -7,6 +7,7 @@ from .case_utils import (
TestBaseMixin, TestBaseMixin,
PytorchTestCase, PytorchTestCase,
TorchaudioTestCase, TorchaudioTestCase,
is_ffmpeg_available,
skipIfNoCtcDecoder, skipIfNoCtcDecoder,
skipIfNoCuda, skipIfNoCuda,
skipIfNoExec, skipIfNoExec,
...@@ -15,6 +16,7 @@ from .case_utils import ( ...@@ -15,6 +16,7 @@ from .case_utils import (
skipIfNoSox, skipIfNoSox,
skipIfRocm, skipIfRocm,
skipIfNoQengine, skipIfNoQengine,
skipIfNoFFmpeg,
) )
from .data_utils import ( from .data_utils import (
get_asset_path, get_asset_path,
...@@ -31,7 +33,6 @@ from .wav_utils import ( ...@@ -31,7 +33,6 @@ from .wav_utils import (
save_wav, save_wav,
) )
__all__ = [ __all__ = [
"get_asset_path", "get_asset_path",
"get_whitenoise", "get_whitenoise",
...@@ -43,6 +44,7 @@ __all__ = [ ...@@ -43,6 +44,7 @@ __all__ = [
"TestBaseMixin", "TestBaseMixin",
"PytorchTestCase", "PytorchTestCase",
"TorchaudioTestCase", "TorchaudioTestCase",
"is_ffmpeg_available",
"skipIfNoCtcDecoder", "skipIfNoCtcDecoder",
"skipIfNoCuda", "skipIfNoCuda",
"skipIfNoExec", "skipIfNoExec",
...@@ -52,6 +54,7 @@ __all__ = [ ...@@ -52,6 +54,7 @@ __all__ = [
"skipIfNoSoxBackend", "skipIfNoSoxBackend",
"skipIfRocm", "skipIfRocm",
"skipIfNoQengine", "skipIfNoQengine",
"skipIfNoFFmpeg",
"get_wav_data", "get_wav_data",
"normalize_wav", "normalize_wav",
"load_wav", "load_wav",
......
...@@ -7,6 +7,7 @@ import time ...@@ -7,6 +7,7 @@ import time
import unittest import unittest
import torch import torch
import torchaudio
from torch.testing._internal.common_utils import TestCase as PytorchTestCase from torch.testing._internal.common_utils import TestCase as PytorchTestCase
from torchaudio._internal.module_utils import is_module_available, is_sox_available, is_kaldi_available from torchaudio._internal.module_utils import is_module_available, is_sox_available, is_kaldi_available
...@@ -95,6 +96,13 @@ class TorchaudioTestCase(TestBaseMixin, PytorchTestCase): ...@@ -95,6 +96,13 @@ class TorchaudioTestCase(TestBaseMixin, PytorchTestCase):
pass pass
def is_ffmpeg_available():
try:
return torchaudio._extension._load_lib("libtorchaudio_ffmpeg")
except Exception:
return False
def _eval_env(var, default): def _eval_env(var, default):
if var not in os.environ: if var not in os.environ:
return default return default
...@@ -199,3 +207,8 @@ skipIfNoQengine = _skipIf( ...@@ -199,3 +207,8 @@ skipIfNoQengine = _skipIf(
reason="`fbgemm` is not available.", reason="`fbgemm` is not available.",
key="NO_QUANTIZATION", key="NO_QUANTIZATION",
) )
skipIfNoFFmpeg = _skipIf(
not is_ffmpeg_available(),
reason="ffmpeg features are not available.",
key="NO_FFMPEG",
)
...@@ -14,15 +14,43 @@ def _get_lib_path(lib: str): ...@@ -14,15 +14,43 @@ def _get_lib_path(lib: str):
return path return path
def _load_lib(lib: str): def _load_lib(lib: str) -> bool:
"""Load extension module
Note:
In case `torchaudio` is deployed with `pex` format, the library file
is not in a standard location.
In this case, we expect that `libtorchaudio` is available somewhere
in the search path of dynamic loading mechanism, so that importing
`_torchaudio` will have library loader find and load `libtorchaudio`.
This is the reason why the function should not raising an error when the library
file is not found.
Returns:
bool:
True if the library file is found AND the library loaded without failure.
False if the library file is not found (like in the case where torchaudio
is deployed with pex format, thus the shared library file is
in a non-standard location.).
If the library file is found but there is an issue loading the library,
(such as missing dependency) then this function raises the exception as-is.
Raises:
Exception:
If the library file is found, but there is an issue loading the library file,
(when underlying `ctype.DLL` throws an exception), this function will pass
the exception as-is, instead of catching it and returning bool.
The expected case is `OSError` thrown by `ctype.DLL` when a dynamic dependency
is not found.
This behavior was chosen because the expected failure case is not recoverable.
If a dependency is missing, then users have to install it.
"""
path = _get_lib_path(lib) path = _get_lib_path(lib)
# In case `torchaudio` is deployed with `pex` format, this file does not exist. if not path.exists():
# In this case, we expect that `libtorchaudio` is available somewhere return False
# in the search path of dynamic loading mechanism, and importing `_torchaudio`,
# which depends on `libtorchaudio` and dynamic loader will handle it for us.
if path.exists():
torch.ops.load_library(path) torch.ops.load_library(path)
torch.classes.load_library(path) torch.classes.load_library(path)
return True
def _init_extension(): def _init_extension():
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment