在MATLAB中使用glmnet-mex时的分割错误

在MATLAB中使用glmnet-mex时的分割错误,matlab,segmentation-fault,mex,Matlab,Segmentation Fault,Mex,从我的MATLAB代码中调用glmnet(从此处下载:)时,由于分段错误,我的工作一直受到影响。我调用glmnet例程数千次。我注意到问题发生的以下特点: 当我的输入矩阵的大小更大时,问题就更频繁了 我在单独的作业中使用高斯分布和泊松分布,并且我注意到在拟合泊松分布时问题更频繁(这通常需要更长的时间才能收敛,因此可能会在内部涉及更多的循环?) 由于没有关于这两个发行版的R版本出现分段错误的报告,我怀疑问题(可能是内存泄漏)可能在于mex接口,而不是核心glmnet Fortran代码,我将在下面

从我的MATLAB代码中调用glmnet(从此处下载:)时,由于分段错误,我的工作一直受到影响。我调用glmnet例程数千次。我注意到问题发生的以下特点:

  • 当我的输入矩阵的大小更大时,问题就更频繁了
  • 我在单独的作业中使用高斯分布和泊松分布,并且我注意到在拟合泊松分布时问题更频繁(这通常需要更长的时间才能收敛,因此可能会在内部涉及更多的循环?) 由于没有关于这两个发行版的R版本出现分段错误的报告,我怀疑问题(可能是内存泄漏)可能在于mex接口,而不是核心glmnet Fortran代码,我将在下面粘贴它。非常感谢您能深入了解内存泄漏可能发生的位置!为冗长的代码转储道歉
  • 谢谢

          subroutine mexFunction(nlhs, plhs, nrhs, prhs)
    C-----------------------------------------------------------------------
    
          mwpointer plhs(*), prhs(*)
          mwpointer mxCreateDoubleMatrix, mxGetPr, mxCreateNumericArray
          integer nlhs, nrhs
          mwsize mxGetM, mxGetN, mxGetNzmax
          integer mxIsNumeric
          integer mxIsSparse
          
    C-----------------------------------------------------------------------
    
    C     Input
          real parm,flmin,thr, intr
          integer ka,no,ni,nr,nc,ne,nx,nlam,isd,maxit,kopt,isparse,nnz,jsd
          real, dimension (:), allocatable :: x,y,w,vp,ulam,cl,sr,xs,o,d,
         $     flog,a
          integer, dimension (:), allocatable :: ix,jx,jd,irs,jcs
    
          mwpointer pr
    
    C     Output
          integer lmu,nlp,jerr
          real dev0
          real, dimension (:), allocatable :: a0,ca,alm,dev,rsq
          integer, dimension (:), allocatable :: ia,nin
    
    C     Temporary      
          mwpointer temp_pr
          mwsize temp_m, temp_n, temp_nzmax, dims(3)
          integer task,i
    
    C     For internal parameters
          real fdev, devmax, eps, big, pmin, prec, exmx
          integer mnlam, mxit
          
    C     Check for proper number of arguments.
          if (nrhs .eq. 0) then
             task = -1;
          else
             temp_pr = mxGetPr(prhs(1))
             call getinteger(temp_pr,task,1)
          endif
    
    C     Get input
    
          if (task .eq. -1) then
             call get_int_parms(fdev,eps,big,mnlam,devmax,pmin,exmx)
             call get_bnorm(prec,mxit)
    
             plhs(1) = mxCreateDoubleMatrix(1,1,0)
             temp_pr = mxGetPr(plhs(1))
             call putreal(fdev,temp_pr,1)
    
             plhs(2) = mxCreateDoubleMatrix(1,1,0)
             temp_pr = mxGetPr(plhs(2))
             call putreal(devmax,temp_pr,1)
    
             plhs(3) = mxCreateDoubleMatrix(1,1,0)
             temp_pr = mxGetPr(plhs(3))
             call putreal(eps,temp_pr,1)
    
             plhs(4) = mxCreateDoubleMatrix(1,1,0)
             temp_pr = mxGetPr(plhs(4))
             call putreal(big,temp_pr,1)
    
             plhs(5) = mxCreateDoubleMatrix(1,1,0)
             temp_pr = mxGetPr(plhs(5))
             call putinteger(mnlam,temp_pr,1)
    
             plhs(6) = mxCreateDoubleMatrix(1,1,0)
             temp_pr = mxGetPr(plhs(6))
             call putreal(pmin,temp_pr,1)
    
             plhs(7) = mxCreateDoubleMatrix(1,1,0)
             temp_pr = mxGetPr(plhs(7))
             call putreal(exmx,temp_pr,1)
    
             plhs(8) = mxCreateDoubleMatrix(1,1,0)
             temp_pr = mxGetPr(plhs(8))
             call putreal(prec,temp_pr,1)
    
             plhs(9) = mxCreateDoubleMatrix(1,1,0)
             temp_pr = mxGetPr(plhs(9))
             call putinteger(mxit,temp_pr,1)
    
             return   
          endif 
          
          if (task .eq. 0) then
             temp_pr = mxGetPr(prhs(2))
             call getreal(temp_pr,fdev,1)
    
             temp_pr = mxGetPr(prhs(3))
             call getreal(temp_pr,devmax,1)
    
             temp_pr = mxGetPr(prhs(4))
             call getreal(temp_pr,eps,1)
    
             temp_pr = mxGetPr(prhs(5))
             call getreal(temp_pr,big,1)
    
             temp_pr = mxGetPr(prhs(6))
             call getinteger(temp_pr,mnlam,1)
    
             temp_pr = mxGetPr(prhs(7))
             call getreal(temp_pr,pmin,1)
    
             temp_pr = mxGetPr(prhs(8))
             call getreal(temp_pr,exmx,1)
    
             temp_pr = mxGetPr(prhs(9))
             call getreal(temp_pr,prec,1)
    
             temp_pr = mxGetPr(prhs(10))
             call getinteger(temp_pr,mxit,1)
    
             call chg_fract_dev(fdev)
             call chg_dev_max(devmax)
             call chg_min_flmin(eps)
             call chg_big(big)
             call chg_min_lambdas(mnlam)
             call chg_min_null_prob(pmin)
             call chg_max_exp(exmx)
             call chg_bnorm(prec, mxit)
    
             return
          endif
    
    c$$$  -----------------Gaussian--------------------  
    c$$$  ---input---   
          
          if (task .eq. 10 .or. task .eq. 11) then
             if (task .eq. 11) then
                temp_pr = mxGetPr(prhs(3))
                temp_m = mxGetM(prhs(3))
                no = temp_m
                temp_n = mxGetN(prhs(3))
                ni = temp_n
                allocate(x(1:no*ni))
                call getreal(temp_pr,x,no*ni)
                
             else
                temp_m = mxGetM(prhs(4))
                no = temp_m
    
                temp_pr = mxGetPr(prhs(3))
                temp_m = mxGetM(prhs(3))
                nnz = temp_m
                allocate(xs(1:nnz))
                call getreal(temp_pr,xs,nnz)
    
                temp_pr = mxGetPr(prhs(19))
                allocate(irs(1:nnz))
                call getinteger(temp_pr,irs,nnz) 
    
                temp_pr = mxGetPr(prhs(20))
                temp_n = mxGetM(prhs(20))
                ni = temp_n - 1
                allocate(jcs(1:(ni+1)))
                call getinteger(temp_pr,jcs,(ni+1)) 
             endif
    
             temp_pr = mxGetPr(prhs(2))
             call getreal(temp_pr,parm,1)
    
             temp_pr = mxGetPr(prhs(4))
             allocate(y(1:no))
             call getreal(temp_pr,y,no)
             
             temp_pr = mxGetPr(prhs(5))
             temp_m = mxGetM(prhs(5))
             temp_n = mxGetN(prhs(5))
             allocate(jd(temp_m*temp_n))
             call getinteger(temp_pr,jd,temp_m*temp_n)     
             
             temp_pr = mxGetPr(prhs(6))
             allocate(vp(1:ni))
             call getreal(temp_pr,vp,ni)
    
             temp_pr = mxGetPr(prhs(7))
             call getinteger(temp_pr,ne,1)
    
             temp_pr = mxGetPr(prhs(8))
             call getinteger(temp_pr,nx,1)
             
             temp_pr = mxGetPr(prhs(9))
             call getinteger(temp_pr,nlam,1)
    
             temp_pr = mxGetPr(prhs(10))
             call getreal(temp_pr,flmin,1)     
             
             temp_pr = mxGetPr(prhs(11))
             temp_m = mxGetM(prhs(11))
             temp_n = mxGetN(prhs(11))
             allocate(ulam(1:temp_m * temp_n))
             call getreal(temp_pr,ulam,temp_m * temp_n)
             
             temp_pr = mxGetPr(prhs(12))
             call getreal(temp_pr,thr,1)
             
             temp_pr = mxGetPr(prhs(13))
             call getinteger(temp_pr,isd,1)
    
             temp_pr = mxGetPr(prhs(14))
             allocate(w(1:no))
             call getreal(temp_pr,w,no)
    
             temp_pr = mxGetPr(prhs(15))
             call getinteger(temp_pr,ka,1)
    
             temp_pr = mxGetPr(prhs(16))
             allocate(cl(1:2*ni))
             call getreal(temp_pr,cl,2*ni)
    
             temp_pr = mxGetPr(prhs(17))
             call getinteger(temp_pr,intr,1)
    
             temp_pr = mxGetPr(prhs(18))
             call getinteger(temp_pr,maxit,1)       
    
    c$$$  ---prepare output---
    
             allocate(ia(1:nx))
             call zerointeger(ia,nx)
             allocate(nin(1:nlam))
             call zerointeger(nin,nlam)
             allocate(alm(1:nlam))
             call zeroreal(alm,nlam)
             allocate(a0(1:nlam))
             call zeroreal(a0,nlam)         
             allocate(ca(1:nx*nlam))
             call zeroreal(ca,nx*nlam)
             allocate(rsq(1:nlam))
             call zeroreal(rsq,nlam)
    
    
    c$$$  ---computation----
    
             if (task .eq. 11) then    
                call elnet(ka,parm,no,ni,x,y,w,jd,vp,cl,ne,nx,nlam,flmin,
         $           ulam,thr,isd,intr,maxit,lmu,a0,ca,ia,nin,rsq,alm,
         $           nlp,jerr)
             else
                call spelnet(ka,parm,no,ni,xs,jcs,irs,y,w,jd,vp,cl,ne,nx,
         $           nlam,flmin,ulam,thr,isd,intr,maxit,lmu,a0,ca,ia,nin,
         $           rsq,alm,nlp,jerr)
             endif
    
    c$$$  ----output-----
    
             plhs(1) = mxCreateDoubleMatrix(1,1,0)
             temp_pr = mxGetPr(plhs(1))
             call putinteger(lmu,temp_pr,1)
    
             plhs(4) = mxCreateDoubleMatrix(nx,1,0)
             temp_pr = mxGetPr(plhs(4))
             call putinteger(ia,temp_pr,nx)
             
             plhs(5) = mxCreateDoubleMatrix(lmu,1,0)
             temp_pr = mxGetPr(plhs(5))
             call putinteger(nin,temp_pr,lmu)
             
             plhs(7) = mxCreateDoubleMatrix(lmu,1,0)
             temp_pr = mxGetPr(plhs(7))
             call putreal(alm,temp_pr,lmu)
             
             plhs(8) = mxCreateDoubleMatrix(1,1,0)
             temp_pr = mxGetPr(plhs(8))
             call putinteger(nlp,temp_pr,1)
             
             plhs(9) = mxCreateDoubleMatrix(1,1,0)
             temp_pr = mxGetPr(plhs(9))
             call putinteger(jerr,temp_pr,1)
    
             plhs(2) = mxCreateDoubleMatrix(lmu,1,0)
             temp_pr = mxGetPr(plhs(2))
             call putreal(a0,temp_pr,lmu)   
             
             plhs(3) = mxCreateDoubleMatrix(nx,lmu,0)
             temp_pr = mxGetPr(plhs(3))
             call putreal(ca,temp_pr,nx*lmu)  
             
             plhs(6) = mxCreateDoubleMatrix(lmu,1,0)
             temp_pr = mxGetPr(plhs(6))
             call putreal(rsq,temp_pr,lmu)  
    
             deallocate(y)
             deallocate(jd)
             deallocate(vp)
             deallocate(ulam)
             deallocate(a0)
             deallocate(ca)
             deallocate(ia)
             deallocate(nin)
             deallocate(alm)
             deallocate(w)
             deallocate(rsq)
             deallocate(cl)
             
             if (task .eq. 11) then
                deallocate(x)
             else
                deallocate(xs)
                deallocate(irs)
                deallocate(jcs)  
             endif
             return
          endif      
    c$$$  --------------end of Gaussian---------------------------
    c$$$  ---------------Poisson--------------------------
    c$$$  ---input---   
          
          if (task .eq. 50 .or. task .eq. 51) then
             if (task .eq. 51) then
                temp_pr = mxGetPr(prhs(3))
                temp_m = mxGetM(prhs(3))
                no = temp_m
                temp_n = mxGetN(prhs(3))
                ni = temp_n
                allocate(x(1:no*ni))
                call getreal(temp_pr,x,no*ni)
                
             else
                temp_m = mxGetM(prhs(4))
                no = temp_m
    
                temp_pr = mxGetPr(prhs(3))
                temp_m = mxGetM(prhs(3))
                nnz = temp_m
                allocate(xs(1:nnz))
                call getreal(temp_pr,xs,nnz)
    
                temp_pr = mxGetPr(prhs(19))
                allocate(irs(1:nnz))
                call getinteger(temp_pr,irs,nnz) 
    
                temp_pr = mxGetPr(prhs(20))
                temp_n = mxGetM(prhs(20))
                ni = temp_n - 1
                allocate(jcs(1:(ni+1)))
                call getinteger(temp_pr,jcs,(ni+1)) 
             endif
    
             temp_pr = mxGetPr(prhs(2))
             call getreal(temp_pr,parm,1)
    
             temp_pr = mxGetPr(prhs(4))
             allocate(y(1:no))
             call getreal(temp_pr,y,no)
             
             temp_pr = mxGetPr(prhs(5))
             temp_m = mxGetM(prhs(5))
             temp_n = mxGetN(prhs(5))
             allocate(jd(temp_m*temp_n))
             call getinteger(temp_pr,jd,temp_m*temp_n)     
             
             temp_pr = mxGetPr(prhs(6))
             allocate(vp(1:ni))
             call getreal(temp_pr,vp,ni)
    
             temp_pr = mxGetPr(prhs(7))
             call getinteger(temp_pr,ne,1)
    
             temp_pr = mxGetPr(prhs(8))
             call getinteger(temp_pr,nx,1)
             
             temp_pr = mxGetPr(prhs(9))
             call getinteger(temp_pr,nlam,1)
    
             temp_pr = mxGetPr(prhs(10))
             call getreal(temp_pr,flmin,1)     
             
             temp_pr = mxGetPr(prhs(11))
             temp_m = mxGetM(prhs(11))
             temp_n = mxGetN(prhs(11))
             allocate(ulam(1:temp_m * temp_n))
             call getreal(temp_pr,ulam,temp_m * temp_n)
             
             temp_pr = mxGetPr(prhs(12))
             call getreal(temp_pr,thr,1)
             
             temp_pr = mxGetPr(prhs(13))
             call getinteger(temp_pr,isd,1)
    
             temp_pr = mxGetPr(prhs(14))
             allocate(w(1:no))
             call getreal(temp_pr,w,no)
    
             temp_pr = mxGetPr(prhs(15))
             allocate(cl(1:2*ni))
             call getreal(temp_pr,cl,2*ni)
    
             temp_pr = mxGetPr(prhs(16))
             call getinteger(temp_pr,intr,1)
    
             temp_pr = mxGetPr(prhs(17))
             call getinteger(temp_pr,maxit,1)
    
             temp_pr = mxGetPr(prhs(18))
             allocate(o(1:no))
             call getreal(temp_pr,o,no)
    
    c$$$  ---prepare output---
    
             allocate(ia(1:nx))
             call zerointeger(ia,nx)
             allocate(nin(1:nlam))
             call zerointeger(nin,nlam)
             allocate(alm(1:nlam))
             call zeroreal(alm,nlam)
             allocate(a0(1:nlam))
             call zeroreal(a0,nlam)
             allocate(ca(1:nx*nlam))
             call zeroreal(ca,nx*nlam)
             allocate(dev(1:nlam))
             call zeroreal(dev,nlam)
    
    c$$$  ---computation----
    
             if (task .eq. 51) then    
                call fishnet(parm,no,ni,x,y,o,w,jd,vp,cl,ne,nx,nlam,flmin,
         $           ulam,thr,isd,intr,maxit,lmu,a0,ca,ia,nin,dev0,dev,alm,
         $           nlp,jerr)
             else
                call spfishnet(parm,no,ni,xs,jcs,irs,y,o,w,jd,vp,cl,ne,nx,
         $           nlam,flmin,ulam,thr,isd,intr,maxit,lmu,a0,ca,ia,
         $           nin,dev0,dev,alm,nlp,jerr)
             endif
    
    c$$$  ----output-----
    
             plhs(1) = mxCreateDoubleMatrix(1,1,0)
             temp_pr = mxGetPr(plhs(1))
             call putinteger(lmu,temp_pr,1)
    
             plhs(4) = mxCreateDoubleMatrix(nx,1,0)
             temp_pr = mxGetPr(plhs(4))
             call putinteger(ia,temp_pr,nx)
             
             plhs(5) = mxCreateDoubleMatrix(lmu,1,0)
             temp_pr = mxGetPr(plhs(5))
             call putinteger(nin,temp_pr,lmu)
             
             plhs(7) = mxCreateDoubleMatrix(lmu,1,0)
             temp_pr = mxGetPr(plhs(7))
             call putreal(alm,temp_pr,lmu)
             
             plhs(8) = mxCreateDoubleMatrix(1,1,0)
             temp_pr = mxGetPr(plhs(8))
             call putinteger(nlp,temp_pr,1)
             
             plhs(9) = mxCreateDoubleMatrix(1,1,0)
             temp_pr = mxGetPr(plhs(9))
             call putinteger(jerr,temp_pr,1)
    
             plhs(2) = mxCreateDoubleMatrix(lmu,1,0)
             temp_pr = mxGetPr(plhs(2))
             call putreal(a0,temp_pr,lmu)
    
             plhs(3) = mxCreateDoubleMatrix(nx,lmu,0)
             temp_pr = mxGetPr(plhs(3))
             call putreal(ca,temp_pr,nx*lmu)
             
             plhs(6) = mxCreateDoubleMatrix(lmu,1,0)
             temp_pr = mxGetPr(plhs(6))
             call putreal(dev,temp_pr,lmu)
    
             plhs(10) = mxCreateDoubleMatrix(1,1,0)
             temp_pr = mxGetPr(plhs(10))
             call putreal(dev0,temp_pr,1)
    
             plhs(11) = mxCreateDoubleMatrix(no,1,0)
             temp_pr = mxGetPr(plhs(11))
             call putreal(o,temp_pr,no)
    
             deallocate(y)
             deallocate(jd)
             deallocate(vp)
             deallocate(ulam)
             deallocate(a0)
             deallocate(ca)
             deallocate(ia)
             deallocate(nin)
             deallocate(alm)
             deallocate(cl)
             deallocate(o)
             deallocate(dev)
             
             if (task .eq. 51) then
                deallocate(x)
             else
                deallocate(xs)
                deallocate(irs)
                deallocate(jcs)  
             endif
             return
          endif
    
    c$$$  --------------------end of Poisson------------------
    
          return
          end
    
    C     End of subroutine mexFunction
          
          subroutine real8toreal(x, y, size)
          integer size
          real*8 x(size)
          real y(size)
          do 10 i=1,size
             y(i)= x(i)
     10   continue
          return
          end
    
          subroutine realtoreal8(x, y, size)
          integer size
          real x(size)
          real*8 y(size)
          do 20 i=1,size
             y(i)= x(i)
     20   continue
          return
          end
          
          subroutine real8tointeger(x, y, size)
          integer size
          real*8 x(size)
          integer y(size)
          do 30 i=1,size
             y(i)= x(i)
     30   continue
          return
          end
          
          subroutine integertoreal8(x, y, size)
          integer size
          integer x(size)
          real*8 y(size)
          do 40 i=1,size
             y(i)= x(i)
     40   continue
          return
          end
          
          subroutine getreal(pr,x,size)
          mwpointer pr
          integer size
          real x(size)
          real*8, dimension (:), allocatable :: temp
          allocate(temp(1:size))
          call mxCopyPtrToReal8(pr,temp,size)
          call real8toreal(temp,x,size)
          deallocate(temp)      
          return
          end
          
          subroutine getinteger(pr,x,size)
          mwpointer pr
          integer size
          integer x(size)
          real*8, dimension (:), allocatable :: temp
          allocate(temp(1:size))
          call mxCopyPtrToReal8(pr,temp,size)
          call real8tointeger(temp,x,size)
          deallocate(temp)      
          return
          end      
          
          subroutine putreal(x,pr,size)
          mwpointer pr
          integer size
          real x(size)
          real*8, dimension (:), allocatable :: temp
          allocate(temp(1:size))
          call realtoreal8(x,temp,size)
          call mxCopyReal8ToPtr(temp,pr,size)
          deallocate(temp)      
          return
          end
          
          subroutine putinteger(x,pr,size)
          mwpointer pr
          integer size
          integer x(size)
          real*8, dimension (:), allocatable :: temp
          allocate(temp(1:size))
          call integertoreal8(x,temp,size)
          call mxCopyReal8ToPtr(temp,pr,size)
          deallocate(temp)      
          return
          end            
          
          subroutine zeroreal(x,size)
          integer size
          real x(size)
          do 90 i=1,size
             x(i) = 0
     90   continue     
          return 
          end
          
          subroutine zerointeger(x,size)
          integer size
          integer x(size)
          do 100 i=1,size
             x(i) = 0
     100  continue
          return
          end
    

    我要做的第一件事是清理MatlabAPI接口的东西。请记住,在Fortran中,不会像在C/C++中那样在函数/子例程参数列表中获得自动类型提升。因此,获得准确的签名非常重要。永远不要将文字整数传递给MatlabAPI函数。您应该完全按照API指定的类型传递变量,以确保不存在不匹配。例如,以以下代码为例:

      subroutine getreal(pr,x,size)
      mwpointer pr
      integer size
      real x(size)
      real*8, dimension (:), allocatable :: temp
      allocate(temp(1:size))
      call mxCopyPtrToReal8(pr,temp,size)
      call real8toreal(temp,x,size)
      deallocate(temp)      
      return
      end
    
    API中mxCopyPtrToReal8的签名为:

      subroutine mxCopyPtrToReal8(px, y, n)
      mwPointer px
      real*8 y(n)
      mwSize n
    
    因此,可能存在不匹配,因为默认Fortran整数可能与mwSize不匹配。此外,size是Fortran instrinsic函数的名称,因此变量的不同名称可能更合适。
    我会将该子程序更改为:

      subroutine getreal(pr,x,sizex)
      mwpointer pr
      mwSize sizex
      real x(sizex)
      real*8, dimension (:), allocatable :: temp
      allocate(temp(1:sizex))
      call mxCopyPtrToReal8(pr,temp,sizex)
      call real8toreal(temp,x,sizex)
      deallocate(temp)      
      return
      end
    
    现在可以确保sizex是合适的类型。您还需要更改调用例程中变量的类型

    (旁注:实际上,我不会做您正在做的任何事情……我只会编写一个循环,将值直接从mxArray复制到实际数组中,而无需额外的拷贝和内存分配/释放)

    另一个例子是:

      integer ...,nx,...
          :
      integer lmu,...
           :
         plhs(3) = mxCreateDoubleMatrix(nx,lmu,0)
    
    应替换为:

      mwSize nx, lmu
      integer*4 :: ComplexFlag = 0
           :
         plhs(3) = mxCreateDoubleMatrix(nx,lmu,ComplexFlag)
    
      x = temp
    
    坦率地说,您有很多赋值循环,可以用简单的语句代替。例如:

      call real8toreal(temp,x,sizex)
    
    可替换为:

      mwSize nx, lmu
      integer*4 :: ComplexFlag = 0
           :
         plhs(3) = mxCreateDoubleMatrix(nx,lmu,ComplexFlag)
    
      x = temp
    
    这是:

     allocate(ia(1:nx))
     call zerointeger(ia,nx)
     allocate(nin(1:nlam))
     call zerointeger(nin,nlam)
     allocate(alm(1:nlam))
     call zeroreal(alm,nlam)
     allocate(a0(1:nlam))
     call zeroreal(a0,nlam)
     allocate(ca(1:nx*nlam))
     call zeroreal(ca,nx*nlam)
     allocate(dev(1:nlam))
     call zeroreal(dev,nlam)
    
    可替换为以下内容:

     allocate(ia(1:nx))
     ia = 0
     allocate(nin(1:nlam))
     nin = 0
     allocate(alm(1:nlam))
     alm = 0.0
     allocate(a0(1:nlam))
     a0 = 0.0
     allocate(ca(1:nx*nlam))
     ca = 0.0
     allocate(dev(1:nlam))
     dev = 0.0
    

    等等。

    谢谢!这真的很有见地。这不是我自己的代码,我是通过glmnet包页面获得的。我不太确定如何在代码处于的状态下调试代码,但您的建议为我提供了一个很好的方向,可以开始清理代码并进行调试。