/usr/local/lib64/python3.6/site-packages/torch/include/ATen/native
NameSizeModeActions
cpu/-0755rm
cuda/-0755rm
quantized/-0755rm
Activation.h30690644editdlrm
AdaptivePooling.h11650644editdlrm
BatchLinearAlgebra.h82460644editdlrm
batch_norm.h12850644editdlrm
BinaryOps.h49160644editdlrm
BucketizationUtils.h42480644editdlrm
ComplexHelper.h37970644editdlrm
CompositeRandomAccessor.h8880644editdlrm
CompositeRandomAccessorCommon.h67130644editdlrm
ConvUtils.h53500644editdlrm
Copy.h3560644editdlrm
CPUBlas.h41990644editdlrm
CPUFallback.h24040644editdlrm
Cross.h2620644editdlrm
DilatedConvolutionUtils.h64160644editdlrm
DispatchStub.h76720644editdlrm
Distance.h7320644editdlrm
Distributions.h216540644editdlrm
DistributionTemplates.h186230644editdlrm
EmbeddingBag.h13200644editdlrm
Fill.h3840644editdlrm
ForeachUtils.h59620644editdlrm
FunctionOfAMatrixUtils.h4360644editdlrm
GridSampler.h105250644editdlrm
group_norm.h8960644editdlrm
Histogram.h4920644editdlrm
im2col.h28380644editdlrm
im2col_shape_check.h61810644editdlrm
IndexingUtils.h53730644editdlrm
layer_norm.h28920644editdlrm
Lerp.h5530644editdlrm
LinearAlgebra.h6030644editdlrm
LinearAlgebraUtils.h252360644editdlrm
LossMulti.h21970644editdlrm
Math.h913560644editdlrm
MathBitFallThroughLists.h40860644editdlrm
MathBitsFallback.h73260644editdlrm
MaxPooling.h12340644editdlrm
Normalization.h3020644editdlrm
PointwiseOps.h7490644editdlrm
Pool.h109220644editdlrm
Pow.h16940644editdlrm
ReduceAllOps.h3780644editdlrm
ReduceOps.h17450644editdlrm
ReduceOpsUtils.h122450644editdlrm
Repeat.h12860644editdlrm
Resize.h65010644editdlrm
ResizeCommon.h13210644editdlrm
RNN.h24670644editdlrm
ScatterGatherChecks.h36410644editdlrm
SegmentReduce.h6850644editdlrm
SharedReduceOps.h157850644editdlrm
SobolEngineOpsUtils.h17230644editdlrm
Sorting.h5360644editdlrm
SortingUtils.h57220644editdlrm
SpectralOpsUtils.h31460644editdlrm
StridedRandomAccessor.h68470644editdlrm
TensorAdvancedIndexing.h30720644editdlrm
TensorCompare.h13330644editdlrm
TensorDimApply.h18320644editdlrm
TensorFactories.h33820644editdlrm
TensorIterator.h460644editdlrm
TensorIteratorDynamicCasting.h20250644editdlrm
TensorShape.h10490644editdlrm
TensorTransformations.h9380644editdlrm
TriangularOpsUtils.h20000644editdlrm
TypeProperties.h4960644editdlrm
UnaryOps.h44640644editdlrm
Unfold2d.h5510644editdlrm
Unfold3d.h8520644editdlrm
UnfoldBackward.h53980644editdlrm
UpSample.h135990644editdlrm
vol2col.h36420644editdlrm
Edit: /usr/local/lib64/python3.6/site-packages/torch/include/ATen/native/UpSample.h (13599B)
#pragma once #include #include #include #include /** * Note [compute_scales_value] * Note [area_pixel_compute_scale] * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Interpolate with scale_factor can have different behaviors * depending on the value of recompute_scale_factor: * * - With recompute_scale_factor = True (current default behavior): * the scale_factor, when provided by the user, are used to calculate * the output size. The input size and the computed output_size * are then used to infer new values for the scales which are * used in the interpolation. Because floating-point math is not exact, * this may be a different value from the user-supplied scales. * * - With recompute_scale_factor = False (which will be the default * behavior starting 1.5.0): * the behavior follows opencv logic, and the scales provided by * the user are the ones used in the interpolation calculations. * * If the scales are not provided or if they are provided but * recompute_scale_factor is set to True (default behavior), the scales * are computed from the input and the output size; * * * When the scales are inferred from the input and output sizes, * we view each pixel as an area, idx + 0.5 as its center index. * Here is an example formula in 1D case. * if align_corners: center of two corner pixel areas are preserved, * (0.5, 0.5) -> (0.5, 0.5), * (input_size - 0.5, 0.5) -> (output_size - 0.5) * scale = (input_size - 0.5 - 0.5) / (output_size - 0.5 - 0.5) * src_index + 0.5 - 0.5 = scale * (dst_index + 0.5 - 0.5) * if not align_corners: the whole range is scaled accordingly * scale = input_size / output_size * src_idx + 0.5 = scale * (dst_index + 0.5) */ namespace at { namespace native { namespace upsample { TORCH_API c10::SmallVector compute_output_size( c10::IntArrayRef input_size, // Full input tensor size. c10::optional output_size, c10::optional> scale_factors); inline c10::optional get_scale_value(c10::optional> scales, int idx) { if (!scales) { return nullopt; } return scales->at(idx); } } // namespace upsample using scale_t = c10::optional; using upsampling_nearest1d = void(*)(const Tensor& output, const Tensor& input, scale_t scales_w); using upsampling_nearest2d = void(*)(const Tensor& output, const Tensor& input, scale_t scales_h, scale_t scales_w); using upsampling_nearest3d = void(*)(const Tensor& output, const Tensor& input, scale_t scales_d, scale_t scales_h, scale_t scales_w); using upsampling_linear1d = void(*)(const Tensor& output, const Tensor& input, bool align_corners, scale_t scales_w); using upsampling_bilinear2d = void(*)(const Tensor& output, const Tensor& input, bool align_corners, scale_t scales_h, scale_t scales_w); using upsampling_trilinear3d = void(*)(const Tensor& output, const Tensor& input, bool align_corners, scale_t scales_d, scale_t scales_h, scale_t scales_w); using upsampling_bicubic2d = void(*)(const Tensor& output, const Tensor& input, bool align_corners, scale_t scales_h, scale_t scales_w); DECLARE_DISPATCH(upsampling_nearest1d, upsample_nearest1d_kernel); DECLARE_DISPATCH(upsampling_nearest2d, upsample_nearest2d_kernel); DECLARE_DISPATCH(upsampling_nearest3d, upsample_nearest3d_kernel); DECLARE_DISPATCH(upsampling_nearest1d, upsample_nearest1d_backward_kernel); DECLARE_DISPATCH(upsampling_nearest2d, upsample_nearest2d_backward_kernel); DECLARE_DISPATCH(upsampling_nearest3d, upsample_nearest3d_backward_kernel); DECLARE_DISPATCH(upsampling_linear1d, upsample_linear1d_kernel); DECLARE_DISPATCH(upsampling_bilinear2d, upsample_bilinear2d_kernel); DECLARE_DISPATCH(upsampling_trilinear3d, upsample_trilinear3d_kernel); DECLARE_DISPATCH(upsampling_linear1d, upsample_linear1d_backward_kernel); DECLARE_DISPATCH(upsampling_bilinear2d, upsample_bilinear2d_backward_kernel); DECLARE_DISPATCH(upsampling_trilinear3d, upsample_trilinear3d_backward_kernel); DECLARE_DISPATCH(upsampling_bicubic2d, upsample_bicubic2d_kernel); static C10_UNUSED std::array upsample_1d_common_check(IntArrayRef input_size, IntArrayRef output_size) { TORCH_CHECK( output_size.size() == 1, "It is expected output_size equals to 1, but got size ", output_size.size()); TORCH_CHECK( input_size.size() == 3, "It is expected input_size equals to 3, but got size ", input_size.size()); int64_t output_width = output_size[0]; int64_t nbatch = input_size[0]; int64_t channels = input_size[1]; int64_t input_width = input_size[2]; TORCH_CHECK( input_width > 0 && output_width > 0, "Input and output sizes should be greater than 0, but got input (W: ", input_width, ") and output (W: ", output_width, ")"); return {nbatch, channels, output_width}; } static C10_UNUSED std::array upsample_2d_common_check(IntArrayRef input_size, IntArrayRef output_size) { TORCH_CHECK( output_size.size() == 2, "It is expected output_size equals to 2, but got size ", output_size.size()); TORCH_CHECK( input_size.size() == 4, "It is expected input_size equals to 4, but got size ", input_size.size()); int64_t output_height = output_size[0]; int64_t output_width = output_size[1]; int64_t nbatch = input_size[0]; int64_t channels = input_size[1]; int64_t input_height = input_size[2]; int64_t input_width = input_size[3]; TORCH_CHECK( input_height > 0 && input_width > 0 && output_height > 0 && output_width > 0, "Input and output sizes should be greater than 0," " but got input (H: ", input_height, ", W: ", input_width, ") output (H: ", output_height, ", W: ", output_width, ")"); return {nbatch, channels, output_height, output_width}; } static C10_UNUSED std::array upsample_3d_common_check(IntArrayRef input_size, IntArrayRef output_size) { TORCH_CHECK( output_size.size() == 3, "It is expected output_size equals to 3, but got size ", output_size.size()); TORCH_CHECK( input_size.size() == 5, "It is expected input_size equals to 5, but got size ", input_size.size()); int64_t output_depth = output_size[0]; int64_t output_height = output_size[1]; int64_t output_width = output_size[2]; int64_t nbatch = input_size[0]; int64_t channels = input_size[1]; int64_t input_depth = input_size[2]; int64_t input_height = input_size[3]; int64_t input_width = input_size[4]; TORCH_CHECK( input_depth > 0 && input_height > 0 && input_width > 0 && output_depth > 0 && output_height > 0 && output_width > 0, "Input and output sizes should be greater than 0, but got input (D: ", input_depth, ", H: ", input_height, ", W: ", input_width, ") output (D: ", output_depth, ", H: ", output_height, ", W: ", output_width, ")"); return {nbatch, channels, output_depth, output_height, output_width}; } static inline void upsample_2d_shape_check( const Tensor& input, const Tensor& grad_output, int64_t nbatch, int64_t nchannels, int64_t input_height, int64_t input_width, int64_t output_height, int64_t output_width) { TORCH_CHECK( input_height > 0 && input_width > 0 && output_height > 0 && output_width > 0, "Input and output sizes should be greater than 0," " but got input (H: ", input_height, ", W: ", input_width, ") output (H: ", output_height, ", W: ", output_width, ")"); if (input.defined()) { // Allow for empty batch size but not other dimensions TORCH_CHECK( (input.numel() != 0 || (input.size(1) != 0 && input.size(2) != 0 && input.size(3) != 0) ) && input.dim() == 4, "Non-empty 4D data tensor expected but got a tensor with sizes ", input.sizes()); } else if (grad_output.defined()) { check_dim_size(grad_output, 4, 0, nbatch); check_dim_size(grad_output, 4, 1, nchannels); check_dim_size(grad_output, 4, 2, output_height); check_dim_size(grad_output, 4, 3, output_width); } } template static inline scalar_t compute_scales_value( const c10::optional scale, int64_t input_size, int64_t output_size) { // see Note [compute_scales_value] // FIXME: remove magic > 0 after we ensure no models were serialized with -1 defaults. return (scale.has_value() && scale.value() > 0.) ? static_cast(1.0 / scale.value()) : (static_cast(input_size) / output_size); } template static inline scalar_t area_pixel_compute_scale( int64_t input_size, int64_t output_size, bool align_corners, const c10::optional scale) { // see Note [area_pixel_compute_scale] if(align_corners){ if(output_size > 1) { return static_cast(input_size - 1) / (output_size - 1); } else { return static_cast(0); } } else{ return compute_scales_value(scale, input_size, output_size); } } template static inline scalar_t area_pixel_compute_source_index( scalar_t scale, int64_t dst_index, bool align_corners, bool cubic) { if (align_corners) { return scale * dst_index; } else { scalar_t src_idx = scale * (dst_index + 0.5) - 0.5; // [Note] Follow Opencv resize logic: // We allow negative src_idx here and later will use // dx = src_idx - floorf(src_idx) // to compute the "distance"(which affects weights). // For linear modes, weight distribution doesn't matter // for negative indices as they use 2 pixels to interpolate. // For example, [-1, 0], they both use pixel 0 value so it // doesn't affect if we bound the src_idx to 0 or not. // TODO: Our current linear mode impls use unbound indices // where we should and then remove this cubic flag. // This matters in cubic mode, as we might need [-1, 0, 1, 2] // to interpolate and the weights can be affected. return (!cubic && src_idx < 0) ? scalar_t(0) : src_idx; } } static inline int64_t nearest_neighbor_compute_source_index( const float scale, int64_t dst_index, int64_t input_size) { const int64_t src_index = std::min(static_cast(floorf(dst_index * scale)), input_size - 1); return src_index; } template static scalar_t upsample_get_value_bounded( scalar_t* data, int64_t width, int64_t height, int64_t x, int64_t y) { int64_t access_x = std::max(std::min(x, width - 1), static_cast(0)); int64_t access_y = std::max(std::min(y, height - 1), static_cast(0)); return data[access_y * width + access_x]; } template static void upsample_increment_value_bounded( scalar_t* data, int64_t width, int64_t height, int64_t x, int64_t y, scalar_t value) { int64_t access_x = std::max(std::min(x, width - 1), static_cast(0)); int64_t access_y = std::max(std::min(y, height - 1), static_cast(0)); data[access_y * width + access_x] += value; } // Based on // https://en.wikipedia.org/wiki/Bicubic_interpolation#Bicubic_convolution_algorithm template static inline scalar_t cubic_convolution1(scalar_t x, scalar_t A) { return ((A + 2) * x - (A + 3)) * x * x + 1; } template static inline scalar_t cubic_convolution2(scalar_t x, scalar_t A) { return ((A * x - 5 * A) * x + 8 * A) * x - 4 * A; } template static inline void get_cubic_upsample_coefficients( scalar_t coeffs[4], scalar_t t) { scalar_t A = -0.75; scalar_t x1 = t; coeffs[0] = cubic_convolution2(x1 + 1.0, A); coeffs[1] = cubic_convolution1(x1, A); // opposite coefficients scalar_t x2 = 1.0 - t; coeffs[2] = cubic_convolution1(x2, A); coeffs[3] = cubic_convolution2(x2 + 1.0, A); } template static inline scalar_t cubic_interp1d( scalar_t x0, scalar_t x1, scalar_t x2, scalar_t x3, scalar_t t) { scalar_t coeffs[4]; get_cubic_upsample_coefficients(coeffs, t); return x0 * coeffs[0] + x1 * coeffs[1] + x2 * coeffs[2] + x3 * coeffs[3]; } template static inline void compute_source_index_and_lambda( int64_t& input_index0, int64_t& input_index1, scalar_t& lambda0, scalar_t& lambda1, scalar_t ratio, int64_t output_index, int64_t input_size, int64_t output_size, bool align_corners) { if (output_size == input_size) { // scale_factor = 1, simply copy input_index0 = output_index; input_index1 = output_index; lambda0 = static_cast(1); lambda1 = static_cast(0); } else { const scalar_t real_input_index = area_pixel_compute_source_index( ratio, output_index, align_corners, /*cubic=*/false); input_index0 = static_cast(real_input_index); int64_t offset = (input_index0 < input_size - 1) ? 1 : 0; input_index1 = input_index0 + offset; lambda1 = real_input_index - input_index0; lambda0 = static_cast(1.) - lambda1; } } } // namespace native } // namespace at