Гфортран и Ифорт дают разные результаты - PullRequest
0 голосов
/ 12 июня 2018

Я делаю небольшой код, который будет читать числа из 2.txt, который представляет собой набор случайных действительных чисел, сохранять его в массиве 2d и передавать информацию в подпрограмму.В подпрограмме я назначаю определенное измерение этого массива другой матрице, чтобы сохранить его для будущих вычислений.

   implicit none
   double precision, allocatable :: x1(:,:)
   integer :: nstep, nheatoms, k, i, j
   open(unit=999,file="2.txt",status="old")

   nstep = 5
   nheatoms = 2

   allocate(x1(3,nheatoms))
   do k = 1, nstep
   do i = 1, 3
   do j = 1, nheatoms
   read(999,*) x1(i,j)
   end do
   read(999,*)
   end do
   call diffusion(nstep,nheatoms,x1)
   end do

   stop
   end

  subroutine diffusion(nstep,nheatoms,qhecent)
  implicit none
  integer, intent (in) :: nheatoms, nstep
  double precision :: qhecent(3,nheatoms)
  integer :: j
  double precision, allocatable  :: qhestep(:,:)
  integer :: nstepdiff, ncross
  integer, save :: l = 0
  double precision :: diff

  l = l + 1
   allocate(qhestep(nstep,nheatoms))
  do j = 1, nheatoms
  qhestep(l,j) = qhecent(3,j)
  end do

  if (l .gt. 1) then
  do j = 1, nheatoms
  write(*,*)qhestep(l,j), qhestep(l-1,j)
  end do
  end if
  end subroutine

Файл 2.txt выглядит следующим образом:

1.0
2.1

3.2
-1.1

-2.2
-3.3

5.0
3.5

4.4
1.9

2.1
1.5

6.0
3.5

4.4
1.9

2.8
2.5

6.0
3.5

4.4
1.9

2.1
3.2

6.0
3.5

4.4
1.9

-4.3
7.9

Теперь, если я скомпилирую с gfortran, большую часть времени я получаю вывод:

   2.1000000000000001       -2.2000000000000002     
   1.5000000000000000       -3.2999999999999998     
   2.7999999999999998        2.1000000000000001     
   2.5000000000000000        1.5000000000000000     
   2.1000000000000001        2.7999999999999998     
   3.2000000000000002        2.5000000000000000     
  -4.2999999999999998        2.1000000000000001     
   7.9000000000000004        3.2000000000000002  

, что ожидается.Но если я запускаю код несколько раз, в выводе появляется неизвестное число, например, например:

   2.1000000000000001       -2.2000000000000002     
   1.5000000000000000       -3.2999999999999998     
   2.7999999999999998        1.2882297539194267E-231

   2.5000000000000000        0.0000000000000000     
   2.1000000000000001        2.7999999999999998     
   3.2000000000000002        2.5000000000000000     
  -4.2999999999999998        2.1000000000000001     
   7.9000000000000004        3.2000000000000002 

Если я скомпилирую с помощью ifort, то получу вывод с двумя нулями, что неверно.

   2.10000000000000       -2.20000000000000     
   1.50000000000000       -3.30000000000000     
   2.80000000000000       0.000000000000000E+000

   2.50000000000000       0.000000000000000E+000

   2.10000000000000        2.80000000000000     
   3.20000000000000        2.50000000000000     
  -4.30000000000000        2.10000000000000     
   7.90000000000000        3.20000000000000 

Я должен подчеркнуть, что компиляция ifort в большинстве случаев дает правильные результаты, как в случае с gfortran.Я нахожусь на Mac OS High Sierra.Заранее спасибо.

1 Ответ

0 голосов
/ 13 июня 2018

Оба компилятора должны выдавать результаты мусора, поскольку вы распределяете qhestep в диффузии для каждого цикла DO k.При выходе из диффузии qhestep освобождается, поэтому накопленная информация должна быть потеряна.То, что ifort возвращает один и тот же адрес кучи для qhestep при каждом вызове, вводит в заблуждение.

Чтобы решить эту проблему, следует использовать allocate (qhestep (nstep, nheatoms)) перед входом в цикл DO k, а затем передать массив накопления.в распространении вызовов.

То, что ifort дает ожидаемый результат, вызывает сожаление, поскольку скрывает существенную логическую ошибку.Каждый ALLOCATE в основном обеспечивает новую область памяти для массива.

Вы также не предоставляете тесты на ошибки при чтении файла.Я бы порекомендовал использовать iostat = для чтения, а также сообщать данные в том виде, в котором они читаются.

Таким образом, ваш подход дает неверный результат, который предоставляют оба компилятора.Предоставленные вами результаты ifort также ошибочны в некоторых случаях, но верны в других, что вводит в заблуждение.

...