From 0d545d115d731c408cf6538f73bb990a4d74fb4d Mon Sep 17 00:00:00 2001 From: Nicolas Hug Date: Wed, 27 Aug 2025 14:14:54 +0100 Subject: [PATCH 1/2] Fix implicit conversion of int64 to int --- src/torchcodec/_core/CMakeLists.txt | 2 ++ src/torchcodec/_core/ValidationUtils.cpp | 35 ++++++++++++++++++++++ src/torchcodec/_core/ValidationUtils.h | 21 +++++++++++++ src/torchcodec/_core/custom_ops.cpp | 38 ++++++++++-------------- src/torchcodec/_core/pybind_ops.cpp | 14 ++++----- 5 files changed, 81 insertions(+), 29 deletions(-) create mode 100644 src/torchcodec/_core/ValidationUtils.cpp create mode 100644 src/torchcodec/_core/ValidationUtils.h diff --git a/src/torchcodec/_core/CMakeLists.txt b/src/torchcodec/_core/CMakeLists.txt index 1f09159e6..6770cd559 100644 --- a/src/torchcodec/_core/CMakeLists.txt +++ b/src/torchcodec/_core/CMakeLists.txt @@ -123,6 +123,7 @@ function(make_torchcodec_libraries set(custom_ops_sources AVIOTensorContext.cpp custom_ops.cpp + ValidationUtils.cpp ) set(custom_ops_dependencies ${core_library_name} @@ -140,6 +141,7 @@ function(make_torchcodec_libraries set(pybind_ops_sources AVIOFileLikeContext.cpp pybind_ops.cpp + ValidationUtils.cpp ) set(pybind_ops_dependencies ${core_library_name} diff --git a/src/torchcodec/_core/ValidationUtils.cpp b/src/torchcodec/_core/ValidationUtils.cpp new file mode 100644 index 000000000..fae3dd940 --- /dev/null +++ b/src/torchcodec/_core/ValidationUtils.cpp @@ -0,0 +1,35 @@ +// Copyright (c) Meta Platforms, Inc. and affiliates. +// All rights reserved. +// +// This source code is licensed under the BSD-style license found in the +// LICENSE file in the root directory of this source tree. + +#include "src/torchcodec/_core/ValidationUtils.h" +#include +#include "c10/util/Exception.h" + +namespace facebook::torchcodec { + +int validateInt64ToInt(int64_t value, const std::string& parameterName) { + TORCH_CHECK( + value >= std::numeric_limits::min() && + value <= std::numeric_limits::max(), + parameterName, + "=", + value, + " is out of range for int type."); + + return static_cast(value); +} + +std::optional validateOptionalInt64ToInt( + const std::optional& value, + const std::string& parameterName) { + if (value.has_value()) { + return validateInt64ToInt(value.value(), parameterName); + } else { + return std::nullopt; + } +} + +} // namespace facebook::torchcodec diff --git a/src/torchcodec/_core/ValidationUtils.h b/src/torchcodec/_core/ValidationUtils.h new file mode 100644 index 000000000..ce2d11256 --- /dev/null +++ b/src/torchcodec/_core/ValidationUtils.h @@ -0,0 +1,21 @@ +// Copyright (c) Meta Platforms, Inc. and affiliates. +// All rights reserved. +// +// This source code is licensed under the BSD-style license found in the +// LICENSE file in the root directory of this source tree. + +#pragma once + +#include +#include +#include + +namespace facebook::torchcodec { + +int validateInt64ToInt(int64_t value, const std::string& parameterName); + +std::optional validateOptionalInt64ToInt( + const std::optional& value, + const std::string& parameterName); + +} // namespace facebook::torchcodec diff --git a/src/torchcodec/_core/custom_ops.cpp b/src/torchcodec/_core/custom_ops.cpp index a5127e73f..c646ed54a 100644 --- a/src/torchcodec/_core/custom_ops.cpp +++ b/src/torchcodec/_core/custom_ops.cpp @@ -13,6 +13,7 @@ #include "src/torchcodec/_core/AVIOTensorContext.h" #include "src/torchcodec/_core/Encoder.h" #include "src/torchcodec/_core/SingleStreamDecoder.h" +#include "src/torchcodec/_core/ValidationUtils.h" namespace facebook::torchcodec { @@ -164,16 +165,6 @@ std::string mapToJson(const std::map& metadataMap) { return ss.str(); } -int validateSampleRate(int64_t sampleRate) { - TORCH_CHECK( - sampleRate <= std::numeric_limits::max(), - "sample_rate=", - sampleRate, - " is too large to be cast to an int."); - - return static_cast(sampleRate); -} - } // namespace // ============================== @@ -413,14 +404,17 @@ void encode_audio_to_file( std::optional bit_rate = std::nullopt, std::optional num_channels = std::nullopt, std::optional desired_sample_rate = std::nullopt) { - // TODO Fix implicit int conversion: - // https://github.com/pytorch/torchcodec/issues/679 AudioStreamOptions audioStreamOptions; - audioStreamOptions.bitRate = bit_rate; - audioStreamOptions.numChannels = num_channels; - audioStreamOptions.sampleRate = desired_sample_rate; + audioStreamOptions.bitRate = validateOptionalInt64ToInt(bit_rate, "bit_rate"); + audioStreamOptions.numChannels = + validateOptionalInt64ToInt(num_channels, "num_channels"); + audioStreamOptions.sampleRate = + validateOptionalInt64ToInt(desired_sample_rate, "desired_sample_rate"); AudioEncoder( - samples, validateSampleRate(sample_rate), file_name, audioStreamOptions) + samples, + validateInt64ToInt(sample_rate, "sample_rate"), + file_name, + audioStreamOptions) .encode(); } @@ -432,15 +426,15 @@ at::Tensor encode_audio_to_tensor( std::optional num_channels = std::nullopt, std::optional desired_sample_rate = std::nullopt) { auto avioContextHolder = std::make_unique(); - // TODO Fix implicit int conversion: - // https://github.com/pytorch/torchcodec/issues/679 AudioStreamOptions audioStreamOptions; - audioStreamOptions.bitRate = bit_rate; - audioStreamOptions.numChannels = num_channels; - audioStreamOptions.sampleRate = desired_sample_rate; + audioStreamOptions.bitRate = validateOptionalInt64ToInt(bit_rate, "bit_rate"); + audioStreamOptions.numChannels = + validateOptionalInt64ToInt(num_channels, "num_channels"); + audioStreamOptions.sampleRate = + validateOptionalInt64ToInt(desired_sample_rate, "desired_sample_rate"); return AudioEncoder( samples, - validateSampleRate(sample_rate), + validateInt64ToInt(sample_rate, "sample_rate"), format, std::move(avioContextHolder), audioStreamOptions) diff --git a/src/torchcodec/_core/pybind_ops.cpp b/src/torchcodec/_core/pybind_ops.cpp index e74e5574f..72969f7a9 100644 --- a/src/torchcodec/_core/pybind_ops.cpp +++ b/src/torchcodec/_core/pybind_ops.cpp @@ -13,6 +13,7 @@ #include "src/torchcodec/_core/Encoder.h" #include "src/torchcodec/_core/SingleStreamDecoder.h" #include "src/torchcodec/_core/StreamOptions.h" +#include "src/torchcodec/_core/ValidationUtils.h" namespace py = pybind11; @@ -55,20 +56,19 @@ void encode_audio_to_file_like( auto samples = torch::from_blob( reinterpret_cast(data_ptr), shape, tensor_options); - // TODO Fix implicit int conversion: - // https://github.com/pytorch/torchcodec/issues/679 - // same for sample_rate parameter below AudioStreamOptions audioStreamOptions; - audioStreamOptions.bitRate = bit_rate; - audioStreamOptions.numChannels = num_channels; - audioStreamOptions.sampleRate = desired_sample_rate; + audioStreamOptions.bitRate = validateOptionalInt64ToInt(bit_rate, "bit_rate"); + audioStreamOptions.numChannels = + validateOptionalInt64ToInt(num_channels, "num_channels"); + audioStreamOptions.sampleRate = + validateOptionalInt64ToInt(desired_sample_rate, "desired_sample_rate"); auto avioContextHolder = std::make_unique(file_like, /*isForWriting=*/true); AudioEncoder encoder( samples, - static_cast(sample_rate), + validateInt64ToInt(sample_rate, "sample_rate"), format, std::move(avioContextHolder), audioStreamOptions); From ae179f53e0215474eda4122f86914ede8a54dd42 Mon Sep 17 00:00:00 2001 From: Nicolas Hug Date: Thu, 28 Aug 2025 07:54:54 +0100 Subject: [PATCH 2/2] Move to core lib --- src/torchcodec/_core/CMakeLists.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/torchcodec/_core/CMakeLists.txt b/src/torchcodec/_core/CMakeLists.txt index 6770cd559..0793c8061 100644 --- a/src/torchcodec/_core/CMakeLists.txt +++ b/src/torchcodec/_core/CMakeLists.txt @@ -93,6 +93,7 @@ function(make_torchcodec_libraries CpuDeviceInterface.cpp SingleStreamDecoder.cpp Encoder.cpp + ValidationUtils.cpp ) if(ENABLE_CUDA) @@ -123,7 +124,6 @@ function(make_torchcodec_libraries set(custom_ops_sources AVIOTensorContext.cpp custom_ops.cpp - ValidationUtils.cpp ) set(custom_ops_dependencies ${core_library_name} @@ -141,7 +141,6 @@ function(make_torchcodec_libraries set(pybind_ops_sources AVIOFileLikeContext.cpp pybind_ops.cpp - ValidationUtils.cpp ) set(pybind_ops_dependencies ${core_library_name}