Quantcast
Channel: Intel® Fortran Compiler
Viewing all 3270 articles
Browse latest View live

DIV by 0.0, vectorization and optimization

$
0
0

It is not unusual for physics simulation programs to use unit vectors.
Physics simulation programs tend to have large sets of data and can benefit significantly through vectorization.

In these types of programs it may be rare, but not impossible, to have a separation of particles of 0.0, thus making the statement(s) that produces the unit vector containing a divide by 0.0. In the cases where separation is 0.0, you do not want to abort the program, instead you usually want to do something else, such as produce a unit vector of 0.0, or alternately a random unit vector.

A defensive measure is to insert a test for 0.0, and when found, perform the alternate substitution.

The problem with this is the test quashes vectorization.

ab(index,1:3) = b(index,1:3) - a(index,1:3)
separation(index) = sqrt(ab(index,1)**2 + ab(index,2)**2 + ab(index,3)**2)
if(separation(index) .eq. 0.0) then
  uv(index,1:3) = 0.0
else
  uv(index,1:3) = ab(index,1:3) / separation(index)
endif

What I would like to suggest is for the compiler optimization gurus to recognize the code sequence is a divide by 0.0 defensive code sequence with a known substitution, in this case 0.0, but it could be someOtherValue(1:3).

Then, when determined safe, have the loop disable divide by zero fault an substitute

uv(index,1:3) = ab(index,1:3) / separation(index)
if(uv(index,1) .eq. Infinity) uv(index,1) = Substitutio(1)
if(uv(index,2) .eq. Infinity) uv(index,2) = Substitutio(2)
if(uv(index,3) .eq. Infinity) uv(index,3) = Substitutio(3)

While the above looks ugly in source code, it can use masked moves (amongst temporary vector registers)

The above optimization removes code branching and thus improves probability of vectorizing loops containing defensive code for divide by 0.

Jim Dempsey


finding the dll to EXECUTE_COMMAND_LINE

$
0
0

I just am trying to use EXECUTE_COMMAND_LINE to replace non-standard system calls.   When I run my executable, I get an error that the function _execute_command_line is not found in the dll libifcoremd.dll.    How do I get the right ifort dll included with my executable so the exe runs on my local computer plus will run on my customers computers who do not have intel fortran installed?

I am building in Win32 (although trying to move to x64).   In ifort 15.0, MS VS 2012.   Building multithreaded dll exe.

subset of compile/link command line if it helps:

/nologo /O1 /Oy- /heap-arrays0
 /assume:nosource_include /Qsave /iface:cref /assume:underscore
  /Fd"Win32/Release\vc110.pdb" /traceback /libs:dll /threads /c
 
  /OUT:"..\..\..\bin\Win32/Release/ACSYSRUN.exe"
  /INCREMENTAL:NO
  /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /SUBSYSTEM:CONSOLE
  /STACK:5000000,5000000
 

WRITE(*,'(X,A)') my_text

$
0
0

Intel Fortran has a (very) nifty language extension that allows an edit descriptor to be an integer expression, using the < > brackets has shown in the subject line above. But is there a standard compliant equivalent form or workaround?

Errors in getting results

$
0
0

Does anyone of you can help me please? I am very new to the FORTRAN and never used it before. I am using Visual Studio 2012 and I think it already has FORTRAN compiler inside the Visual Studio. Every time when I hit "start" to build my program to get results, it gives me the following two errors:

1) Error    1     error #5082: Syntax error, found '=' when expecting one of: ( , <END-OF-STATEMENT> ; <IDENTIFIER> <INTEGER_CONSTANT> <POUND_VAL> <INTEGER_KIND_CON> ...    C:\Users\tborisovich\Documents\Winter2015\New Folder\615\A2\Prog\Draft1_fixed.f90    39    

2) Error    2    Compilation Aborted (code 1)    C:\Users\tborisovich\Documents\Winter2015\New Folder\615\A2\Prog\Draft1_fixed.f90    1    

 

Why is that? 

 

                            

                                                                                                          

  

Anything not standard conforming in following code?

$
0
0

I am puzzled by a difference in behavior between the Intel compiler and the Cray compiler on the example below.

PROGRAM TEST_STRING_FUNCTION

IMPLICIT NONE

CHARACTER(LEN=:),ALLOCATABLE :: S
CALL SUB( __LINE__ ,S)
WRITE(*,*) __LINE__
WRITE(*,*) S

CONTAINS

SUBROUTINE SUB(I,O)
INTEGER,INTENT(IN) :: I
CHARACTER(LEN=:),ALLOCATABLE :: O
CHARACTER(LEN=15) :: S15_1
WRITE(S15_1,'(I15)') I
O = TRIM(ADJUSTL(S15_1))
END SUBROUTINE SUB

END PROGRAM TEST_STRING_FUNCTION

When (automatically preprocessed, due to the .F90 extension) and compiled with Intel, I get the expected output (7, then 6). With the Cray compiler, I only get the output from the first WRITE statement.

Am I overlooking something here? What could explain (besides a bug or omission in one of the compilers) the different behavior?

Error in writing strings

$
0
0

Hi all,

I get a "forrtl: severe (66): output statement overflows record, unit -5" in this code, which tries to write a matrix to a CSV file with ";" separator:
 

CHARACTER(255) kterm,scrK
REAL*8 kcond(6,6)
...

OPEN(UNIT=200,FILE="K.CSV",STATUS="REPLACE",ACTION='WRITE')
do i=1,size(kcond,1)
do j=1,size(kcond,2)
    write(kterm,*)kcond(i,j)
    write(scrK,*)trim(adjustl(scrK))//';'//trim(adjustl(kterm)) ! error in this line
enddo
write(200,*)scrK
enddo
CLOSE(200)

