The C ABI is the easiest place to integrate with foreign runtimes and custom allocators.
The C++ layer is the easiest place to express typed packed workflows, tensor slicing, and allocator-aware ownership.
aligned_allocator defaults to 64-byte alignment for owned containers, but unaligned caller inputs are still valid for the kernels that accept raw pointers or views.
If you override result types away from the scalar defaults, document that choice carefully because it can change both performance and numerical policy.