UH-OH

It looks like you don’t have access to that feature yet

Contact sales to get upgraded to the full DevStudio experience.

UH-OH

It looks like you don't have access to that feature yet.

Chimera Compute Library (CCL) API ReferenceImage ProcessingImage Resize

Image Resize

chimera::image::resize is a general-purpose tensor resize. It resizes each channel independently, supports nearest-neighbor and bilinear interpolation, and works on both OCM-resident and DDR-resident tensors. The DDR variants stream channels through OCM and can distribute the work across all cores. The API is provided by image.hpp (included via qil.h); the configuration enums live in image_resize_helpers.hpp.

Specialized overloads are selected at compile time from the ResizeMethod and the tensor locations, so the same call site dispatches to the best implementation for the shapes involved.

Resize Methods & Coordinate Transforms

File: /src/image_resize_helpers.hppLines 11–61
    /**
     * @brief Resize methods.
     *
     * NEAREST_NEIGHBORS: Nearest neighbor interpolation.
     * BILINEAR_INTERPOLATION: Bilinear interpolation.
     * BILINEAR_INTERPOLATION_MULTISTEP: Pyramid method using a series of bilinear interpolations. Downscales by 2 at a
     * time. Reduces aliasing for large downscaling.
     * BILINEAR_INTERPOLATION_HALF_PIXEL: Bilinear interpolation with half pixel offset. Deprecated in favor of using
     * ResizeMethod::BILINEAR_INTERPOLATION with CoordinateTranform::HALF_PIXEL
     * BILINEAR_INTERPOLATION_ASYMMETRIC: Bilinear interpolation without offset. Deprecated in favor of using
     * ResizeMethod::BILINEAR_INTERPOLATION with CoordinateTranform::ASYMMETRIC
     *
     */
    enum class ResizeMethod {
      NEAREST_NEIGHBORS = 0,
      BILINEAR_INTERPOLATION,
      BILINEAR_INTERPOLATION_MULTISTEP,
      BILINEAR_INTERPOLATION_HALF_PIXEL QUADRIC_DEPRECATED_FUNCTION(
        "Use BILINEAR_INTERPOLATION with CoordinateTransform mode HALF_PIXEL instead.", "2026-02-24", "26.04"),
      BILINEAR_INTERPOLATION_ASYMMETRIC QUADRIC_DEPRECATED_FUNCTION(
        "Use BILINEAR_INTERPOLATION with CoordinateTransform mode ASYMMETRIC instead.", "2026-02-24", "26.04"),
    };

    /**
     * @brief Coordinate transform methods.
     *
     * ASYMMETRIC: Directly use image indices for internal calculations.
     * HALF_PIXEL: Use half pixel offset to consider pixel values to be at the center of a pixel.
     *
     */
    enum class CoordinateTransform { ASYMMETRIC = 0, HALF_PIXEL, ALIGN_CORNERS };

    /**
     * @brief Internal rounding method to be used to calculate pixels for nearest neighbor interpolation.
     *
     * ROUND_PREFER_FLOOR: Round down when the decimal portion <= 0.5. Otherwise round up.
     * ROUND_PREFER_CEIL: Round down when the decimal poriton < 0.5. Otherwise round up.
     * FLOOR: Always take the floor.
     * CEIL: ALways take the ceiling.
     *
     */
    enum class NearestMode { ROUND_PREFER_FLOOR = 0, ROUND_PREFER_CEIL, FLOOR, CEIL };

    /**
     * @brief Rounding method to use for integer outputs of bilinear resize methods.
     *
     * ROUND: Round the final output using math::RoundMethod::towardsPositiveInfinity.
     * CAST: Mimic float to int casting.
     *
     */
    enum class IntRoundMethod { ROUND = 0, CAST };

The template parameters mirror the ONNX Resize attributes:

ParameterApplies toValuesDefault
resizeMethodallNEAREST_NEIGHBORS, BILINEAR_INTERPOLATIONBILINEAR_INTERPOLATION
coordinateTransformallASYMMETRIC, HALF_PIXEL, ALIGN_CORNERSHALF_PIXEL (bilinear), ASYMMETRIC (nearest)
nearestModeNEAREST_NEIGHBORS onlyROUND_PREFER_FLOOR, ROUND_PREFER_CEIL, FLOOR, CEILROUND_PREFER_FLOOR
intRoundMethodBILINEAR_INTERPOLATION onlyROUND, CASTROUND
multicoreModeDDR overloads onlySingle, AllSingle

