Fix OOB pointer in TensorAt for sub-byte packed types (#28973)
### Description
<!-- Describe your changes. -->
Reject sub-byte packed types with appropriate error message. The
TensorAt API returns a void*, it fundamentally cannot point to a
sub-byte element. The fix is to reject sub-byte types at the API
boundary, similar to how strings are rejected. Tests have been updated
to reflect the changes.
### Motivation and Context
<!-- - Why is this change required? What problem does it solve?
- If it fixes an open issue, please link to the issue here. -->
TensorAt computed pointer offsets using logical element indices but
Size() returns the byte size of the packed storage unit (1 byte for
Int4x2/UInt4x2 which holds 2 elements). This caused out-of-bounds
pointer returns when element indices exceeded the actual buffer size.
The API fundamentally cannot return a pointer to a sub-byte element, so
reject sub-byte packed types with an appropriate error message, similar
to how strings are already rejected.
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>