Re: [go-nuts] Contracts and fused multiply add
On Sat, 15 Sep 2018 11:53:51 +0200 "Wojciech S. Czarnecki" wrote: > With CGG `for type` contracts now you can use constraint > that allows for any custom type of base float64 Ie. **precisely** castable to a base of float64, so substitute type T with base of float32 will be treated as float32 > // a, b, c are treated by the code as float64 Errata: // a, b, c are treated by the code as either float32 or float64 -- Wojciech S. Czarnecki << ^oo^ >> OHIR-RIPE -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [go-nuts] Contracts and fused multiply add
> On Sep 15, 2018, at 7:31 AM, Wojciech S. Czarnecki wrote: > > On Sat, 15 Sep 2018 06:36:35 -0500 > Robert Engels wrote: > >> Why do you need the for... > > Because 'for type' means 'contract' > Because CGG contracts are for each typeholder > and expressed in terms of already familiar types. > > Thats why right after `for type` you see `T`. > > `for type T = constraint` "execute the body". > > It just reads. > >> Keywords with dual meaning is never a good idea. > There always is some context to read within. > Not for standardized keywords like ‘for’. Just my opinion of your proposals, the syntax is very clumsy, and not intuitive. > See https://github.com/ohir/gonerics examples > and point where it could be confusing. > > I am also open for any other contrived examples > showing possible confusion. > > Note the contract placement rules as described, please. > > -- > Wojciech S. Czarnecki > << ^oo^ >> OHIR-RIPE > > -- > You received this message because you are subscribed to the Google Groups > "golang-nuts" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to golang-nuts+unsubscr...@googlegroups.com. > For more options, visit https://groups.google.com/d/optout. -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [go-nuts] Contracts and fused multiply add
Why do you need the for... Keywords with dual meaning is never a good idea. Sent from my iPhone > On Sep 15, 2018, at 4:53 AM, Wojciech S. Czarnecki wrote: > > On Wed, 12 Sep 2018 10:54:15 -0700 > jimmy frasche wrote: > >> because that misses cases like >> type Float float64 > > I am working on constraint examples for CGG. > [https://github.com/ohir/gonerics] (Appendix A) > > With CGG `for type` contracts now you can use constraint > that allows for any custom type of base float64 > > `for type T = float64() // T must be assignable to given base via a cast` > > so example func becomes: > > func maMustFMA(a, b, c type T) type T { > > for type T = float64() > > // Here yours Float match and > // a, b, c are treated by the code as float64 > //... > > } > > I assume that this is not enough for you to narrow > contract to 'FMA capable'. Or is it? > > (As by the https://github.com/golang/go/issues/25819 > comments, given float64 compiler should know). > > Is that true? If so, what kind of constraint > (in terms of Go type system) would fit your needs > in place of below "someConstraint". > > func maMustFMA(a, b, c type T) type T { > for type ( >T = float64() >T = someConstraint // > ) > // ... > } > > Thanks in advance for the answer > > -- > Wojciech S. Czarnecki > << ^oo^ >> OHIR-RIPE > > -- > You received this message because you are subscribed to the Google Groups > "golang-nuts" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to golang-nuts+unsubscr...@googlegroups.com. > For more options, visit https://groups.google.com/d/optout. -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [go-nuts] Contracts and fused multiply add
On Wed, 12 Sep 2018 10:54:15 -0700 jimmy frasche wrote: > because that misses cases like > type Float float64 I am working on constraint examples for CGG. [https://github.com/ohir/gonerics] (Appendix A) With CGG `for type` contracts now you can use constraint that allows for any custom type of base float64 `for type T = float64() // T must be assignable to given base via a cast` so example func becomes: func maMustFMA(a, b, c type T) type T { for type T = float64() // Here yours Float match and // a, b, c are treated by the code as float64 //... } I assume that this is not enough for you to narrow contract to 'FMA capable'. Or is it? (As by the https://github.com/golang/go/issues/25819 comments, given float64 compiler should know). Is that true? If so, what kind of constraint (in terms of Go type system) would fit your needs in place of below "someConstraint". func maMustFMA(a, b, c type T) type T { for type ( T = float64() T = someConstraint // ) // ... } Thanks in advance for the answer -- Wojciech S. Czarnecki << ^oo^ >> OHIR-RIPE -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [go-nuts] Contracts and fused multiply add
If the contract further specified that the type must be ordered without restricting it to just floating-point you could feature test var d T = 3 if d/2 != 1 { // T is floatX if unsafe.Sizeof(d) == 4 { // float32 } else { // float64 } } Similarly, you could test for unsigned with var z T if z - 1 > 0 { // T is uintX } else { // T is intX or floatX } In both cases you have to kick out the complex numbers. Combined you have a means of classifying the properties of the types that satisfy a basic ordered arithmetic contract without having to use reflection or unsafe. Not especially readable, but it could be pulled out into a generic predicate: contract Number(t T) { t - t < t } const ( Int = iota Uint Float ) func Kind(type T Number)(_ T) int { if T(3)/2 != 1 { return Float } else if T(0) - 1 > 0 { return Uint } return Int } With that you could write the must-FMA version as: func maMustFMA(type T Number)(a, b, c T) T { if Kind(a) == Float { return T(math.Fma(float64(a), float64(b), float64(c))) } return a*b + c } } On Wed, Sep 12, 2018 at 11:08 AM jimmy frasche wrote: > > On Wed, Sep 12, 2018 at 11:02 AM Ian Lance Taylor wrote: > > You could perhaps choose an implementation based on unsafe.Sizeof. > > But I agree that it's pretty ugly. > > Only if the contract were t * t + t < .1 > > Part of the construction was that it accepted more than just floating points. -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [go-nuts] Contracts and fused multiply add
On Wed, Sep 12, 2018 at 11:02 AM Ian Lance Taylor wrote: > You could perhaps choose an implementation based on unsafe.Sizeof. > But I agree that it's pretty ugly. Only if the contract were t * t + t < .1 Part of the construction was that it accepted more than just floating points. -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [go-nuts] Contracts and fused multiply add
On Wed, Sep 12, 2018 at 10:54 AM, jimmy frasche wrote: > > Given a platform that supports the fused multiply add (FMA) > instruction and the code: > > contract MA(t T) { > t * t + t > } > > func ma(type T MA)(a, b, c T) T { > return a*b + c > } > > Does the compiled-for-any-type version support the FMA optimization > when called with a floating-point type? I think that in practice it's going to be up to the compiler. The language spec permits but does not require using an FMA instruction for the expression `x*y + z`. Whether that specific expression appears in a contract is going to be irrelevant. If it appears in the body of the generic function, the compiler may or may not recognize it. > If I specifically want to not use the optimization when instantiated > with floats, can I do: > > func maNoFMA(type T MA)(a, b, c T) T { > return T(a*b) + c > } Yes, adding an explicit type conversion always disables the use of FMA, as explained in the language spec. Again, that is independent of whether the expression appears in the contract. > If I need it to use the guaranteed FMA intrinsic (see > https://github.com/golang/go/issues/25819 ) when instantiated with > floats, I can't do > > func maMustFMA(type T MA)(a, b, c T) T { > switch a.(type) { > case float32: > return T(math.Fma( > float64(a.(float32)), > float64(b.(float32)), > float64(c.(float32)), > )) > case float64: > return T(math.Fma(a.(float64), b.(float64), c.(float64))) > } > return a*b + c > } > > because that misses cases like > type Float float64 > so I have to use reflect which can't be dead-code eliminated during > specialization. You could perhaps choose an implementation based on unsafe.Sizeof. But I agree that it's pretty ugly. Ian -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
[go-nuts] Contracts and fused multiply add
Given a platform that supports the fused multiply add (FMA) instruction and the code: contract MA(t T) { t * t + t } func ma(type T MA)(a, b, c T) T { return a*b + c } Does the compiled-for-any-type version support the FMA optimization when called with a floating-point type? If not, does a specialized version, making the two different based on whether the compiler chooses to specialize the function? If I specifically want to not use the optimization when instantiated with floats, can I do: func maNoFMA(type T MA)(a, b, c T) T { return T(a*b) + c } If I need it to use the guaranteed FMA intrinsic (see https://github.com/golang/go/issues/25819 ) when instantiated with floats, I can't do func maMustFMA(type T MA)(a, b, c T) T { switch a.(type) { case float32: return T(math.Fma( float64(a.(float32)), float64(b.(float32)), float64(c.(float32)), )) case float64: return T(math.Fma(a.(float64), b.(float64), c.(float64))) } return a*b + c } because that misses cases like type Float float64 so I have to use reflect which can't be dead-code eliminated during specialization. I'm sure there are other cases where similar questions could be asked, but this seems like a good proxy for the whole class. -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.