Ah, I think I know the problem. Consider these lines of code: delta = delta + d * bjmass * dt / (distance * d2); bodies.j.vel = bodies.j.vel + d * bimass * dt / (distance * d2);
The first line works. The second doesn't, in fact I spot this during the optimsation: /*proj*/(case 0 of 3)(delta<42938>) = (+<5971>[double] (/*proj*/(case 0 of 3)(delta<42938>), (*<5982>[double] ((*<5982>[double] (/*proj*/(case 0 of 3)(d<42940>), y<46182>)), y<46205>)))); If you decipher it, it says: delta . 0 = delta . 0 + d . 0 * y1 * y2 which is the first component of the delta assignment, where y1=bimass, y2 = dt/(distance* d2) This looks correct and I believe it works. However the second line looks like this: // parallel assignment /*proj*/(case 2 of 3)(/*proj*/(case 1 of 3)((unsafe_get<62015> (bodies<42960>, (_ctor_size<5709>[size] (_ctor_size<5709>[int] j<42936>)))))) = (+<5971>[double] (/*proj*/(case 2 of 3)(/*proj*/(case 1 of 3)((unsafe_get<62015> (bodies<42960>, (_ctor_size<5709>[size] (_ctor_size<5709>[int] j<42936>)))))), (*<5982>[double] ((*<5982>[double] (/*proj*/(case 2 of 3)(d<42940>), y<46286>)), y<46294>)))); this time for the third component (case 2) and the problem is apparent: unsafe_get<62015> (bodies<42960> on the LHS. The LHS expression is just being expanded. Which results in a value. It's doing a value get from the bodies array then slicing it with projections, but that's useless: assignment to a value doesn't work :) I will check but I am sure this problem only exists for carrays, that is arrays of type +T There should be no problem with proper Felix arrays, i.e. arrays of type T ^ N. The reason is for them, a . 1 = 3; is translated to (&a) . 1 <- 3 and the N-th projection of a pointer to an array is just pointer + N, i.e. another pointer. however carray is abstract, and is not translated to use the <- notation. But I'm not sure because in nbody the variable "bodies" is an array (not a carray). possibly the problem is here in array_class: fun apply [I in ints] (i:I, x:t) => get (x,i.size); fun get[I in ints] (x:t, i:I) = { assert i.size < x.len; return unsafe_get (x,i.size); } so basically a . i = 1 translates to i a = 1 // by reverse application apply(i,a) = 1 // what i a means get (a,i) = 1 // by apply method assert .. unsafe_get (a,i) // inline def of get So by history: originally Felix didn't allow arbitrary LHS in assignments. But then C bindings producing lvalues couldn't be used on the LHS: s.[i] = char "A" // not allowed so I just relaxed the rule, to allow arbitrary LHS. The grammar just says: //$ Assignment form. sassignexpr := sexpr sassignop sexpr =># "`(ast_assign ,_sr ,_2 ((Expr ,_sr ,_1) none) ,_3)"; //$ Assignment. sassignop:= "=" =># "'_set"; //$ Store at pointer. sassignop:= "<-" =># "'_pset"; //$ Short form val declaration. sassignop:= ":=" =># "'_init"; so it is left up to the desugaring routine to figure out what this means. And it gets it wrong :) -- john skaller skal...@users.sourceforge.net http://felix-lang.org ------------------------------------------------------------------------------ The Go Parallel Website, sponsored by Intel - in partnership with Geeknet, is your hub for all things parallel software development, from weekly thought leadership blogs to news, videos, case studies, tutorials, tech docs, whitepapers, evaluation guides, and opinion stories. Check out the most recent posts - join the conversation now. http://goparallel.sourceforge.net/ _______________________________________________ Felix-language mailing list Felix-language@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/felix-language