Re: [rust-dev] OpenCL-style accessors, casts.
This supports swizzling? If so, *very* cool (I've wanted swizzling in Rust for some time). J On 07/15/2013 09:27 PM, Jens Nockert wrote: Hello rust-dev! I implemented OpenCL-style[0] accessors for SIMD types in Rust[1], the code quality isn't near /merge-worthy yet, but I wanted some input. For some code-examples, go to https://github.com/jensnockert/rust/tree/simd/src/test/run-pass/simd-test and check it out, you should be able to get the idea of how they work. Note that I didn't add any actual syntax for vector types yet (since it would be highly controversial and I don't know what would be the best option), so I just added a simd!(name: T * n) syntax extension that declares a new type that maps down to a LLVM n * T. My preference for syntax right now would be simd!(n x T) if I can get that to parse, or simd!(T, ..n). And then you would declare a type with type f32x4 = simd(4 x f32); and it would magically work. Another option would be some variant of the [T, ..n] syntax used for fixed-length vectors. Introducing a new t, ty_simd_vec(t, uint), instead of using the current #[simd] struct { … }, is yet another thing that is controversial about the patch and this needs a bit of explanation of the problem with #[simd] struct { … }. To be able to make these accessors work, you unfortunately need to be able to generate anonymous types in the compiler, x.even for example (take the even-indexed elements of a vector) may be a type that is undeclared. And if you want to be able to pretty-print that, you need to be able to generate a type without a name, which makes #[simd] struct { … } impossible. You could just pre-declare all possible options up to 256-bit long, which probably would only be a hundred types or so, but would feel a bit silly. There are also other operations that could generate (possibly) unnamed types, like a == b, which should generate a i1-vector, or a shufflevector intrinsic that could generate vectors of any length. Ps. I didn't think of #[simd] (T, T, T, T) c. before implementing (sanxiyn gave me that idea), but I still think that is probably a worse idea than adding SIMD as an additional type with actual syntax. [0]: http://www.khronos.org/files/opencl-quick-reference-card.pdf, page 2, Vector Component Addressing [1]: https://github.com/jensnockert/rust/tree/simd ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] OpenCL-style accessors, casts.
Introducing a new t, ty_simd_vec(t, uint), instead of using the current #[simd] struct { … }, is yet another thing that is controversial about the patch This is indeed a shame because named fields are very nice for clean, self-documenting apis. Perhaps properties solve this, but I don't think there would be much will to add more features considering all the work that still has to be done (I could be wrong though). ~Brendan On 16/07/2013, at 2:27 PM, Jens Nockert j...@nockert.se wrote: Hello rust-dev! I implemented OpenCL-style[0] accessors for SIMD types in Rust[1], the code quality isn't near /merge-worthy yet, but I wanted some input. For some code-examples, go to https://github.com/jensnockert/rust/tree/simd/src/test/run-pass/simd-test and check it out, you should be able to get the idea of how they work. Note that I didn't add any actual syntax for vector types yet (since it would be highly controversial and I don't know what would be the best option), so I just added a simd!(name: T * n) syntax extension that declares a new type that maps down to a LLVM n * T. My preference for syntax right now would be simd!(n x T) if I can get that to parse, or simd!(T, ..n). And then you would declare a type with type f32x4 = simd(4 x f32); and it would magically work. Another option would be some variant of the [T, ..n] syntax used for fixed-length vectors. Introducing a new t, ty_simd_vec(t, uint), instead of using the current #[simd] struct { … }, is yet another thing that is controversial about the patch and this needs a bit of explanation of the problem with #[simd] struct { … }. To be able to make these accessors work, you unfortunately need to be able to generate anonymous types in the compiler, x.even for example (take the even-indexed elements of a vector) may be a type that is undeclared. And if you want to be able to pretty-print that, you need to be able to generate a type without a name, which makes #[simd] struct { … } impossible. You could just pre-declare all possible options up to 256-bit long, which probably would only be a hundred types or so, but would feel a bit silly. There are also other operations that could generate (possibly) unnamed types, like a == b, which should generate a i1-vector, or a shufflevector intrinsic that could generate vectors of any length. Ps. I didn't think of #[simd] (T, T, T, T) c. before implementing (sanxiyn gave me that idea), but I still think that is probably a worse idea than adding SIMD as an additional type with actual syntax. [0]: http://www.khronos.org/files/opencl-quick-reference-card.pdf, page 2, Vector Component Addressing [1]: https://github.com/jensnockert/rust/tree/simd ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] OpenCL-style accessors, casts.
I'm not saying that the shuffles would have to be generated using the field names - that would be near impossible. For example: ~~~ #[simd] struct RGB T { r: T, g: T, b: T, a: T } ~~~ Shuffling would still use the CL syntax: ~~~ let v2 = v.s3201 ~~~ I would be really interested to hear what sanxiyn had in mind for #[simd] when he added it. Relevant PRs with discussions: https://github.com/mozilla/rust/pull/5841 https://github.com/mozilla/rust/pull/6214 https://github.com/mozilla/rust/pull/7705 ~Brendan On 16/07/2013, at 9:06 PM, Jens Nockert j...@nockert.se wrote: On H.25/07/16, at 12:13, Brendan Zabarauskas bjz...@yahoo.com.au wrote: Introducing a new t, ty_simd_vec(t, uint), instead of using the current #[simd] struct { … }, is yet another thing that is controversial about the patch This is indeed a shame because named fields are very nice for clean, self-documenting apis. Perhaps properties solve this, but I don't think there would be much will to add more features considering all the work that still has to be done (I could be wrong though). While nice, I don't think this is a good idea. It leads to very complex shuffle-syntax, and makes intrinsics and anything else with a T1 (x T1) - T2 type signature (comparisons, non-bitwise casts) much harder to call and implement. It would also mean that all intrinsics would have to be generic. And that you need to pattern-match match in trans to generate shufflevector operations. Examples, ~~~ OpenCL shuffle let v2 = v.abgr; ~~~ Named property shuffle let v2 = match v1 { rgba { r:r, b:b, g:g, a:a } = rgba { r:a, g:b, b:g, a:r } }; ~~~ And that isn't even the degenerate case of wanting to replace the order of a subset of the elements of a u8x16-like type which succintly can be described in OpenCl-like syntax. ~~~ v1.s89 = v1.s98; // or for complex arithmetic let i0 = a * b; r.even = i0.even - i0.odd; r.odd = a.odd * b.even + a.even * b.odd; ~~~ And these I cannot write the named-property variants of on my phone, so you will have to imagine what they would look like. ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Rust on bare metal ARM - sample project
On 15.07. 13 23:37, Patrick Walton wrote: On 7/14/13 1:04 PM, Svetoslav Neykov wrote: .unsafe is not a normal block and doesn't return a value, can't be used as an expression. This made it impossible to wrap the unsafe casts from fixed memory locations to borrowed pointers in macros. Instead I had to use inline functions and assign the resulting value to a local function variable. This should not be the case. There may be a bug in the way macros interact with unsafe checking. Do you have a test case by any chance? Yes, my bad. I double checked, there is no problem using unsafe as an expression or wrapping it inside of a macro. The real problem, turns out, is that the macro can't be used as an expression unless wrapped inside parentheses. GPIOD!().MODER //doesn't compile (error: unexpected token: `.`) (GPIOD!()).MODER //OK Svetoslav. ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Rust on bare metal ARM - sample project
On Sun, Jul 14, 2013 at 3:04 PM, Svetoslav Neykov svetos...@neykov.name wrote: Hello, My interest in Rust is from the point of view of an embedded microcontrollers running bare metal programs with no underlying OS. I decided to explore what the language offers in that space by creating an actual running program. For the target I used STM32F4Discovery board since it has an ARM CPU which is already supported by the compiler. What is special about this board with comparison to the Android port is that it has only 192K internal memory (no SDRAM) and no MMU. You can find the project at https://github.com/neykov/armboot. For the first step I chose the fastest approach possible – to generate an intermediate .ll, convert it to assembler and compile it with the gcc cross-compiler for the target (arm-none-eabi). One change was required to the compiler to skip the generation of function prologue for split stacks (see https://raw.github.com/neykov/armboot/master/rustc.patch). This version supports only static memory allocation, though heap access (owned pointers) is easily implemented (i.e. use malloc/free linked to newlib). Zero.rs is used so no managed pointers and garbage collection. The generation of the executable file is automated. After generation the .ll file is corrected so it works with unpatched llvm 3.4 and the .note.rustc section is removed so it doesn’t take space on the target device. Major points from the effort: · I ported a basic C program to equivalent safe Rust program (see main.rs vs blinky.c). It is interesting because it uses an interrupt callback for the actual blinking logic. · The platform definitions were needed – like IO register locations and memory layout. I created a subset of them, mostly by hand, taking the output from rust-bindgen for the structures. All the #defines and enums had to be created as macros so as not to allocate actual memory on the device if declared as static (which I tried and ran out of memory J ). This is somewhat cumbersome since it requires adding “!()” but not a huge problem. · “unsafe” is not a normal block and doesn’t return a value, can’t be used as an expression. This made it impossible to wrap the unsafe casts from fixed memory locations to borrowed pointers in macros. Instead I had to use inline functions and assign the resulting value to a local function variable. · No “volatile” equivalent in Rust – currently all code is compiled with disabled optimizations so IO code is not optimized away. Another possible workaround is to use extern “C” functions to do the actual hardware communication. · I couldn’t move the platform code to a separate library since macros can’t be exported (I saw that this is still a work in progress according to #3114 so not a long term problem). · There were problems with the code comments in the original source files (i.e. see https://github.com/neykov/armboot/blob/master/sys/inc/stm32f4xx.h). I got compile-time errors because of the special symbol combinations in them which are reserved in Rust. · No core/std since I used zero.rs. As a future development I will look into adding support for the arm-none-eabi target by the Rust compiler and getting at least part of “core” working on the target device in memory constrained environment. Svetoslav ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev This is really exciting! I'm actually working on something very similar, but didn't get nearly as far as you - I made a post about it on the mailing list a month back: https://mail.mozilla.org/pipermail/rust-dev/2013-June/004538.html I started with the same approach as you, generating the LLVM bytecode intermediate, pushing it through the LLVM compiler externally, then using gcc-arm-embedded's linker combined with libopencm3. However, I also quickly ran into the issue of the runtime, and decided to start instead with slowly porting the standard library away from OS dependencies (made harder due to in being in flux at the moment). I have the exact same hardware as you do, so when I have more time next week I'll see if I can run your script. - Thomas ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Rust on bare metal ARM - sample project
On 16/07/2013 19:52, Svetoslav Neykov wrote: On 15.07.13 23:37, Patrick Walton wrote: On 7/14/13 1:04 PM, Svetoslav Neykov wrote: ·unsafe is not a normal block and doesn't return a value, can't be used as an expression. This made it impossible to wrap the unsafe casts from fixed memory locations to borrowed pointers in macros. Instead I had to use inline functions and assign the resulting value to a local function variable. This should not be the case. There may be a bug in the way macros interact with unsafe checking. Do you have a test case by any chance? Yes, my bad. I double checked, there is no problem using unsafe as an expression or wrapping it inside of a macro. The real problem, turns out, is that the macro can't be used as an expression unless wrapped inside parentheses. GPIOD!().MODER //doesn't compile (error: unexpected token: `.`) (GPIOD!()).MODER //OK Svetoslav. ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev Yes I believe this is filed under the following ticket: Syntax extensions (and macros) that start a line want to be a whole statement https://github.com/mozilla/rust/issues/5941 (I noted on that bug that we could probably provide a better error message here.) Cheers, -Felix -- irc: pnkfelix on irc.mozilla.org email: {fklock, pnkfelix}@mozilla.com ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
[rust-dev] perf metrics and ratchets
Hi, I've added some new machinery to the testing systems in rust and wanted to draw a little attention to them. At least this will all be true shortly when https://github.com/mozilla/rust/pull/7829 lands. They're (lightly) documented at the bottom of: https://github.com/mozilla/rust/wiki/Doc-unit-testing and https://github.com/mozilla/rust/wiki/Note-testsuite The point-form version is: - #[bench] tests can now save their results as json. run the testrunner with --save-metrics=foo.json - If you want to avoid regressing on something, use --ratchet-metrics=foo.json instead; it will save and reload with each run, and consider any regression beyond a given noise threshold to be a test-fail. (Removing, renaming, omitting or adding metrics does not cause failure. it emits a warning and assumes you meant to do it.) - If you configure with --ratchet-bench then all the crate #[bench] benchmarks will be ratcheted in your workspace. We will turn this on on the buildbot soon-ish. At that point, adding a #[bench] function will make it impervious to perf regressions, so add them regularly but also with some care and thought. - If you're on a particularly noisy machine, you can override the inferred noise thresholds with --ratchet-noise-percent=N - There are new compiletests in src/test/codegen. These consist of pairs of files, foo.rs and foo.cc, each containing a non-mangled extern C function 'test'. The runner will compile the rust one with rustc and the C++ one with clang, extract their LLVM bitcode, disassemble it and compare the sizes. The result is recorded in a metrics file and _ratcheted by default_. - The codegen tests also leave behind foo-extract.ll and foo-clang-extract.ll files, which are helpful for eyeballing problems in our codegen. Please populate the codegen directory liberally. All you need to do is write a function in rust and a function that does the same thing in C++. If you have any questions, or find none of it works for you and want help making it work, please let me know. I'll hopefully turn on --ratchet-bench and export the metrics files from the buildbot soon. -Graydon ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
[rust-dev] Fwd: OpenCL-style accessors, casts.
Begin forwarded message: From: Jens Nockert j...@nockert.se Subject: Re: [rust-dev] OpenCL-style accessors, casts. Date: 16 July 2013 14:36:34 CEST To: Brendan Zabarauskas bjz...@yahoo.com.au On 16 Jul 2013, at 14:07, Brendan Zabarauskas bjz...@yahoo.com.au wrote: I'm not saying that the shuffles would have to be generated using the field names - that would be near impossible. For example: ~~~ #[simd] struct RGB T { r: T, g: T, b: T, a: T } ~~~ Shuffling would still use the CL syntax: ~~~ let v2 = v.s3201 ~~~ But then they would not behave like structs at all anymore, and you would see someone do something silly like define Vertex { w:f32, x:f32, y:f32, z:f32 } and try to access .w and get the value for z. And it only solves a small part of the problem, what is the type of a componentwise (v1 == v2), where v1, v2 are RGBf32 ? Ps. Sorry bjz that you get duplicate messages, it was early and I replied only to you.___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev