[CoreML EP] Add Sin and Cos unary ops (#28596)
### 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
- #28595 — Support bool Cast in ML Program *(prerequisite)*
- **#28596 — Add Sin and Cos unary ops** *(this PR — independent)*
- #28597 — Add Where and And builders *(depends on #28595)*
- #28598 — Add GatherND builder *(depends on #28595)*
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.
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>