`rustc_scalable_vector`
Supercedes #3268.
Introduces a new attribute, #[rustc_scalable_vector(N)], which can be used to define new scalable vector types, such as those in Arm's Scalable Vector Extension (SVE), or RISC-V's Vector Extension (RVV).
rustc_scalable_vector(N) is internal compiler infrastructure that will be used only in the standard library to introduce scalable vector types which can then be stabilised. Only the infrastructure to define these types are introduced in this RFC, not the types or intrinsics that use it.
This RFC has a dependency on #3729 as scalable vectors are necessarily non-const Sized.
There are some large unresolved questions in this RFC, the current purpose of the RFC is to indicate a intended direction for this work to justify an experimental implementation to help resolve those unresolved questions.
Thanks all for the feedback, I got a little bit busy after posting this, so I'll respond as soon as I can.
Thanks everyone for the feedback, I've pushed a bunch of changes:
Notable changes:
- f514a3ef7e9699d9065dd84c5b19a1e173d7b6c0 renames this from
repr(scalable)torustc_scalable_vector- I wasn't aware of objections to
repr(simd)and I don't have an especially strong preference as to what we call this, the framing that it was an extension ofrepr(simd)was largely syntactic and quite shallow, so I've changed it torustc_scalable_vector
- I wasn't aware of objections to
- 83d0b93580b97eb7879d411e45a3c490db654d7c clarifies which types are accepted with the type marker
- dcb29b4175bd13db4c07c8e7f0ea8f3a354d8e40 avoids partially introducing scalable vectors in the guide-level explanation
- 388170ada8c455c6b3d588603fedb0648b54ad40 is a significant change to how we explain scalable vectors and justify the manual specification of
N- As I said in https://github.com/rust-lang/rfcs/pull/3838#discussion_r2259897375, I'm still open to changing this, but I don't think it's trivial and think manually specifying
Nis likely to be okay, happy to hear if my justification of that point isn't convincing - Crucially, it adds ASCII diagrams, and every RFC is better with ASCII diagrams
- As I said in https://github.com/rust-lang/rfcs/pull/3838#discussion_r2259897375, I'm still open to changing this, but I don't think it's trivial and think manually specifying
- 16bb4ebaad14dcc681dd434552c67cad66e852a8 adds a bunch of restrictions to these types to avoid issues with
target_feature- I don't like these restrictions and I want to find a way to remove them, so I've made this change so that the RFC isn't just entirely infeasible, but I've got some ideas that I'd like to explore for how to fix the issues here
- 9466d266087ffe734326c2854a69bf10cc039e2a adds another possibility for how we might be able to avoid these restrictions
- ca4aa06f89eb725e76b258cd703b94e237b38549 mentions that these types ought to be considered FFI-safe
- 5011dc692f2a9315f0f17c952cd05f6ccdd51310 adds lots of prior art, reviewing the issues related to
repr(simd)andtarget_featureand their relevance to scalable vectors - 6186245a5f44f9d41852284c00cd9c066640936c relaxes some of the restrictions about these types' use in compound types following changes in LLVM and describes how tuples of vectors will be defined
- c6d836de9fca7b4e739478141ffd3a1643fd1ec9 clarifies how the ABI requirements of these types will impact function pointers
- 530378cf66ce504c386f61001c682dbf199bd4e6 clarifies how the ABI requirements of these types will impact dyn compatibility
Small changes:
- 2a7705a531d7fe4292b6cecfbadafd849750d323 adds asserts into the example of using scalable vectors
- 8709d8ca40eebf49a157f4e4d1bd1419bf1dc8e2 adds some missing words
- b96e2b7d7e0ca22f41676acaf1332f4d70574031 clarifies some of the ambiguous parts of the code example and what the intrinsics are doing
- 4123a3a2b2da690fe9732556923ac12e95969b16 fixes a typo
- e5b546c6aef456d4e9740f458cccc275d7beb8c6 removes trailing whitespaces
- 494da8afe28e4e8f3001ae92948281f7c51dd92a moves the warning about
prctlinto a subsection - 968ae3ed02e0bfa11db28378bbf8cf23e22d3928 removes an incorrect detail from our description of the "no action taken" alternative
- 96307808a391102f470ea95ebe350e75dab3d910 removes a reference to
repr(simd)that is no longer relevant
Hopefully these address many of the concerns raised so far. I don't expect it to address all of them, there are still big unresolved questions to be resolved. My intent with this is just to indicate the rough direction we plan to take so that I can justify an experimental implementation to try and find solutions to some of the issues raised.
Hello, I'm a student interested in the rust compiler. I'd like to ask how exactly one can write an sve intrinsic. Or how to write the following C language in rust: // #include <arm_sve.h>
// void vec_add(const float *a,const float *b,float *c,int n){ // for (int i=0; i<n; i+=svcntw()){ // svbool_t pg = svwhilelt_b32(i,n); // svfloat32_t va = svld1(pg,&a[i]); // svfloat32_t vb = svld1(pg,&b[i]); // svfloat32_t vc = svadd_f32_m(pg,va,vb); // svst1(pg,&c[i],vc); //} //}
#include <stdio.h> #include <stdlib.h> #include <arm_sve.h>
void vec_add(const float* a, const float* b, float* c, int n) { for (int i = 0; i < n; i += svcntw()) { svbool_t pg = svwhilelt_b32(i, n); svfloat32_t va = svld1(pg, &a[i]); svfloat32_t vb = svld1(pg, &b[i]); svfloat32_t vc = svadd_f32_m(pg, va, vb); svst1(pg, &c[i], vc); } }
void print_array(const char* name, const float* arr, int n) { printf("%s: [", name); for (int i = 0; i < n; ++i) { printf("%.1f", arr[i]); if (i < n - 1) printf(", "); } printf("]\n"); }
int main() { #ifdef __ARM_FEATURE_SVE printf("SVE is supported! \n"); printf("SVE vector length: %d floats (%d bits)\n", svcntw(), svcntw() * 32); #else printf("SVE not supported.\n"); return 1; #endif
const int n = 16; float a[n], b[n], c[n];
for (int i = 0; i < n; ++i) { a[i] = (float)i; b[i] = (float)(2 * i); }
printf("\nBefore vector addition:\n"); print_array("A", a, n); print_array("B", b, n);
vec_add(a, b, c, n);
printf("\nAfter vector addition:\n"); print_array("C = A+B", c, n);
int errors = 0; for (int i = 0; i < n; ++i) { if (c[i] ! = a[i] + b[i]) { printf("Error at index %d: expected %.1f, got %.1f\n", i, a[i] + b[i], c[i]); errors++; } }
if (errors == 0) { printf("\nAll results correct! \n"); } else { printf("\nFound %d errors! \n", errors); }
return 0; }