Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
28456 Discussions

More submodule head scratching.... functions with result() array

andrew_4619
Honored Contributor II
404 Views

Consider:

    ! the interface part in the module which compiles OK

    module function double_it(A)  
       REAL(KIND=IRK), intent(in) :: A(3)
       REAL(KIND=IRK)             :: double_it(3)
    end function double_it 

    ! the implementation part in the submodule.
    ! error #6833: The RESULT data type is  multiply specified: on function statement and result name.   
    ! error #6834: Array specifications must be given for result name, not function.   
    ! both errors relate to the line below
    module function double_it(A) result(B) 
       implicit none
       REAL(KIND=IRK), intent(in) :: A(3)
       REAL(KIND=IRK)             :: B(3)
       B=2._IRK*A
    end function double_it

Can one use result with module function? If so what is the correct syntax I have spend some time trying to find enlightenment and have failed again :-(

.

0 Kudos
15 Replies
FortranFan
Honored Contributor II
404 Views

You may have seen this: https://software.intel.com/en-us/forums/intel-visual-fortran-compiler-for-windows/topic/549513.

Would you prefer using RESULT clause in both the interface as well as in the actual procedure,  as I do?

Or are you asking for the compiler (and perhaps the standard) to handle a scenario where the interface follows one approach (which includes or excludes the RESULT) but the actual implementation has the opposite?  Gee, I don't know how that would work, beyond my faculties!

 

0 Kudos
andrew_4619
Honored Contributor II
404 Views

I Have tried various things for example if I have the interface:

    module function double_it(A) result(B)  
       REAL(KIND=IRK), intent(in) :: A(3)
       REAL(KIND=IRK)             :: B(3)
    end function double_it 

I still get the error:

error #6834: Array specifications must be given for result name, not function.  

0 Kudos
andrew_4619
Honored Contributor II
404 Views

"Or are you asking for the compiler (and perhaps the standard) to handle a scenario where the interface follows one approach (which includes or excludes the RESULT) but the actual implementation has the opposite?  Gee, I don't know how that would work, beyond my faculties!"

That is too deep a question, I just want something that works (without having to remove result)! :-)

But logically the interface defines the return type of the function and the fact that the implimentation of the function has an alias to the function name in it I would not have though mattered but if it does that is not a problem!

0 Kudos
FortranFan
Honored Contributor II
404 Views

Looks like a bug in Intel Fortran implementation.  Strange I haven't run into this one so far; I've tried out submodules on a few small projects using 16.0 beta and encountered some of the other issues you're noticing such as warnings about function/subroutine names and temporary files but more importantly, the recompilation aspect.  On that, I couldn't spend enough time to figure out the details and/or rule out any of my VS settings as being the culprit that might cause recompilation.  Also, I didn't notice it my second, more important, project with submodules and so I didn't pursue it

Back to your case involving a function result returning arrays, hopefully there is a quick resolution/workaround.

 

0 Kudos
andrew_4619
Honored Contributor II
404 Views

@fortranfan

Yes I am looking to convert many of my large modules to submodules as in the long run it will save me time. At the moment I am just playing to see what the problems are.  There seem to be some implementation issues that need to be resolved before I can use it but I will keep playing with it.

The biggest issue is actually creating  interfaces for existing routines, Some semi-automated method is needed,  It would seem to me that if a compiler option would allow the generated interfaces for interface checking to be optionally  created for existing modules these can be used, I butchered a module to make the routines external and then concatenated all the generated interface files did a few global edit/replace operations and I had a working set of interfaces, The problem is butchering a module to allow it to compile as external routines is not a viable solution as there are dependencies that stop compilation in many cases. Any thoughts on this, know of any tools?

 

 

 

0 Kudos
FortranFan
Honored Contributor II
404 Views

app4619 wrote:

@fortranfan

..

The biggest issue is actually creating  interfaces for existing routines, Some semi-automated method is needed, ... Any thoughts on this, know of any tools?

Sorry I don't know of any tools.  In my case, I'd done some work several years ago to convert most of the older style external procedures to 'contain'ed procedures in modules with "implicit none", intent specifications of all arguments, assumed shape arrays, etc. as much as possible.  So I have a macro in a commercial editor I use that grabs a module, makes a copy, and then takes each procedure from the CONTAINS section and places it within an INTERFACE block, strip out all the lines of said procedure past the argument list definition until the END statement, and prefaces SUBROUTINE/FUNCTION statement at the beginning with MODULE keyword, and finally it strips out the CONTAINS section.  Note this is not fully debugged and I have to fix a few things manually to get it right, but it seems to get me 70-80% of the distance.  The bigger challenge I find is in organizing my submodules so I can have related procedures and data they operate all in the same submodule and try to modularize the overall code further so that data dependencies are minimized.  In addition, I'm not fully sure about interprocedural optimization (IPO) and whether it becomes better (or worse, at least in the interim future) if the code starts to live in a "yellow sub.."!!  

0 Kudos
IanH
Honored Contributor II
404 Views

app4619 wrote:
The biggest issue is actually creating  interfaces for existing routines, Some semi-automated method is needed,  It would seem to me that if a compiler option would allow the generated interfaces for interface checking to be optionally  created for existing modules these can be used, I butchered a module to make the routines external and then concatenated all the generated interface files did a few global edit/replace operations and I had a working set of interfaces, The problem is butchering a module to allow it to compile as external routines is not a viable solution as there are dependencies that stop compilation in many cases. Any thoughts on this, know of any tools?

