<!--
{
  "availability" : [
    "iOS: 27.0.0 -",
    "iPadOS: 27.0.0 -",
    "tvOS: 27.0.0 -",
    "visionOS: 27.0.0 -",
    "watchOS: 27.0.0 -"
  ],
  "documentType" : "symbol",
  "framework" : "CoreAI",
  "identifier" : "/documentation/CoreAI/NDArrayDescriptor/preferredStrides",
  "metadataVersion" : "0.1.0",
  "role" : "Instance Property",
  "symbol" : {
    "kind" : "Instance Property",
    "modules" : [
      "Core AI"
    ],
    "preciseIdentifier" : "s:13CoreAIRuntime17NDArrayDescriptorV16preferredStridesSaySiGvp"
  },
  "title" : "preferredStrides"
}
-->

# preferredStrides

The strides that avoid data layout transformations during inference.

```
var preferredStrides: [Int] { get }
```

## Discussion

During the specialization of an [`AIModel`](/documentation/CoreAI/AIModel), a preferred memory layout for a given ndArray value may be set depending on structure of the model
and which compute units it is specialized for. In some cases, this can result in a non-contiguous layout being preferred/required by the backing compute.
In such case, you are still able to provide `InferenceFunction.run` normal contiguous ndArray values, however it may incur a copy
to the preferred layout. As such, this property provides an opportunity for you to optimize performance by creating your source ndArray value with the
preferred striding and avoiding that copy.

> Note: Constructing an ndArray with these preferred strides may result in a non-contiguous layout. In such case calling
> `ndArrayView.contiguousElements` on a view of the ndArray will return `nil`.
> If you choose to use the preferred strides, you must read/write the resulting ndArray by dynamically respecting whatever strides are returned:

```swift
guard case .ndArray(let inputDescriptor) = inferenceFunctionDescriptor.inputDescriptor(of: "input") else {
  throw UnexpectedInferenceValueType()
}
let preferredStrides = inputDescriptor.preferredStrides
var ndArray = NDArray(shape: [theShape], scalarType: .float32, strides: preferredStrides)
var view = ndArray.mutableView(as: Float.self)
if let contiguousElements = view.contiguousElements {
  // The preferred strides were a normal contiguous layout
} else {
  // The preferred strides were non-contiguous
  view.withUnsafeMutablePointer { data, shape, strides in
    ... logic which respects whatever strides were preferred ...
  }
}
```

> Note: Accessing this property on a descriptor for which `hasDynamicShape` is true, is a programming error.
> If the descriptor has a dynamic shape, you must first call `resolvingDynamicDimensions` to provide a concrete size for each dimension.

---

Copyright &copy; 2026 Apple Inc. All rights reserved. | [Terms of Use](https://www.apple.com/legal/internet-services/terms/site.html) | [Privacy Policy](https://www.apple.com/privacy/privacy-policy)