Большая проблема с массивом - PullRequest
4 голосов
/ 09 мая 2011

У меня есть код, который до сих пор работал нормально с 3 миллионами статических массивов размером с атом. По практическим соображениям мне нужно перейти к массивам размером 10 миллионов атомов. Сначала мой компилятор не позволял мне это делать, но мне удалось найти способ обойти следующие флаги ifort -mcmodel medium -shared-intel -traceback kubo.f. Это работает, но происходит нечто очень странное. Моя матрица содержит 11 609 198 элементов.

Я проверяю значение моих координат следующим образом (значение 4 669 671 - первый раз, когда происходит ошибка):

print *, x (4669671), y (4669671), zcoord (4669671)

, за которыми следуют несколько строк, где значения x, y и zcoord не изменены или что-либо еще. Затем я вхожу в цикл для этих 3 векторов, где значения x, y и zcoord будут использоваться, но не изменяться. Я снова печатаю 3 значения, и вдруг 3 значения меняются?!

Что-то мне не хватает для больших массивов?

РЕДАКТИРОВАТЬ: Здесь полный код (поскольку я не знаю, что такое состояние гонки, я не знаю, разрешено ли мне удалять некоторые части, чтобы сделать его более читабельным):

  open(1,FILE='fort.10')
  read(1,*)NAT1
  write(*,*)'Lecture de Nat1=',NAT1
  read(1,*) 
  do i=1,nsites
   read(1,*)parcon(i),x(i),y(i),zcoord(i)
  enddo
  print*, x(4663659),y(4663659),zcoord(4663659)
  print*, x(4663663),y(4663663),zcoord(4663663)
  !HERE
  print*, x(4669671),y(4669671),zcoord(4669671)
  print*, x(4673254),y(4673254),zcoord(4673254)
  iflag=0
  iflagg=0
  impurityCounter=0
  C4Counter=0
  do i=1,nsites                                                                                                   
    nvo=0
    if(i.le.(nsites-93998)) then                                                                                  
      jj=i-10000
      jjj=i+10000
      do j=jj,jjj,1
        if((j.gt.0).and.(j.le.(nsites-93998))) then                                                               
          dist=dsqrt((x(j)-x(i))**2+(y(j)-y(i))**2                                                                
 .                      +(zcoord(j)-zcoord(i))**2)                                                                
          if((dist.lt.(1.11*aCC))
 .             .and.(j.ne.i).and.(dist.gt.0.1)) then                                                              
             nvo=nvo+1
             v(i,nvo)=j
             if(i.eq.4663660) then
                !THERE
                print*, dist,j,x(j),y(j),zcoord(j)                                                                
             endif                                                                                                
          endif                                                                                                   
        endif                                                                                                     
      enddo
      jjjj=nsites-93998+1                                                                                         
      do j=jjjj,nsites,1
        dist=dsqrt((x(j)-x(i))**2+(y(j)-y(i))**2                                                                  
 .                 +(zcoord(j)-zcoord(i))**2)
        if((dist.lt.(1.11*aCC)).and.(j.ne.i).and.(dist.gt.0.1)) then                                              
          nvo=nvo+1
          v(i,nvo)=j                                                                                              
        endif                                                                                                     
      enddo                                                                                                       
    else 
      do j=1,nsites
        dist=dsqrt((x(j)-x(i))**2+(y(j)-y(i))**2                                                                  
 .                 +(zcoord(j)-zcoord(i))**2)
        if((dist.lt.(1.11*aCC)).and.(j.ne.i).and.(dist.gt.0.1)) then                                              
          nvo=nvo+1
          v(i,nvo)=j                                                                                              
        endif                                                                                                     
      enddo                                                                                                       
    endif
    if ((nvo.eq.2).AND.(parcon(i).eq.'C')) then                                                                   
      iflag=iflag+1                                                                                               
      vpb(iflag)=i                                                                                                
    endif                                                                                                                
    if((nvo.eq.1).AND.(parcon(i).eq.'C')) then                                                                    
      iflagg=iflagg+1                                                                                             
      vpbb(iflagg)=i                                                                                              
    endif
    !count the number of impurities
    if((nvo.eq.2).AND.(parcon(i).eq.'O1')) then                                                                   
      impurityCounter=impurityCounter+1                                                                           
      impurityVector(impurityCounter)=i                                                                           
    endif
    if((nvo.eq.2).AND.(parcon(i).eq.'O2')) then                                                                   
      impurityCounter=impurityCounter+1                                                                           
      impurityVector(impurityCounter)=i                                                                           
    endif
    !If nvo equals 4, there is a BAD counting!                                                                           
    if(nvo.eq.4) then
        print*, v(i,1)                                                                                            
        print*, v(i,2)                                                                                            
        print*, v(i,3)                                                                                            
        print*, v(i,4)
        print*, x(i), y(i)                                                                                        
    endif                                                                                                                
    if(nvo.eq.5) then
      C4Counter=C4Counter+1                                                                                       
      C4Vector(C4Counter)=i                                                                                       
    endif                                                                                                         
  enddo

Я добавил! ЗДЕСЬ и! ЗДЕСЬ, чтобы показать вам, где находятся два места, где я печатаю x, y и zcoord элемента 4669671 ...

Ответы [ 2 ]

2 голосов
/ 09 мая 2011

Вы получаете какое-либо сообщение об ошибке, кроме "kill"?Возможно с проверкой границ использование памяти снова слишком велико.Распространенной проблемой с большими массивами является превышение доступного пространства стека ... см. Переполнение стека в Fortran 90 .Как объявлены переменные?Все ли целые числа по крайней мере четыре байта для хранения этих больших значений?Если вы перезаписываете память из-за превышения массива, связанного в этом блоке кода, она должна быть из памяти в массив в этом блоке (v, как предложено @Jonathan Dursi, vpb, vpbb) ... очевидно, но вы можете вставитьваш собственный код проверки индекса, если проверка параметров компилятора все еще приводит к получению слишком большого исполняемого файла.Поместите оператор IF перед каждым назначением массива в коде, который выполняется от до до после возникновения проблемы.

2 голосов
/ 09 мая 2011

Я не знаком с ifort, но я предполагаю, что у него есть опция для проверки границ массива.Включите его.
Переменные, изменяющие свое значение без фактического присвоения им чего-либо, часто являются признаком того, что на какую-то другую переменную ссылаются вне ее объявленных границ.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...