When I saw your initial query a few days back, I figured that I could modify some of my existing Fortran parsing routines to do this - what I would need to add would be a little bit of statement filtering and then the ability to re-render the filtered set of the input statements back to a file.  I started to sketch the concept out a bit more, but about thirty seconds later I realized that it would only be for quite simple cases.  Splitting out the entire set of statements for the specification of the arguments requires a tool to have a pretty good understanding of what each statement specifies, and then it has to work "back" from anything that might affect the characteristics of the procedure - consider things like implicit typing in the scope of the procedure, use of local sequence types or interface blocks for dummy procedures.  Then another thirty seconds later my children informed me that they were very bored and I was neglecting them, so I stopped surfing the forum and thinking about this, pulled back onto the road and resumed driving them to school.

0 Kudos
andrew_4619
Honored Contributor II
404 Views

@Ian Yes a considered making a parser but It isn't that easy. I think I could bang together a quick parser  that did maybe 95% of the work and the rest by human fixing but that still does not sound very appealing.

The Intel compiler has 99.998% of the code build in already to do this job for generated interfaces or indeed making mod files.......

 ...and yes I have kids who are unreasonable like that also but school runs are long passed ..... that said I had a "University run" from the UK to France last week which was a 1100 mile round trip though so it can get worse!

.

0 Kudos
Kevin_D_Intel
Employee
404 Views

I recreated the error #6834 shown from the combination of code segments from posts #1 and #3 and reported it to Development. I’ll keep you updated about that.

I can make some inquiries about utilities/tools or the compiler’s assistance in converting existing modules to submodules and let you know what I hear back.

(Internal tracking id: DPD200375960)

(Resolution Update on 02/26/2016): This defect is fixed in the Intel® Parallel Studio XE 2016 Update 2 Release (PSXE 2016.2.055/ CnL 2016.2.180 - Windows)

0 Kudos
andrew_4619
Honored Contributor II
404 Views

Further to the discussion on automatically generated interfaces by various hackology and automated wild card edits I successfully generated interfaces for quite a few modules (a few hundred procedures) using the<name>_genmod.f90.

One drawback is the the generate interfaces  don't keep any KIND parameters e.g. INTEGER(HANDLE) becomes INTEGER(4) or INTEGER(8) dependent on if it is a 32 or 54 bit build. so one way or another the application fails to build and you have to go interface fixing again.....

A proper tool would be good. A driver for SUBMODULE functionality is build cascades in large programs. It stands to reason that people with large programs will find it desirable to convert Modules to Submodules....... 

0 Kudos
Kevin_D_Intel
Employee
404 Views

Our Fortran Developers discussed the idea of a utility to aid in the conversion to submodules. They said adding a utility to the compiler amounts to creating a new compilation phase to create one parent module and one submodule from an existing  standard-conforming module.  They believe the work on that would be non-trivial.  They were not fully persuaded about the need for such either, adding they converted a number of module tests to use submodules to exercise this new feature in 16.0, and while admittedly tedious, it was not necessarily difficult. Certainly converting a lot of modules for a larger app, such as you described you are facing, will also be non-trivial and tedious.

I know you are already aware, but for the benefit of others reading who are not, Doctor Fortran describes the steps in Doctor Fortran in "We All Live in a Yellow Submodule".

Sorry we could not be of more help.

0 Kudos
andrew_4619
Honored Contributor II
404 Views

Kevin,

Thanks for looking in to this, if had been an easier task it would have been a useful feature. I found the generated interfaces xxx_genmod.f90 files are have limitations as parameterised ( e.g. integer(handle) ) KIND's all get converted to INTEGER(4) or indeed INTEGER(8) dependent on the Bitness of the build and hence you need to check and fix them anyway.

Tedious the task is indeed! Via a mix of manual and semi-automated bodging I created interfaces for several hundred routines recently and am about 70% through the immediate task at hand. This has been halted, the main reason being that the false inter-dependency problem (DPD200375981  & DPD200375984)   that causes multiple sub-modules to always rebuild. This  makes any development very tedious and painful as every tiny change generates a large build cascade. 

I am convinced in my mind that the fact the the dependency checker believes (from the first time error messages) every occurrence in a module or submodule of  "MODULE SUBROUTINE xxxx" leads it to think there is a dependent MODULE called SUBROUTINE.  Is there any work around or patch that could be applied or some configuration files for VS I could "fiddle with"? Was there any progress on this issue

Best Regards

Andrew

0 Kudos
jimdempseyatthecove
Honored Contributor III
404 Views

App4619,

>>false inter-dependency problem (DPD200375981  & DPD200375984)   that causes multiple sub-modules to always rebuild

In the situation where you have A using B, B using C, C using A (of variations on this), the usual source of the dependency issue is the CONTAINS routines in the module needing type and/or interface declarations of the other modules. To remedy this, consider separating the type definition and interfaces from the defined data and CONTAINS (code) section. And compile as separate .f90 sources. (A..F90,A_CODE.F90, B.F90, B_CODE.F90, ...). The circular dependency is thus broken.

If the root cause of the problem is a circular list of type declarations, then you need to re-work the placement of those declarations or add an additional module with declarations.

Jim Dempsey

0 Kudos
andrew_4619
Honored Contributor II
404 Views

There are no circular dependencies in the code.It has a hierarchy of modules that avoids this.  Submodules has an all new level of flexibility to make life easier in this respect. The (probably circular) dependencies are due to a bug in the VS integration relating to the use of submodules in 16.0. The reproducer in post #5 of https://software.intel.com/en-us/forums/intel-visual-fortran-compiler-for-windows/topic/592084 demonstrates this.

 

0 Kudos
Kevin_D_Intel
Employee
404 Views

I confirmed the error #6834 shown from the combination of code segments from posts #1 and #3 (as reported it to Development per post #10) has been fixed in the latest PSXE 2016 Update 2 Release.

Re: (DPD200375981  & DPD200375984) as mentioned in post #13, refer to the other thread here for status.

0 Kudos
Reply