How to resolve scalar last value needed

Hi all,
While compiling openacc code, i am getting following “Scalar last value needed after loop for *** at line ***”

void transform(uint32_t state[] {
   uint32_t a, b, c, d, e, f, g, h, t1, t2;

	a = state[0];
	b = state[1];
	c = state[2];
	d = state[3];
	e = state[4];
	f = state[5];
	g = state[6];
	h = state[7];

#pragma acc parallel loop
	for (i = 0; i < 64; ++i) {
		t1 = e + f + g; 
      t2 = a + b + c;
      h = g;
		g = f;
		f = e;
		e = d + t1;
		d = c;
		c = b;
		b = a;
		a = t1 + t2;
	}

	state[0] += a;
	state[1] += b;
	state[2] += c;
	state[3] += d;
	state[4] += e;
	state[5] += f;
	state[6] += g;
	state[7] += h;
}

I understand this warning is provoked because I’m using a scalar variable outside of a parallel region whose value is being set in within the parallel region.

I can use the “private” clause to have each loop to have it’s own copy of the scalar.

#pragma acc parallel loop private(a, b, c, d, e, f, g, h)

but the value will remain unchanged from it’s value before the loop.

How can I resolve this ?

Hi LeMoussel,

How can I resolve this ?

The code as written is not parallelizable. You can still off-load the code using the “serial” directive, but you’ll get wrong answers if you try to use parallel.

In some cases, you can promote a scalar from private to global (scalars are private by default) and then use an “atomic” directive to update the variable. However here, while you could atomically update “g” with “f”, you can’t guarantee that “f” wasn’t updated with a different value. In other words, “atomic” works when you need to update a globally shared variable that can be updated across multiple iteration of a loop, but here you also have dependencies within a single iteration so it would not help to solve this.

Sorry,
Mat