<!--
{
  "availability" : [
    "iOS: 13.0.0 -",
    "iPadOS: 13.0.0 -",
    "macCatalyst: 13.1.0 -",
    "macOS: 11.0.0 -",
    "tvOS: 13.0.0 -",
    "visionOS: 1.0.0 -"
  ],
  "documentType" : "symbol",
  "framework" : "Metal",
  "identifier" : "/documentation/Metal/MTLIndirectComputeCommand/concurrentDispatchThreadgroups(_:threadsPerThreadgroup:)",
  "metadataVersion" : "0.1.0",
  "role" : "Instance Method",
  "symbol" : {
    "kind" : "Instance Method",
    "modules" : [
      "Metal"
    ],
    "preciseIdentifier" : "c:objc(pl)MTLIndirectComputeCommand(im)concurrentDispatchThreadgroups:threadsPerThreadgroup:"
  },
  "title" : "concurrentDispatchThreadgroups(_:threadsPerThreadgroup:)"
}
-->

# concurrentDispatchThreadgroups(_:threadsPerThreadgroup:)

Encodes a compute command using a grid aligned to threadgroup boundaries.

```
func concurrentDispatchThreadgroups(_ threadgroupsPerGrid: MTLSize, threadsPerThreadgroup: MTLSize)
```

## Parameters

`threadgroupsPerGrid`

The number of threadgroups in the grid, in each dimension.

`threadsPerThreadgroup`

The number of threads in one threadgroup, in each dimension.

## Discussion

The command generated by this method is equivalent to calling [`dispatchThreadgroups(_:threadsPerThreadgroup:)`](/documentation/Metal/MTLComputeCommandEncoder/dispatchThreadgroups(_:threadsPerThreadgroup:)).

Compute commands encoded into an indirect command buffer don’t automatically serialize access to resources with other commands in the indirect command buffer. Use barriers to serialize access to resources within a range of commands. See [`setBarrier()`](/documentation/Metal/MTLIndirectComputeCommand/setBarrier()).

When you execute the commands in an indirect command buffer, the [`dispatchType`](/documentation/Metal/MTLComputeCommandEncoder/dispatchType) property of the compute command encoder determines whether the compute command encoder adds additional barriers. If [`dispatchType`](/documentation/Metal/MTLComputeCommandEncoder/dispatchType) is [`MTLDispatchType.serial`](/documentation/Metal/MTLDispatchType/serial), the compute command encoder adds a barrier before and after the range of commands. If [`dispatchType`](/documentation/Metal/MTLComputeCommandEncoder/dispatchType) is [`MTLDispatchType.concurrent`](/documentation/Metal/MTLDispatchType/concurrent), then the compute command encoder does nothing, and you are responsible for synchronizing access to resources.

---

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)