Problem in initialization of large arrays

I want to test the optimization of do concurrent in NVFortran. I generated a vector dot product program using ChatGPT, and when n <= 10^7, the results for the first few elements are normal. However, when I set the array length to 10^8, there is an issue with the initialization of array y. The first few elements are all 100000000. Since integer*8 type is used, overflow is clearly not the issue. On the other hand, when using an array constructor expression for initialization yy, the results are normal. I used gfortran version 9.4 with the compilation command gfortran test.f90.

program optimization_example
    implicit none
    integer(kind=8), parameter :: n = 100000000
    integer(kind=8) :: x(n), y(n), z(n)
    integer(kind=8) :: i
    real(kind=8) :: t1,t2
    call cpu_time(t1)
    ! Initialize arrays
    call initialize_arrays(x, y, n)

    ! Compute z = x * y using loop unrolling and data locality
    ! Using DO CONCURRENT for parallel execution
    do concurrent(i = 1:n)
        z(i) = x(i) * y(i)
    end do

    ! Print a few results to check
    call cpu_time(t2)
    write(*,*) t2-t1
    print *, 'x=',x(1:10)
    print *, 'y=', y(1:10)
    print *, 'z=', z(1:10)

end program optimization_example

subroutine initialize_arrays(x, y, n)
    implicit none
    integer(kind=8) :: n
    integer(kind=8), dimension(n) :: x, y,yy
    integer(kind=8) :: i

    ! Initialize arrays with some values
    do i = 1, n
        x(i) = real(i)
        y(i) = real(n - i)
    end do
    yy=[(n-i, i=1,n)]
    print *, 'init_x=',x(1:10)
    print *, 'init_y=', y(1:10)
    print *, 'init_yy=', yy(1:10)
end subroutine initialize_arrays

The results are as follows:
init_y= 100000000 100000000 100000000 100000000 99999992 99999992 99999992 99999992 99999992 99999992
init_yy= 99999999 99999998 99999997 99999996 99999995 99999994 99999993 99999992 99999991 99999990

This is because you are using a real intermediate type when filling in the x and y arrays. In most compilers the default real type is 32 bits, with 6 (almost 7 actually) significant digits, while you are manipulating numbers with 8 digits.

And BTW this is not a dot product that is in the program, but an element by element product.

Conclusion: do not fully trust chatGPT and always double check the generated codes.

5 Likes