Skip to content

[CoreML EP] Add Sin and Cos unary ops#28596

Draft
maxwbuckley wants to merge 2 commits into
microsoft:mainfrom
maxwbuckley:coreml-sin-cos
Draft

[CoreML EP] Add Sin and Cos unary ops#28596
maxwbuckley wants to merge 2 commits into
microsoft:mainfrom
maxwbuckley:coreml-sin-cos

Conversation

@maxwbuckley
Copy link
Copy Markdown
Contributor

@maxwbuckley maxwbuckley commented May 20, 2026

Summary

Lower ONNX Sin and Cos to the CoreML ML Program sin / cos elementwise ops
via the existing UnaryOpBuilder, registered in the op builder factory. Like
Erf / Round / Exp, these have no NeuralNetwork lowering
(UnaryFunctionLayerParams has no sin/cos), so IsOpSupportedImpl rejects them on
the NeuralNetwork format.

Why

Sin / Cos form the sinusoidal timestep embedding of diffusion UNets. Supporting
them keeps that prologue on CoreML instead of splitting the graph — a tiny
Stable-Diffusion UNet goes from 2 CoreML partitions → 1, zero graph breaks with
this change alone.

This PR is independent of the rest of the series (it touches only the unary
builder) and can be reviewed/merged in any order.

Tests (coreml_basic_test.cc)

  • SinCos_MLProgram — a Sin + Cos graph runs fully on CoreML and matches the CPU
    reference.
  • SinCosNeuralNetworkNotSupported — the same graph falls back to CPU on the
    NeuralNetwork format.

Doc: coreml_supported_mlprogram_ops.md lists Sin and Cos.

Series — CoreML EP coverage for transformer / diffusion graphs

Together with #28278 (scalar-Gather), the series takes BERT / GPT-2 / ViT /
diffusion-UNet graphs — tiny and full-size — from 2 CoreML partitions to 1, with
zero graph breaks.

Lower ONNX Sin and Cos to the CoreML ML Program `sin` / `cos` elementwise
ops via the existing UnaryOpBuilder, and register them in the op builder
factory. Like Erf/Round/Exp, these have no NeuralNetwork lowering
(UnaryFunctionLayerParams has no sin/cos), so IsOpSupportedImpl rejects
them on the NeuralNetwork format.

These appear in the timestep (sinusoidal position) embedding of diffusion
UNets; supporting them lets that prologue stay on CoreML instead of
splitting the graph into separate partitions.

Tests (coreml_basic_test.cc):
- SinCos_MLProgram: a Sin+Cos graph runs fully on CoreML and matches the
  CPU reference.
- SinCosNeuralNetworkNotSupported: the same graph falls back to CPU on the
  NeuralNetwork format.

Doc: coreml_supported_mlprogram_ops.md lists Sin and Cos.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
# Conflicts:
#	onnxruntime/core/providers/coreml/builders/impl/unary_op_builder.cc
#	onnxruntime/core/providers/coreml/builders/op_builder_factory.cc
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant