Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
Announcements
FPGA community forums and blogs have moved to the Altera Community. Existing Intel Community members can sign in with their current credentials.

generic module procedure problem

Li_Dong
Beginner
631 Views
Hi all,

I have written a module which I want to add a new subroutine without disturbing the previous one, so I want to wrap them with an interface, say:

[cpp]subroutine file_io_output_1(label, file_name, folder_name, card_name, buf, nd, dims)
    character(*), intent(in) :: label
    character(*), intent(in) :: file_name
    character(*), intent(in) :: folder_name
    character(*), intent(in) :: card_name
    real, intent(in) :: buf(*)
    integer, intent(in) :: nd
    integer, intent(in) :: dims(*)

subroutine file_io_output_2(label, file_name, card_name, buf, nd, dims)
    character(*), intent(in) :: label
    character(*), intent(in) :: file_name
    character(*), intent(in) :: card_name
    real, intent(in) :: buf(*)
    integer, intent(in) :: nd
    integer, intent(in) :: dims(*)

interface file_io_output
    module procedure file_io_output_1
    module procedure file_io_output_2
end interface file_io_output[/cpp]

When I compiled the program, it complained:

error #6285: There is no matching specific subroutine for this generic subroutine call. [FILE_IO_OUTPUT]

It is more strange that I have two program files calling "file_io_output" with the same pattern of arguments (file_io_output_1), the first one is successfully compiled, but the second one failed. What's wrong?

Thank you for help!

DONG Li
0 Kudos
4 Replies
Steven_L_Intel1
Employee
631 Views
Please show the call that fails and the declarations of all its arguments.
0 Kudos
Li_Dong
Beginner
631 Views
Please show the call that fails and the declarations of all its arguments.

Hi Steve,

The calling that passed the compilation is:

[plain]call file_io_output(trim(label), output_file, module_name, &
    "parcel_"//trim(q_name(i)), q(:,i), 1, (/nq/))

character(20) :: label
character(50) :: output_file
character(50) :: module_name
integer :: nq
character(8) :: q_name(nq)
real :: q(np,nq) ! np is another integer variable[/plain]

The calling that failed the compilation is:

[plain]call file_io_output("constant", output_file, folder_name, &
    "mesh_"//trim(x_name(i)), x(:,:,:,i), 3, num_grid)

character(50) :: output_file
character(50) :: folder_name ! identical to module_name previously
character(8) :: x_name(nd) ! nd is an integer variable
integer :: num_grid(3)
real, allocatable :: x(:,:,:,:) ! The actual dimensions are num_grid(1) X num_grid(2) X num_grid(3) X nd [/plain]

Before I added "file_io_output_2", the compilation is ok. So what is the side effect of interface "file_io_output"?

Thank you for help!

DONG Li
0 Kudos
Hirchert__Kurt_W
New Contributor II
631 Views
Quoting - DONG Li
Before I added "file_io_output_2", the compilation is ok. So what is the side effect of interface "file_io_output"?

I assume that before you added file_io_output_2, you weren't using using a generic interface.

When you invoke a specific name, an assumed size argument like buf can be associated with an actual argument of any rank. Thus, you could associate it with that 3-dimensional subsection of x, even though buf is declared 1-dimensional.

Once you were using a generic interface, rank is one of the attributes used to select the appropriate specific routine, so a 3-dimensional actual argument now requires a 3-dimensional dummy argument. Since your generic interface didn't have one of those, you got an error message. (In the example that worked with the generic interface, you were passing a 1-dimensional subsection of q, so ranks matched.)

If you wanted to make this work, you could add to the generic interface another routine (say "file_io_ouput_1_3d") with the same arguments as file_io_ouput_1 except that buf is buf(:,:,:) instead of buf(*). This routine could then directly call the specific file_io_output_1 to actually do the work. (Because this would be a direct call to the specific, instead of a call to the generic, the rank mismatch would again be allowed.)

-Kurt

If you create these additional "glue" routines with assumed-shape buf arguments to match various dimensionalities, you could create versions with no nd or dims arguments, as these can be recreated with an appropriate constant and shape(buf) respecitively.

I believe I read that Fortran 2008 will have a feature that would allow "assumed-rank" arrays, but since the Fortran 2008 draft has not yet been formally adopted, I expect is will be quite some time before such a feature would make its way into ifort.


0 Kudos
Li_Dong
Beginner
631 Views
Quoting - hirchert

I assume that before you added file_io_output_2, you weren't using using a generic interface.

When you invoke a specific name, an assumed size argument like buf can be associated with an actual argument of any rank. Thus, you could associate it with that 3-dimensional subsection of x, even though buf is declared 1-dimensional.

Once you were using a generic interface, rank is one of the attributes used to select the appropriate specific routine, so a 3-dimensional actual argument now requires a 3-dimensional dummy argument. Since your generic interface didn't have one of those, you got an error message. (In the example that worked with the generic interface, you were passing a 1-dimensional subsection of q, so ranks matched.)

If you wanted to make this work, you could add to the generic interface another routine (say "file_io_ouput_1_3d") with the same arguments as file_io_ouput_1 except that buf is buf(:,:,:) instead of buf(*). This routine could then directly call the specific file_io_output_1 to actually do the work. (Because this would be a direct call to the specific, instead of a call to the generic, the rank mismatch would again be allowed.)

-Kurt

If you create these additional "glue" routines with assumed-shape buf arguments to match various dimensionalities, you could create versions with no nd or dims arguments, as these can be recreated with an appropriate constant and shape(buf) respecitively.

I believe I read that Fortran 2008 will have a feature that would allow "assumed-rank" arrays, but since the Fortran 2008 draft has not yet been formally adopted, I expect is will be quite some time before such a feature would make its way into ifort.



Hi hirchert,

Thank you for your detail explanation!

DONG Li
0 Kudos
Reply