Fix fileobj I/O un-deterministic behavior #1297
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Ever since the file-like object support was added in #1158, the test
was occasionally failing in CI. This PR fixes this.
What issues are resolved by this PR?
The failing tests exhibit flakiness in the following three areas;
info_test
For
mp3
andvorbis
formats, the number of reported frames were most times zero (this is due to the container format), but occasionally, the test reported a correct number. It should be always reporting the same number.load_test
The shape of the Tensor loaded with
load
function occasionally had different number of frames than what actually the file has.save_test
The saved data occasionally lacked some frames at the end.
On which environment were the issues happening?
unix system, all Python environment
What was the cause and what is the fix?
When opening file (for both read and write),
libsox
initializes the dedicated data structure calledsox_format_t
, and set various attributes. One of which isseekable
and this value is supposed to befalse
for file-like objects. In the investigation #1229, it turned out that this attribute is occasionallytrue
which contributed to the un-deterministic behavior described above. The following code fromlibsox
determines if the openedFILE*
isseekable
, by simply checking if the associated file descriptor is a regular file. [src]The problem is that
fileno
returns-1
for the case of file-like object. This is because for file-like object, we usesox_open_mem_read
orsox_open_mem_stream_write
, which callsfmemopen
andopen_memstream
respectively, and the resulting*FILE
object does not have the associated file descriptor. In this case,fstat
received-1
as the file descriptor value and (I guess) thestat
structure is untouched. Thus the attribute ofst_mode
has an un-initialized value, which result in un-deterministic behavior.This PR adds patch to check the the value of file descriptor and mark
seekable=false
if it does not have a valid file descriptor.How do we know this patch fixes the issue?
I took the detailed note on #1229. The following script will keep running the tests.
https://github.com/mthrok/audio/blob/10ba189d8bc5f0beb5f7200fcb59778acc490033/debug_fileobj.sh#L1
Before applying the patch, it typically took ~15 mins for one of the tests to fail. After this patch is applied, they do not fail. I kept running the test over night and none of the tests failed.
TODOs
release/0.8
is_seekable
returntrue
for the in-memory file object case (need to verify this), which is the opposite of the behavior we want in torchaudio implementation.