any clue?
It seems that the string scrK cannot hold the concat strings because they are too long. why trim(adjustl( don't do the magic? initially, scrK is empty.
thanks in advance

Compilation aborted code 1 in a fortran program

$
0
0

Hi, I am a student, new in fortran, and my tutor left me a fortran program to study.

There is always a message:"Compilation aborted (code 1)" when I try to run it, and it is the only error. I don't know the reason.

Please help me. Here is the Log file.

Thanks.

AttachmentSize
DownloadBuildLog.rar2.88 KB

Is fstack-protector-all supported on MIC?

$
0
0

I'm debugging a crash in my Fortran code, and would like to try stack protection.

Is fstack-protector-all supported on the MIC platform?  When I build with -mic -fstack-protector-all the executable crashes because it can't find the libssp.so.0 library.  Is a MIC version of that library supposed to be included with my compiler?  I'm using ifort 14.0.2.  

Thank you for your help.


Derived Type Variables

$
0
0

The % sign separates the components of a derived type variable. For example: ! The following the syntax given in the language reference. george%age = 56 george%height = 6.0 But I see some examples where a period is used instead of the % sign. ! The following works too george.age = 56 george.height = 6.0 Is the use of a period in place of % considered standard FORTRAN, or is it non-standard? I am asking in case I try to compile the source with a different compiler someday. Thanks for responding.

Non-scalar pass-object dummy arguments

$
0
0

Hi,

I am trying to use type-bound procedures (TBP) with non-scalar pass-object dummy arguments. Although not valid from the standard (C461: "The passed-object dummy argument shall be a scalar, nonpointer, nonallocatable dummy data object..."), it seems to be supported by ifort version 14.0.4 (the version I'm using here) as shown by the following code:

Module MyModule
  implicit none
  Type          ::      MyType
    integer     ::      Val
  contains
    procedure   ::      ScaProc
    procedure   ::      VecProc
  End Type
  contains
Subroutine ScaProc( This, Inp, Out )
  class(MyType)                 ,intent(in)     ::      This
  integer                       ,intent(in)     ::      Inp
  integer                       ,intent(out)    ::      Out
  Out   =       Inp     +       This%Val
End Subroutine
Subroutine VecProc( Those, Inp, Out )
  class(MyType) ,dimension(:)   ,intent(in)     ::      Those
  integer                       ,intent(in)     ::      Inp
  integer                       ,intent(out)    ::      Out
  Out   =       Inp     +       sum(Those%Val)
End Subroutine
End Module

Program Main
  use MyModule  ,only:  MyType
  implicit none
  type(MyType)                  ::      Sca
  type(MyType)  ,dimension(10)  ::      Vec
  integer                       ::      i
  integer       ,parameter      ::      Inp = 1000
  integer                       ::      Out
  write(*,"(/,a)") 'Calling a TBP with a scalar passed-object dummy argument:'
  Sca        =       MyType(Val=100)
  call Sca%ScaProc( Inp, Out )
  write(*,"(a,g0)")       'Sca%Val = ', Sca%Val
  write(*,"(a,g0)")       'Inp     = ', Inp
  write(*,"(a,g0)")       'Out     = ', Out
  write(*,"(/,a)") 'Calling a TBP with a non-scalar passed-object dummy argument:'
  Vec        =       [ (MyType(Val=i),i=1,size(Vec)) ]
  call Vec%VecProc( Inp, Out )
  write(*,"(a,*(i3,1x))") 'Vec%Val = ', Vec(:)%Val
  write(*,"(a,g0)")       'Inp     = ', Inp
  write(*,"(a,g0)")       'Out     = ', Out
End Program

Using ifort version 14.0.4, I am getting the following output:

$ ifort main.F90; ./a.out

Calling a TBP with a scalar passed-object dummy argument:
Sca%Val = 100
Inp     = 1000
Out     = 1100

Calling a TBP with a non-scalar passed-object dummy argument:
Vec%Val =   1   2   3   4   5   6   7   8   9  10
Inp     = 1000
Out     = 1055

while gfortran (version 4.8.3 20140911) do not compile this code:

$ gfortran main.F90
main.F90:10.13:

    procedure   ::      VecProc
             1
Error: Passed-object dummy argument of 'vecproc' at (1) must be scalar

Note that if I had a generic TBP, I get an ICE.

Module MyModule
  implicit none
  Type          ::      MyType
    integer     ::      Val
  contains
    generic     ::      Proc => ScaProc, VecProc
    procedure   ::      ScaProc
    procedure   ::      VecProc
  End Type
  contains
Subroutine ScaProc( This, Inp, Out )
  class(MyType)                 ,intent(in)     ::      This
  integer                       ,intent(in)     ::      Inp
  integer                       ,intent(out)    ::      Out
  Out   =       Inp     +       This%Val
End Subroutine
Subroutine VecProc( Those, Inp, Out )
  class(MyType) ,dimension(:)   ,intent(in)     ::      Those
  integer                       ,intent(in)     ::      Inp
  integer                       ,intent(out)    ::      Out
  Out   =       Inp     +       sum(Those%Val)
End Subroutine
End Module

Program Main
  use MyModule  ,only:  MyType
  implicit none
  type(MyType)                  ::      Sca
  type(MyType)  ,dimension(10)  ::      Vec
  integer                       ::      i
  integer       ,parameter      ::      Inp = 1000
  integer                       ::      Out
  write(*,"(/,a)") 'Calling a TBP with a scalar passed-object dummy argument:'
  Sca        =       MyType(Val=100)
  call Sca%Proc( Inp, Out )
  write(*,"(a,g0)")       'Sca%Val = ', Sca%Val
  write(*,"(a,g0)")       'Inp     = ', Inp
  write(*,"(a,g0)")       'Out     = ', Out
  write(*,"(/,a)") 'Calling a TBP with a non-scalar passed-object dummy argument:'
  Vec        =       [ (MyType(Val=i),i=1,size(Vec)) ]
  call Vec%Proc( Inp, Out )
  write(*,"(a,*(i3,1x))") 'Vec%Val = ', Vec(:)%Val
  write(*,"(a,g0)")       'Inp     = ', Inp
  write(*,"(a,g0)")       'Out     = ', Out
End Program

which produce

main_ICE.F90(44): catastrophic error: **Internal compiler error: internal abort** Please report this error along with the circumstances in which it occurred in a Software Problem Report.  Note: File and line given may not be explicit cause of this error.
compilation aborted for main_ICE.F90 (code 1)

So, here are my questions:

  1. Is the "non-scalar pass-object dummy arguments" capability an non-standard extension from intel or just a bug that somehow passes through the compiler checks and happens to gives the correct results ?
  2. Is this "scalar pass-object dummy arguments" restriction on TBP is likely to be relaxed in the standard ?

 

Thanks

Problem with IMSL serial number

$
0
0

Hi,

I bough the Intel IMSL Fortran Numerical Library, but when I install it a error message appears after I enter the serial number, as if it were an invalid serial number. How could this be fixed? The error message goes attached. [Message deleted by Steve L as it reveals serial number]

Thanks

 

 

Headache free C-Fortran interface under 11+

$
0
0

I'm in charge of a rather large C-Fortran interface for our codes that has recently run afoul of the extra strictness included in 11+.

"error #8532: A character dummy argument with length other than 1 is not interoperable"

This problem has previously been raised by a coworker in 2011. Unfortunately, the answer given does not solve the real problem at hand (mostly because the co-worker was just trying to solve one specific issue and not the entire issue). I also understand that the old solution operated in a gray area, however, the implementation met all of the requirements imposed by operation in this gray area.

Problem Description

  1. Large C library with 100+ API entry points.
  2. Almost all of them include string arguments (90% IN, some are OUT)
  3. This library was previously written in Fortran.
  4. Thousands of lines in 50-60 Fortran executables which call the C library assuming it is still Fortran.
  5. The C Library includes the necessary logic to "pretend" to be Fortran (supports pretending to be CVF, IVF, and gfortran)
  6. The C Library provides an optional auto-generated module with the interface/subroutine/BIND magic to give argument type/dimension checking to these codes.

Example C API method

/* "data" is scalar to 7D, any of the primitive fortran types */
ABC_API(void) foobar (
  IN int *id,
  IN const char *folder FDECL_LENGTH_MIXED(folder),
  IN const char *file FDECL_LENGTH_MIXED(file),
  IN_BUFFER_ANY const void *data,
  IN_ESIZE(10) const int descriptor[],
  IN int *count,
  IN_ESIZE_MAX(7) const int startingElement[],
  OUT_ESIZE(2) int status[]
  FDECL_LENGTH_AFTER(folder)
  FDECL_LENGTH_AFTER(file)
);

Example Fortran Module entry for that routine (snipped for brevity)

! toplevel foobar selects type/dimension call
interface foobar
    module procedure foobar_i0, foobar_i1, foobar_i2, foobar_i3, foobar_i4, foobar_i5, foobar_i6, foobar_i7 &
          , foobar_r0, foobar_r1, foobar_r2, foobar_r3, foobar_r4, foobar_r5, foobar_r6, foobar_r7 &
          , foobar_d0, foobar_d1, foobar_d2, foobar_d3, foobar_d4, foobar_d5, foobar_d6, foobar_d7 &
          , foobar_cx0, foobar_cx1, foobar_cx2, foobar_cx3, foobar_cx4, foobar_cx5, foobar_cx6, foobar_cx7 &
          , foobar_l0, foobar_l1, foobar_l2, foobar_l3, foobar_l4, foobar_l5, foobar_l6, foobar_l7 &
          , foobar_c0, foobar_c1, foobar_c2, foobar_c3, foobar_c4, foobar_c5, foobar_c6, foobar_c7
endinterface foobar

! top level generic interface selects one of the following, which calls the C binding routines
subroutine foobar_i0 ( id, folder, file, idata, dsdes, ne, selem, istat )
    implicit none
    integer, intent(in) :: id
    character(len=*), intent(in) :: folder
    character(len=*), intent(in) :: file
    integer, intent(in) :: idata
    integer, intent(in) :: dsdes(DSDES_COUNT)
    integer, intent(in) :: ne
    integer, intent(in) :: selem(*)
    integer, intent(out) :: istat(STAT_COUNT)
    call foobar_internal_i0(id, folder, file, idata, dsdes, ne, selem, istat)
endsubroutine foobar_i0
subroutine foobar_i1 ( id, folder, file, idata, dsdes, ne, selem, istat )
    implicit none
    integer, intent(in) :: id
    character(len=*), intent(in) :: folder
    character(len=*), intent(in) :: file
    integer, intent(in) :: idata(:)
    integer, intent(in) :: dsdes(DSDES_COUNT)
    integer, intent(in) :: ne
    integer, intent(in) :: selem(*)
    integer, intent(out) :: istat(STAT_COUNT)
    call foobar_internal_i(id, folder, file, idata, dsdes, ne, selem, istat)
endsubroutine foobar_i1
! repeat subroutine foobar_XYZ for each type and dimension
! These _internal_ variants are the methods actually bound to the C, which provide both Scalar and
! DIMENSION(*) versions so that C just gets a raw pointer

subroutine foobar_internal_c ( id, folder, file, cdata, dsdes, ne, selem, istat ) bind(C, name='FOOBAR')
    implicit none
    integer, intent(in) :: id
    character(len=*), intent(in) :: folder
    character(len=*), intent(in) :: file
    character(len=*), intent(in) :: cdata(*)
    integer, intent(in) :: dsdes(DSDES_COUNT)
    integer, intent(in) :: ne
    integer, intent(in) :: selem(*)
    integer, intent(out) :: istat(STAT_COUNT)
endsubroutine foobar_internal_c

subroutine foobar_internal_c0 ( id, folder, file, cdata, dsdes, ne, selem, istat ) bind(C, name='FOOBAR')
    implicit none
    integer, intent(in) :: id
    character(len=*), intent(in) :: folder
    character(len=*), intent(in) :: file
    character(len=*), intent(in) :: cdata
    integer, intent(in) :: dsdes(DSDES_COUNT)
    integer, intent(in) :: ne
    integer, intent(in) :: selem(*)
    integer, intent(out) :: istat(STAT_COUNT)
endsubroutine foobar_internal_c0
! repeat foobar_internal_XYZ for each type

Basically, I can't update the C code (and its API) in any manner which would break the expectation that it is "Fortran". Now I'm caught because 11+ no longer allows this behavior. I also cannot introduce any required shim code on the Fortran side, because the API must work with or without the auto-generated module.

I'm more than happy to maintain the headache of the C side understanding Fortran string-isms, etc. This is far easier than introducing C-isms to the Fortran side, in both code support AND time-burden to update/verify all of the production Fortran.

Is there a way I can update this interface to meet both my desire to: (a) provide a type checking solution for the library, and (b) not introduce any required shimming?

 

value being NaN and (+-)infinity in fortran

$
0
0

Hi there,

I'm running my abaqus .inp file with UMAT( modified by fortran). Due to some errors, the job can not complete successfully. After using write(*,*) to output some variables I've defined. I've found that some are being NaN and some are infinity. How can I solve this?( the stress is zero initially and being the denominator. Thanks.

Regards,

Vicky

Undefined pointer/array *not crashing*

$
0
0

Hello everyone,

I'm having issues with this sample of code

subroutine tri_2D(vect)
	real(kind=DP), dimension(:,:),pointer :: vect

	integer :: n, n1, n2
	real(kind=DP), dimension(:), allocatable :: STOCK1, STOCK2
	real(kind=DP) :: temp1,temp2

	integer :: j, jj, jcompt, flag, jk

	integer :: nn,nntemp

	integer :: k,w

	integer :: markeur
	real(kind=DP),dimension(:), pointer :: ptr_temp

	! recuperation des dimensions de vect
	n1=size(vect,1)
	n2=size(vect,2)

!	write(unit=*,fmt=*) "n1=",n1,"n2=",n2
!	pause

	if (n2/=2) then
		write(unit=*,fmt=*) "erreur de dimension de vect, tri 2D : dim non égale a 2"
		return
	endif

	nn=n1
	allocate(stock1(nn),stock2(nn))

	do k=1,nn
		STOCK1(k)=vect(k,1)
		STOCK2(k)=vect(k,2)
	enddo

.........

Oddly, I declare these variables as "allocatable", so they should be allocated after the statement allocate, right ?

Except I get that "Undefined pointer/aray" (see attached picture). So I guess that it should crash when I affect a value in the "do loop" that follows ? But it doesn't. The debugger still goes through the code

 

Please advise. I can't figure out what's going on in my statements.

Regards,

Renaud Egal

AttachmentSize
Downloadundefined.png10.47 KB

optimization help/vectorization/SIMD questions

$
0
0

Hi,

Consider the following code snippet: 

    do i = 1, size(rhs,dim=2)
       if (n == biggest_int) exit !Overflow!
       n1 = n
       n = n + 1
       n1on = real(n1,WP)/real(n,WP)
       ! Add SIMD dir?
       !!!!DIR$ SIMD PRIVATE(p,k)
       do concurrent (j=1:size(lhs)) ! I'm nervous about p and k getting stepped on
          delta(j) = rhs(j,i) - local_res(j)%M(1)
          local_res(j)%M(1) = local_res(j)%M(1) + delta(j)/real(n,WP)
          !DIR$ LOOP COUNT (1,2,3,4,5)
          do p = local_res(j)%p,2,-1 !iterate backwards because new M4 depends on old M3,M2 etc.
             sum(j) = 0
             !DIR$ LOOP COUNT (0,1,2,3,4)
             do k = 1,p-2
                sum(j) = sum(j) + &
                     local_res(j)%binkp(k,p)*((-delta(j)/n)**k)*n1on*local_res(j)%M(p-k)
             end do
             local_res(j)%M(p) = n1on*local_res(j)%M(p) + sum(j) + &
                  ((delta(j)/n)**p)*(n1**p + n1*((-1)**p))/n
          end do
          local_res(j)%n   = n
          local_res(j)%min = min(lhs(j)%min,rhs(j,i))
          local_res(j)%max = max(lhs(j)%max,rhs(j,i))
       end do
    end do

Note that the outermost do loop has data dependencies… It is performing a data reduction operation over one dimension of rhs.

Iterations of the next do loop (expressed as do concurrent) may be performed in any order. My reading of ‘Modern Fortran Explained’ p. 360:

 any variable referenced is either previously defined in the same iteration, or its value is

not affected by any other iteration;

To me this means that the loop indices contained within this `do concurrent` loop, p, and k, are *NOT* in danger of getting stepped on, since they are “previously defined in the same iteration” of the current `do concurrent` loop. Is this correct?

The loops *inside* the `do concurrent` are order dependent. The loop over p moves backwards, because we are updating values of `local_res(j)%M(p)` using the old (relative to the iteration over p) values of `local_res(j)%M(2)` … `local_res(j)%M(p-1)` for the update.

The loop over k has a data dependency because it is a sum reduction. The sum may be performed in any order, so long as two iterations don’t try to write the sum at once.

Typically the upper bound of the `do concurrent` loop will be quite large, so my idea was to try to do some optimizations on this loop, such as SIMD or vectorization. Am I on the right track here?

If the directive on line 7 is *not* commented out (by removing 3 of 4 !s) then the compiler gives an error: 

error #8592: Within a SIMD region, a DO-loop control-variable must not be specified in a PRIVATE/REDUCTION/FIRSTPRIVATE/LASTPRIVATE SIMD clause.   [P]
          do p = local_res(j)%p,2,-1 !iterate backwards because new M4 depends on old M3,M2 etc.
-------------^

Does this mean I don’t need the private clause and that p and k are safe from getting stepped on, or does this mean that the directive is telling the compiler that loops over p and k have no data dependencies?

Any and all advice is greatly welcome.

Thanks!


Line of sight for compiler allowing mixed coarray/OpenMP use?

$
0
0

I am wondering if we could have an estimate of when Intel will release a compiler that allows mixed coarray/OpenMP usage. It is still not possible in version 15. Thanks!
 

"Stack trace terminated abnormally": what does this mean?

$
0
0

Hi,

running a code compiled with -check all I see various warnings concerning the creation of some temporaries (I know about them and I am fine with them) and somehow interspersed in the ouput various lines saying

Stack trace terminated abnormally.

What does this mean? Notice that I do see a traceback for the warnings, but this line has no traceback.

I am using "Intel(R) Fortran Intel(R) 64 Compiler XE for applications running on Intel(R) 64, Version 15.0 Build 20141023"

Thank you, Marco

compiler unable to find module and symbols

$
0
0

Hello,

I can compile my sources on Linux with the ifort compiler without any problems. 

However, when I use the same Makefile or when I use the Visual Studio IDE with  Visual Fortran Compiler XE 13.0.1.119 the compiler complains about one particular module thus:

path\to\SOURCE\myfortranfile.f90(12): error #7002: Error in opening the compiled module file. Check INCLUDE paths. [fn#fn]

What I find baffling is that the name of the module is mentioned as fn#fn and as far as the code goes, since it compiles without issues on Linux, I'm confident that the sources themselves have no serious issues. 

Anything else I need to look out for?

Thanks in advance.

 

How to enforce inlining ?

$
0
0

Hi,

My code involves a derived-type variable (denoted 'Object' hereafter) holding another derived-type variable as a component (denoted 'SubObject').

The SubObject has a type-bound procedure for computing some quantity, let say Q.

The Object also has a procedure for computing Q, but the actual computation is delegated to the SubObject component.

Here is simple example:

Module SubObject_Module
  implicit none
  private
  public        ::      SubObject_Type
  Type          ::      SubObject_Type
  contains
    procedure   ::      Compute => Compute_SubObj
  End Type
  contains
Pure Subroutine Compute_SubObj( This, Inp, Out )
  class(SubObject_Type)         ,intent(in)     ::      This
  integer                       ,intent(in)     ::      Inp
  integer                       ,intent(out)    ::      Out
  Out = Inp * 2
End Subroutine
End Module

Module Object_Module
  use SubObject_Module  ,only:  SubObject_Type
  implicit none
  private
  public        ::      Object_Type
  Type  ::      Object_Type
    private
    type(SubObject_Type) ::      Sub
  contains
    procedure   ::      Compute => Compute_Obj
  End Type
  contains
Pure Subroutine Compute_Obj( This, Inp, Out )
  class(Object_Type)            ,intent(in)     ::      This
  integer                       ,intent(in)     ::      Inp
  integer                       ,intent(out)    ::      Out
  call This%Sub%Compute( Inp, Out )
End Subroutine
End Module

Program Main
  use Object_Module ,only: Object_Type
  implicit none
  type(Object_Type)             ::      Object
  integer                       ::      Inp = 5, Out
  call Object%Compute( Inp, Out )
End Program

As you can see, in the main program I'm calling the TBP from the Object variable using "call Object%Compute(...)" (line 43).

The only task of this TBP is to call the TBP from the SubObject component, using "call This%Sub%Compute(...)" (line 34)

My real code heavily uses this delegation approach, which leads to lots of TBP being actually only wrappers to components' TBP calls.

Now, I want to avoid the extra cost of calling all those "useless" TBP (Compute_Obj) by forcing inlining of the call to the component's TBP (Compute_SubObj).

How should I do so ?

For now, I'm adding the "!DEC$ ATTRIBUTES FORCEINLINE :: Compute_SubObj" line before the "Compute_SubObj" procedure:

!DEC$ ATTRIBUTES FORCEINLINE :: Compute_SubObj
Pure Subroutine Compute_SubObj( This, Inp, Out )
  class(SubObject_Type)         ,intent(in)     ::      This
  integer                       ,intent(in)     ::      Inp
  integer                       ,intent(out)    ::      Out
  Out = Inp * 2
End Subroutine

Is it the correct way to enforce  inlining?

I know that inlining can also be changed using the following compiler options:

  -inline-factor
  -inline-min-size
  -inline-max-size
  -inline-max-total-size
  -inline-max-per-routine
  -inline-max-per-compile

but with no guarantee that the inlining is actually going to happen.

Am I right ?

Thank for yous enlightenment.

size of undefined allocatable array different than zero !

$
0
0

Hello !

I've been working on migrating old Compaq projects to Intel Visual Fortran. I'm hitting some problems and I can't find any solution on this forum. Please help me.

First, I have to mention that these are large complex and most of all confidential projects, so I won't provide them entirely for these reasons.

The first problem I encountered is the one showed in the attached project : when I try to get the size of a deallocated array, I get the size of the array before deallocating... That's something that wasn't happening with CVF.

If you have any advice on that, I'm all ears !

Cheers

Renaud Egal

Microsoft Visual Studio 2010
Version 10.0.30319.1 RTMRel
Microsoft .NET Framework
Version 4.5.51209 RTMRel

Installed Version: IDE Standard

Microsoft Visual Web Developer 2010   01011-532-2002361-70018
Microsoft Visual Web Developer 2010

Intel(R) Visual Fortran     Package ID: w_fcompxe_2013_sp1.4.237
Intel(R) Visual Fortran Composer XE 2013 SP1 Update 4 Integration for Microsoft Visual Studio* 2010, 14.0.0100.2010, Copyright (C) 2002-2014 Intel Corporation
* Other names and brands may be claimed as the property of others.

This product includes software developed at The Apache Software Foundation (http://www.apache.org/).

Portions of this software were originally based on the following:
- software copyright (c) 1999, IBM Corporation., http://www.ibm.com.
- software copyright (c) 1999, Sun Microsystems., http://www.sun.com.
- the W3C consortium (http://www.w3c.org) ,
- the SAX project (http://www.saxproject.org)
- voluntary contributions made by Paul Eng on behalf of the Apache Software Foundation that were originally developed at iClick, Inc., software copyright (c) 1999.

This product includes updcrc macro, Satchell Evaluations and Chuck Forsberg. Copyright (C) 1986 Stephen Satchell.

This product includes software developed by the MX4J project (http://mx4j.sourceforge.net).

This product includes ICU 1.8.1 and later.Copyright (c) 1995-2006 International Business Machines Corporation and others.

Portions copyright (c) 1997-2007 Cypress Semiconductor Corporation. All rights reserved.

This product includes XORP. Copyright (c) 2001-2004 International Computer Science Institute

This product includes software from the book "Linux Device Drivers" by Alessandro Rubini and Jonathan Corbet, published by O'Reilly & Associates.

This product includes hashtab.c. Bob Jenkins, 1996.

 

AttachmentSize
DownloadConsole1.zip69.98 KB
Viewing all 3270 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>