In Openacc, warning: Accelerator restriction: induction variable live-out from loop: i

Viewed 35

May I know how to use the variable i in the first loop as the addend in the second loop? And moreover, I want to ask if I should use update and whether I should use present($var) to tell compiler the i is already in device.

  #include<iostream>

  #include<openacc.h>

  #define N 10

  using namespace std;
  int main(){

    int a[N];

    int i=0;

    #pragma acc data copyin(N) copy(a[:N],i)
 {
    
    #pragma acc parallel loop present(i)

    for(;i<N;i++){
         
            a[i]=i;
        }

        #pragma acc parallel loop //data reduction(a[0:N])
 
        for(int j=0;j<N;j++){
        
            a[j]=j+**i**;//here I would like here i=10 as addend 

    }

 }

  cout<<"a[N]"<<a[N-1]<<endl;


}

The result is : `main: 13, Generating copy(i,a[:]) [if not already present] 21, Generating present(i) Generating NVIDIA GPU code 21, #pragma acc loop seq 23, Accelerator restriction: induction variable live-out from loop: i 24, Accelerator restriction: induction variable live-out from loop: i Generating NVIDIA GPU code 26, #pragma acc loop gang /* blockIdx.x */

$ ./teste

a[N]9

i 10

But if I changed the directive

#pragma acc data copyin(N) copy(a[:N],i)
{
  


   // int a[N];

   #pragma acc kernels
   {
   // #pragma acc parallel loop
    for(;i<N;i++){
         
            a[i]=i;
        }
  // #pragma acc parallel loop present(i)//data reduction(a[0:N])
        for(int j=0;j<N;j++){
        a[j]=j+i;

    }
   }
}

I got the result :

$ ./teste

a[N]19

i 10

Thanks in Advance

1 Answers

Scalars are firstprivate by default, so in the second compute region, you need to add "present(i)" to have the global device copy be used.

Though as Alan commented, taking the last value of i from the first loop seems unnecessary given it's equal to N. Also, the first loop can't be run in parallel given to get the last value, all previous iterations of the loop must be run in order, thus causing a dependency.

The second example works because both loops are within the same compute region and the compiler is scheduling them to run serially.

Related