Note: BILINEAR_INTERPOLATION_HALF_PIXEL and BILINEAR_INTERPOLATION_ASYMMETRIC are deprecated. Use BILINEAR_INTERPOLATION with the matching CoordinateTransform instead.

OCM → OCM Resize

Resizes a planar OCM tensor of shape (1, channels, height, width) into an OCM tensor of shape (1, channels, resized_height, resized_width). The allocator parameter defaults to EmptyType — no scratch OCM is required.

Bilinear interpolation:

File: /src/image.hppLines 2432–2462
    /**
     * @brief General purpose tensor resize.
     *
     * Input tensor shape must be of form (1, channels, height, width).
     * Output tensor shape must be of form (1, channels, resized_height, resized_width)
     * @tparam resizeMethod Selection of resize method.
     * @tparam coordinateTransform Selection of coordinate transform method.
     * @tparam nearestMode Selection of internal rounding method. Only applicable for NEAREST_NEIGHBORS.
     * @tparam intRoundMode Selection for output int rounding method. Only applicable for BILINEAR_INTERPOLATION.
     * @tparam OcmAllocatorType Type of ocm allocator.
     * @tparam OcmInputShape The shape of the input tensor.
     * @tparam OcmOutputShape The shape of the output tensor.
     * @param ocmInput The input tensor.
     * @param ocmOutput The output tensor.
     * @param ocmMemAlloc ocm allocator to be used locally.
     * @return void
     */
    template <ResizeMethod        resizeMethod        = ResizeMethod::BILINEAR_INTERPOLATION,
              CoordinateTransform coordinateTransform = CoordinateTransform::HALF_PIXEL,
              NearestMode         nearestMode         = NearestMode::ROUND_PREFER_FLOOR,
              IntRoundMethod      intRoundMethod      = IntRoundMethod::ROUND,
              typename OcmAllocatorType               = EmptyType,
              typename OcmInputShape,
              typename OcmOutputShape,
              std::enable_if_t<resizeMethod != ResizeMethod::BILINEAR_INTERPOLATION_MULTISTEP &&
                                 resizeMethod != ResizeMethod::NEAREST_NEIGHBORS &&
                                 OcmInputShape::location == TensorLocation::OCM,
                               int> = 0>
    INLINE void resize(OcmInputShape&          ocmInput,
                       OcmOutputShape&         ocmOutput,
                       const OcmAllocatorType& ocmMemAlloc = EmptyType()) {

With ResizeMethod::NEAREST_NEIGHBORS, a matching overload is selected automatically; it is identical except that coordinateTransform defaults to ASYMMETRIC.

Example:

OcmTensor<std::uint8_t, 1, 3, 224, 224> ocmIn;
OcmTensor<std::uint8_t, 1, 3, 112, 112> ocmOut;
ocmMem.allocate(ocmIn);
ocmMem.allocate(ocmOut);

memCpy(ddrIn, ocmIn);
image::resize<image::ResizeMethod::BILINEAR_INTERPOLATION, image::CoordinateTransform::HALF_PIXEL>(ocmIn, ocmOut);
memCpy(ocmOut, ddrOut);

DDR → DDR Resize

Resizes a DDR tensor of shape (batch, channels, height, width) into a DDR tensor of shape (batch, channels, resized_height, resized_width). Channels are streamed through a double-buffered OCM working set and resized on chip, so a single channel of input plus output must fit within reservedSize bytes of OCM (default: half of OCM). An OCM allocator is required.

File: /src/image.hppLines 2482–2515
    /**
     * @brief General purpose tensor resize for Ddr -> Ddr.
     *
     * Input tensor shape must be of form (batch, channels, height, width).
     * Output tensor shape must be of form (batch, channels, resized_height, resized_width)
     * @tparam resizeMethod Selection of resize method.
     * @tparam coordinateTransform Selection of coordinate transform method.
     * @tparam nearestMode Selection of internal rounding method. Only applicable for NEAREST_NEIGHBORS.
     * @tparam reservedSize Amount of reserved ocm storage that can be used in this function.
     * @tparam intRoundMode Selection for output int rounding method. Only applicable for BILINEAR_INTERPOLATION.
     * @tparam multicoreMode Selection for multicore processing mode.
     * @tparam numFracBits Number of fractional bits for fixed point bilinear operations.
     * @tparam OcmAllocatorType Type of ocm allocator.
     * @tparam DdrInputShape The Ddr region shape of the input tensor.
     * @tparam DdrOutputShape The Ddr region shape of the output tensor.
     * @param ddrInput The input tensor.
     * @param ddrOutput The output tensor.
     * @param ocmMemAlloc ocm allocator to be used locally.
     * @return void
     */
    template <ResizeMethod        resizeMethod        = ResizeMethod::BILINEAR_INTERPOLATION,
              CoordinateTransform coordinateTransform = CoordinateTransform::HALF_PIXEL,
              NearestMode         nearestMode         = NearestMode::ROUND_PREFER_FLOOR,
              std::int32_t        reservedSize        = ocm::ocmSizeBytes / 2,
              IntRoundMethod      intRoundMethod      = IntRoundMethod::ROUND,
              MultiCoreMode       multicoreMode       = MultiCoreMode::Single,
              typename OcmAllocatorType,
              typename DdrInputShape,
              typename DdrOutputShape,
              std::enable_if_t<resizeMethod != ResizeMethod::BILINEAR_INTERPOLATION_MULTISTEP &&
                                 resizeMethod != ResizeMethod::NEAREST_NEIGHBORS &&
                                 DdrInputShape::location == TensorLocation::DDR,
                               int> = 0>
    INLINE void resize(DdrInputShape& ddrInput, DdrOutputShape& ddrOutput, OcmAllocatorType& ocmMemAlloc) {

As with the OCM overload, ResizeMethod::NEAREST_NEIGHBORS selects a matching overload whose coordinateTransform defaults to ASYMMETRIC.

The DDR overloads also support multicore execution via the multicoreMode parameter. With MultiCoreMode::All, the batch * channels planes are divided evenly across the cores in the kernel group and each core resizes its share; a kGroupSync() is performed before returning. With MultiCoreMode::Single (the default), the calling core processes all channels.

Example (multicore, nearest neighbors):

MemAllocator ocmMem;
DdrInputShape  ddrInput(ddrInputPtr);
DdrOutputShape ddrOutput(ddrOutputPtr);

image::resize<image::ResizeMethod::NEAREST_NEIGHBORS,
              image::CoordinateTransform::HALF_PIXEL,
              image::NearestMode::ROUND_PREFER_FLOOR,
              ocm::ocmSizeBytes / 2,
              image::IntRoundMethod::CAST,
              MultiCoreMode::All>(ddrInput, ddrOutput, ocmMem);

Optimized Paths

The implementation selects an optimized kernel at compile time when the shapes and modes allow it (canOptimizeDownscale / canOptimizeUpscale in image_resize_helpers.hpp). No code changes are needed — the same resize call dispatches automatically.

PathConditions
Optimized downscaleBilinear + HALF_PIXEL, 1-byte element type (int8/uint8), each axis scaled by exactly 1×, 2×, or 4×. Uses packed flows instead of RAU gathers.
Optimized 2× upscale2× on both axes, 1-byte element type, bilinear + HALF_PIXEL or nearest neighbors with any transform except ALIGN_CORNERS. Streams tiles through flows and computes via neighbor exchange.
Optimized 4× upscale4× on both axes, 1-byte element type, bilinear + HALF_PIXEL, input larger than coreDim / 4 in at least one axis.
GeneralAll other shape/type/mode combinations. Processes a row of output at a time, gathering the 4 source pixels per output pixel through RAU.

The general bilinear path computes interpolation weights in fixed point (FixedPoint32<31>) and clamps source coordinates at image borders (border replication).

For resizing 3-channel images with fused color conversion, see resizeImage in Image Transformations.

Table of Contents

Sign in to your account

Don't have an account? Create an Account
By signing in, you are agreeing to our Terms of Use and Privacy Policy.

Develop.

Simulate.

Profile.

Collaborate.