Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Layout of vector types #38

Closed
gnzlbg opened this issue Oct 12, 2018 · 5 comments
Closed

Layout of vector types #38

gnzlbg opened this issue Oct 12, 2018 · 5 comments
Labels
A-layout Topic: Related to data structure layout (`#[repr]`)

Comments

@gnzlbg
Copy link
Contributor

gnzlbg commented Oct 12, 2018

The layout of Rust vector types (e.g. core::arch::x86_64::__m128 and friends) is currently unspecified but we probably want to make it implementation defined. That requires the implementation to specify their layout in "unsafe-code-guidelines speak" so we might just as well do it here for the canonical implementation at least for the stable types on the tier 1 platforms (maybe there is a way to do this generally). Some things to consider:

  • In C, __m256 is only available when AVX is available such that its layout is always a 256-bit wide register.

  • In Rust, __m256 is always available, even when 256-bit or 128-bit wide registers are not available. That is, repr(C) and repr(Rust) vector types do not necessarily have the same layout.

  • The Rust function abi for vector types transparently handles this by passing vector types through memory, but the x64 SysV ABI passes them in registers (this leads to subtleties when using them in C FFI: repr(simd) is unsound in C FFI rust#53346).

@hanna-kruppe
Copy link

Quibbles:

  • Memory layout should be the same everywhere, only calling convention is different.
    • I am not quite certain about the order of elements in memory but worst case this should be determined by the architecture
  • There is no such thing as repr(C) and repr(Rust) variants of the same type

@gnzlbg
Copy link
Contributor Author

gnzlbg commented Oct 13, 2018

If we can treat __m128 and friends as bag of bits we just have to define their size and alignment and that's it. Doing it this way for the optional architecture specific vector types is trivial.

The RFC for vector types states that Simd<[T; N]> has the same layout as a [T; N] array, it should probably add: "with an implementation-defined alignment >= mem::align_of::<[T; N]>()".

I don't like to have two "kinds" of vector types, so maybe the layout of one can be specified as a function of the other (e.g. __m128 has the same layout as Simd<[f32; 4]>).

@avadacatavra avadacatavra added the A-layout Topic: Related to data structure layout (`#[repr]`) label Oct 24, 2018
@gnzlbg
Copy link
Contributor Author

gnzlbg commented Nov 18, 2018

@rkruppe what can we guarantee for repr(simd) types containing N elements of type T ?

I'd say that the size and alignment of the vector type are:

  • size: N * size_of::<T>()
  • alignment: implementation-defined function of N and T and greater-equal than align_of::<T>()
#[repr(simd)] struct i32x4(i32, i32, i32, i32);

assert_eq!(size_of::<i32x4>(), size_of::<[i32; 4]>());
assert_eq!(size_of::<i32x4>(), size_of::<(i32, i32, i32, i32)>());

(note: this specification would prevent an implementation from exposing two distinct repr(simd) vector types with the same number of Ts that differ in size or alignment).

I'd also say that the layout of elements within the vector is the same as that of [T; N] and an homogeneous tuple containing N elements of type T. Such that there is a a 1:1 correspondence between the indices of the vector, array, and tuple elements.

That is:

union U {
   vec: i32x4,
   tup: (i32, i32, i32, i32),
   arr: [i32; 4]
}

unsafe {
  let u = U { vec: i32x4(0, 1, 2, 3) };

  assert_eq!(u.vec.0, u.arr[0]);
  assert_eq!(u.vec.0, u.tup.0);
  // ... 
  assert_eq!(u.vec.3, u.arr[3]);
  assert_eq!(u.vec.3, u.tup.3);
}

@hanna-kruppe
Copy link

None of this seems particularly controversial to me, except guaranteeing anything related to tuples. That's blocked on deciding to guarantee anything about the layout of tuples, not really on anything vector-specific. In fact, the layout equivalence of vectors and tuples is interchangeable with defining the vector layout in the obvious way and deciding that homogeneous tuples won't get reordered.

@gnzlbg
Copy link
Contributor Author

gnzlbg commented Nov 18, 2018

Makes sense. I'll send a PR specifying all of this for arrays, and moving the tuple parts to unresolved questions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-layout Topic: Related to data structure layout (`#[repr]`)
Projects
None yet
Development

No branches or pull requests

4 participants