tensorflow / tensorflow/tensorflow
Metal PluggableDevice: op coverage tracking toward CUDA parity
@Venkat6871 is already working on this.
Since Aug 27, 2026.
- Dominant language
- C++
- Stars
- 200k
- Forks
- 76.9k
- Avg merge
- 2d 3h
- Merged PRs (30d)
- 433
Description
Tracking issue for bringing the in-tree Metal PluggableDevice backend added in #126254 to parity with the CUDA op set.
Where things stand
| Ops registered for Metal | 116 |
Ops with a CUDA GPU kernel in tensorflow/core/kernels/ |
277 explicit, 534 counting macro registrations |
| Remaining in this list | 165 |
The 116 already in place cover a convolutional classifier end to end: Conv2D and its gradients, pooling, FusedBatchNorm v1 to v3 with gradients, activations, the softmax cross entropies, a broadcasting arithmetic and maths library with matching gradient ops, BatchMatMul, reductions, Slice, Pad, Split, Concat, the random initialisers, and the SGD, Adam, Momentum and RMSProp updates.
Method
Every op below is implemented against MPSGraph or a Metal compute shader and checked on device against a CPU reference before it is counted. Gradients are additionally checked against central finite differences, which is how the FusedBatchNormGrad batch-coupling terms and the four unary gradient formulas were validated.
Ops TensorFlow registers for DEVICE_DEFAULT in a form a pluggable device can actually use are excluded from this list, since the backend inherits them. Ops whose DEVICE_DEFAULT registration is an int32-in-host-memory special case, which is the pattern used for Sum, Slice, Pad, Fill and ZerosLike, are not excluded, because a float version on device is genuinely missing.
Also excluded as out of scope for a device backend: collectives and NCCL, dataset and iterator ops, TensorList and TensorArray, the CSR sparse matrix family, cuDNN-specific RNN entry points, and the FFT family.
Remaining
Convolution and pooling (24)
-
AvgPoolGrad -
Conv -
Conv3D -
Conv3DBackpropFilter -
Conv3DBackpropFilterV2 -
Conv3DBackpropInput -
Conv3DBackpropInputV2 -
DepthwiseConv2dNative -
DepthwiseConv2dNativeBackpropFilter -
DepthwiseConv2dNativeBackpropInput -
Dilation2D -
Dilation2DBackpropFilter -
Dilation2DBackpropInput -
ExtractImagePatches -
ExtractVolumePatches -
LRN -
LRNGrad -
MaxPoolGradGrad -
MaxPoolGradGradV2 -
MaxPoolGradGradWithArgmax -
MaxPoolGradV2 -
MaxPoolGradWithArgmax -
MaxPoolV2 -
MaxPoolWithArgmax
Image (19)
-
AdjustContrast -
AdjustContrastv2 -
AdjustHue -
AdjustSaturation -
CropAndResize -
CropAndResizeGradBoxes -
CropAndResizeGradImage -
GenerateBoundingBoxProposals -
HSVToRGB -
ImageProjectiveTransformV2 -
ImageProjectiveTransformV3 -
NonMaxSuppressionV2 -
NonMaxSuppressionV3 -
NonMaxSuppressionV4 -
RGBToHSV -
ResizeBilinear -
ResizeBilinearGrad -
ResizeNearestNeighbor -
ResizeNearestNeighborGrad
Indexing and shape (45)
-
BatchMatrixBandPart -
BatchMatrixDiag -
BatchMatrixDiagPart -
BatchMatrixSetDiag -
BatchMatrixTriangularSolve -
BatchToSpace -
BatchToSpaceND -
DepthToSpace -
Diag -
DiagPart -
DynamicPartition -
DynamicStitch -
InTopK -
InTopKV2 -
LowerBound -
MatrixBandPart -
MatrixDiag -
MatrixDiagPart -
MatrixDiagPartV2 -
MatrixDiagPartV3 -
MatrixDiagV2 -
MatrixDiagV3 -
MatrixSetDiag -
MatrixSetDiagV2 -
MatrixSetDiagV3 -
MirrorPadGrad -
OneHot -
ParallelDynamicStitch -
ResourceGather -
ResourceGatherNd -
ResourceScatterUpdate -
Reverse -
ReverseSequence -
Roll -
SpaceToBatch -
SpaceToBatchND -
SpaceToDepth -
StridedSlice -
StridedSliceGrad -
TileGrad -
TopK -
TopKV2 -
Unique -
UniqueWithCounts -
UpperBound
Reduction and scan (8)
-
Bucketize -
Cumprod -
Cumsum -
CumulativeLogsumexp -
DenseBincount -
EuclideanNorm -
HistogramFixedWidth -
L2Loss
Elementwise and comparison (9)
-
ApproximateEqual -
CheckNumerics -
CheckNumericsV2 -
ClipByValue -
Conj -
ConjugateTranspose -
Cross -
LinSpace -
PopulationCount
Normalisation (2)
-
BatchNormWithGlobalNormalization -
BatchNormWithGlobalNormalizationGrad
Recurrent (10)
-
BlockLSTM -
BlockLSTMGrad -
BlockLSTMGradV2 -
BlockLSTMV2 -
CTCLoss -
CTCLossV2 -
GRUBlockCell -
GRUBlockCellGrad -
LSTMBlockCell -
LSTMBlockCellGrad
Linear algebra (4)
-
Lu -
MatrixTriangularSolve -
Qr -
SelfAdjointEigV2
Random (8)
-
Multinomial -
ParameterizedTruncatedNormal -
RandomGamma -
RandomUniformInt -
StatelessMultinomial -
StatelessParameterizedTruncatedNormal -
StatelessRandomGammaV2 -
StatelessRandomGammaV3
Quantisation (11)
-
FakeQuantWithMinMaxArgs -
FakeQuantWithMinMaxArgsGradient -
FakeQuantWithMinMaxVars -
FakeQuantWithMinMaxVarsGradient -
FakeQuantWithMinMaxVarsPerChannel -
FakeQuantWithMinMaxVarsPerChannelGradient -
QuantizeAndDequantize -
QuantizeAndDequantizeV2 -
QuantizeAndDequantizeV3 -
QuantizeAndDequantizeV4 -
QuantizeAndDequantizeV4Grad
Misc (25)
-
ApproxTopK -
BatchFFT -
BatchFFT2D -
BatchFFT3D -
BatchIFFT -
BatchIFFT2D -
BatchIFFT3D -
BiasAddV1 -
FFT -
FFT2D -
FFT3D -
FFTND -
IFFT -
IFFT2D -
IFFT3D -
IFFTND -
IRFFT -
IRFFT2D -
IRFFT3D -
IRFFTND -
ParallelConcat -
RFFT -
RFFT2D -
RFFT3D -
RFFTND
Related: #126254 adds the backend. #126275 fixes an unrelated llvm-raw patch failure that currently blocks bazel build on a clean checkout.
Drafted with assistance from Claude Opus 5.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.