Re: [rust-dev] OpenCL-style accessors, casts.

2013-07-16 Thread Jeaye
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.

2013-07-16 Thread Brendan Zabarauskas
 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.

2013-07-16 Thread Brendan Zabarauskas
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

2013-07-16 Thread Svetoslav Neykov
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

2013-07-16 Thread Thomas Daede
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

2013-07-16 Thread Felix S. Klock II

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

2013-07-16 Thread Graydon Hoare
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.

2013-07-16 Thread Jens Nockert
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