Thread overview
Squaring Arrays without Overlapping Array Error
Jul 07, 2015
jmh530
Jul 07, 2015
tcak
Jul 07, 2015
tcak
Jul 07, 2015
jmh530
Jul 07, 2015
jmh530
Jul 07, 2015
jmh530
July 07, 2015
If I call a function like

int[] square_array(int[] x)
{
	return x[] *= x[];
}

I get an error that there is an overlapping array in a vector operation. I guess this makes sense as the lhs and rhs are occupying the same memory. Nevertheless, I find it a little frustrating.

I tried two alternatives, one just adds a temporary duplicate array for the lhs x[] in the above, while the other uses a foreach loop. Both get correct results without errors, but also have their issues. Duplicating requires memory allocation, which makes it slower for small arrays. Foreach (ignoring parallelism or SIMD) tends to be slower for larger arrays, I take it due to compiler optimizations for vector operations.

Are there any other alternatives here?
July 07, 2015
On Tuesday, 7 July 2015 at 05:27:10 UTC, jmh530 wrote:
> If I call a function like
>
> int[] square_array(int[] x)
> {
> 	return x[] *= x[];
> }
>
> I get an error that there is an overlapping array in a vector operation. I guess this makes sense as the lhs and rhs are occupying the same memory. Nevertheless, I find it a little frustrating.
>
> I tried two alternatives, one just adds a temporary duplicate array for the lhs x[] in the above, while the other uses a foreach loop. Both get correct results without errors, but also have their issues. Duplicating requires memory allocation, which makes it slower for small arrays. Foreach (ignoring parallelism or SIMD) tends to be slower for larger arrays, I take it due to compiler optimizations for vector operations.
>
> Are there any other alternatives here?

I have never used arrays in that way before, though I don't get why you are writing return line in that way. Shouldn't it be like `return (x[] * x[]);` ?
July 07, 2015
On Tuesday, 7 July 2015 at 08:06:50 UTC, tcak wrote:
> On Tuesday, 7 July 2015 at 05:27:10 UTC, jmh530 wrote:
>> [...]
>
> I have never used arrays in that way before, though I don't get why you are writing return line in that way. Shouldn't it be like `return (x[] * x[]);` ?

But, yes, the result should be stored somewhere still. Since either you, or the compiler would be writing a loop for multiplication already, I would be writing by hand for this operation.
July 07, 2015
On Tuesday, 7 July 2015 at 08:06:50 UTC, tcak wrote:
>
> I have never used arrays in that way before, though I don't get why you are writing return line in that way. Shouldn't it be like `return (x[] * x[]);` ?


There's nothing fundamentally wrong with doing that in the return line. For instance, the one I duplicated the array on looks like

int[] square_array_dup(int[] x)
{
	auto y = x.dup;
	return y[] *= x[];
}

To get your way to work requires

int[] square_array(int[] x)
{
	int[] y;
	y.length = x.length;
	y[] = x[] * x[];
	return y;
}

which can be slower.

Anyway, the main reason I used x[] *= x[] was that the original code I had written was not in a function and was just

void main()
{
	int len = 10;
	auto x = len.iota.array;
	x[] *= x[];
}

Obviously, in this case, I can just do a map before putting it into an array, but then I got more interested in squaring arrays.
July 07, 2015
On 7/7/15 1:27 AM, jmh530 wrote:
> If I call a function like
>
> int[] square_array(int[] x)
> {
>      return x[] *= x[];
> }
>
> I get an error that there is an overlapping array in a vector operation.

Yeah, this seems like an unnecessary limitation for exact matching. In other words, if your destination array exactly matches one or more of the arguments, it should be fine. Where the overlapping starts causing problems is something like this:

x[1..$] *= x[0..$-1];

I would love to see this limitation fixed.

-Steve
July 07, 2015
On Tuesday, 7 July 2015 at 13:58:17 UTC, Steven Schveighoffer wrote:
> Yeah, this seems like an unnecessary limitation for exact matching. In other words, if your destination array exactly matches one or more of the arguments, it should be fine. Where the overlapping starts causing problems is something like this:
>
> x[1..$] *= x[0..$-1];
>
> I would love to see this limitation fixed.
>
> -Steve

Do you think I should file a bug report?
July 07, 2015
On 7/7/15 12:45 PM, jmh530 wrote:
> On Tuesday, 7 July 2015 at 13:58:17 UTC, Steven Schveighoffer wrote:
>> Yeah, this seems like an unnecessary limitation for exact matching. In
>> other words, if your destination array exactly matches one or more of
>> the arguments, it should be fine. Where the overlapping starts causing
>> problems is something like this:
>>
>> x[1..$] *= x[0..$-1];
>>
>> I would love to see this limitation fixed.
>
> Do you think I should file a bug report?

Sure, file as an enhancement.

-Steve
July 07, 2015
On Tuesday, 7 July 2015 at 17:05:21 UTC, Steven Schveighoffer wrote:
> Sure, file as an enhancement.
>
> -Steve

https://issues.dlang.org/show_bug.cgi?id=14783