大阵列问题

时间:2011-05-09 10:20:50

标签: arrays fortran

我有一个代码,到目前为止工作正常,有300万个原子大小的静态数组。 出于实际原因,我现在必须使用1000万个原子大小的数组。起初,我的编译器不允许我这样做,但我设法找到了以下标志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

我添加了!HERE和!那里告诉你我在哪里打印元素4669671的x,y和zcoord ...

2 个答案:

答案 0 :(得分:2)

我不熟悉ifort,但我认为它有一个检查数组边界的选项。打开它。
变量更改它们的值而不实际为它们分配内容通常表示某些其他变量在其声明的边界之外被引用。

答案 1 :(得分:2)

除了“已杀死”之外,您是否收到任何错误消息?也许有边界检查内存使用量再次太大。大型阵列的一个常见问题是超出可用的堆栈空间...请参阅Stack overflow in Fortran 90。如何声明变量?是否所有整数至少有四个字节来保存这些大值?如果你覆盖超过这个代码块中绑定的数组的内存,它必须是从存储到这个块中的数组(v由@Jonathan Dursi,vpb,vpbb建议)......很明显,但你可以插入如果编译器选项边界检查仍然导致可执行文件太大,那么您自己的索引检查代码。在问题发生之前到之后执行的代码中,在每个数组赋值之前放置一个IF语句。