- Marquer comme nouveau
- Marquer
- S'abonner
- Sourdine
- S'abonner au fil RSS
- Surligner
- Imprimer
- Signaler un contenu inapproprié
Hi!
I face a problem which I did not succeed to solve despite several trials based on clues found here and elsewhere on the internet…
I gathered several functions and procedures in a module ‘mymod.f90'. Some of these procedures are calling other functions or procedures within the same module. I also have a program ‘myprog’ using the module. These files are in attachment.
I compiled the module without error with ifort –c mymod.f90 and get files ‘mymod.obj’ and ‘mymod.mod’ created
Then, when I try to compile with ifort mymod.obj myprog.f I have the following errors:
c:\Users>ifort mymod.obj myprog.f
Intel(R) Visual Fortran Intel(R) 64 Compiler XE for applications running on Intel(R) 64, Version 14.0.3.202 Build 20140422
Copyright (C) 1985-2014 Intel Corporation. All rights reserved.
Microsoft (R) Incremental Linker Version 10.00.40219.01
Copyright (C) Microsoft Corporation. All rights reserved.
-out:mymod.exe
-subsystem:console
mymod.obj
myprog.obj
mymod.obj : error LNK2019: unresolved external symbol I1MACH referenced in function MYMOD_mp_INTEXJX
mymod.obj : error LNK2019: unresolved external symbol ZABS referenced in function MYMOD_mp_INTEXJX
myprog.obj : error LNK2019: unresolved external symbol DQAG referenced in function MAIN__
mymod.exe : fatal error LNK1120: 3 unresolved externals
I could solve such errors by removing declarations of variables corresponding to call of functions defined within the module (e.g., variable D1MACH in lines 51,361, 1664,… and variable DGAMLN in lines 3261, 4459 and 4162 of module mymod), as recommended somewhere on this forum. Yet, this did not work for I1MACH and ZABS, for which I get type definition errors. For instance, when removing declaration of variable I1MACH at line 1067 of mymod, I get the following:
c:\Users>ifort –c mymod.f90
Intel(R) Visual Fortran Intel(R) 64 Compiler XE for applications running on Intel(R) 64, Version 14.0.3.202 Build 20140422
Copyright (C) 1985-2014 Intel Corporation. All rights reserved.
mymod.f90(1094): error #6404: This name does not have a type, and must have an explicit type. [I1MACH]
K1 = I1MACH(15)
-----------^
mymod.f90(1116): error #6362: The data types of the argument(s) are invalid. [FLOAT]
BB=DBLE(FLOAT(I1MACH(9)))*0.5D0
--------------------^
compilation aborted for mymod.f90 (code 1)
Besides, I do not know how to solve the error for procedure DQAG called in myprog.
For further information, the code works when compiling it with functions and procedures in separate files. Yet, I decided to use a module as I got problem when attempting to parallelize the code with OpenMP (i.e. the ‘do loop’ at line 51 in myprog), apparently because of threads interacting on some variables (though these were declared as private and subroutines as recursive, according to recommendations found on the web in this regard). I read that working with module might solve it.
Hope someone can help. Thank you very much in advance!
Fred
- Balises:
- Intel® Fortran Compiler
- Marquer comme nouveau
- Marquer
- S'abonner
- Sourdine
- S'abonner au fil RSS
- Surligner
- Imprimer
- Signaler un contenu inapproprié
You have three problems to fix in your code.
- Do not apply PRIVATE to subprogram names inside a module that you plan to call from outside the module.
- Do not declare EXTERNAL those subprogram names that are accessible through a USE statement or are contained in the same module.
- Provide missing function subprogram I1MACH(); perhaps the one at www.netlib.org/slatec/src/i1mach.f will do.
There are several source lines that are longer than 132 characters, and these may give you trouble with other compilers. The source code in the module is in need of clean-up; in particular, many specific names of Fortran intrinsics are given EXTERNAL declarations. You will have to fix these declarations, and possibly replace specific names with generic names.
I removed the lines from "MODULE..." to "CONTAINS" and the last line, "END MODULE", and the program could be built when I used the I1MACH from Netlib. It needs a data file to be run.
From what I have seen, the objective of your program is to calculate an integral using numerical quadrature routines from QUADPACK. A clean solution would be possible if you used the F90 interface available provided in IMSL to QUADPACK.
Lien copié
- Marquer comme nouveau
- Marquer
- S'abonner
- Sourdine
- S'abonner au fil RSS
- Surligner
- Imprimer
- Signaler un contenu inapproprié
You have three problems to fix in your code.
- Do not apply PRIVATE to subprogram names inside a module that you plan to call from outside the module.
- Do not declare EXTERNAL those subprogram names that are accessible through a USE statement or are contained in the same module.
- Provide missing function subprogram I1MACH(); perhaps the one at www.netlib.org/slatec/src/i1mach.f will do.
There are several source lines that are longer than 132 characters, and these may give you trouble with other compilers. The source code in the module is in need of clean-up; in particular, many specific names of Fortran intrinsics are given EXTERNAL declarations. You will have to fix these declarations, and possibly replace specific names with generic names.
I removed the lines from "MODULE..." to "CONTAINS" and the last line, "END MODULE", and the program could be built when I used the I1MACH from Netlib. It needs a data file to be run.
From what I have seen, the objective of your program is to calculate an integral using numerical quadrature routines from QUADPACK. A clean solution would be possible if you used the F90 interface available provided in IMSL to QUADPACK.
- Marquer comme nouveau
- Marquer
- S'abonner
- Sourdine
- S'abonner au fil RSS
- Surligner
- Imprimer
- Signaler un contenu inapproprié
Thank you very much for your prompt reply!
I have applied your recommendations could successfully built the program and make it run. So I am now ready for the next step: parallelization...
I indeed inadvertently did not include i1mach.
Regarding the PRIVATE statement, I used it to ensure that all variables and procedures/functions declared in the module have a separate copy for each thread of this (future) parallel section. But this statement indeed generated the error for DQAG. To work around this problem, I used PUBLIC :: DQAG. Is there any other way to ensure independent copies amongst threads of all involved variables, i.e., to avoid threads interaction on variables as I apparently had before?
- Marquer comme nouveau
- Marquer
- S'abonner
- Sourdine
- S'abonner au fil RSS
- Surligner
- Imprimer
- Signaler un contenu inapproprié
PUBLIC and PRIVATE are not storage-related. They affect the visibility of symbols inherited from a module. You're looking for the PRIVATE clause on an OpenMP directive.
- Marquer comme nouveau
- Marquer
- S'abonner
- Sourdine
- S'abonner au fil RSS
- Surligner
- Imprimer
- Signaler un contenu inapproprié
OK, great! Thanks for the clarification!
- Marquer comme nouveau
- Marquer
- S'abonner
- Sourdine
- S'abonner au fil RSS
- Surligner
- Imprimer
- Signaler un contenu inapproprié
You have resolved the issue of the visibility of DQAG correctly.
Regarding the thread safety question: do you have any variables that are passed through COMMON or module variables accessed by USE? If so, you would have to ensure that only one thread modifies those variables and that the modifications are completed before you pass control to the other threads in which those variables are referenced.
There are tools such as the Intel Inspector XE for debugging threading problems.
- Marquer comme nouveau
- Marquer
- S'abonner
- Sourdine
- S'abonner au fil RSS
- Surligner
- Imprimer
- Signaler un contenu inapproprié

- S'abonner au fil RSS
- Marquer le sujet comme nouveau
- Marquer le sujet comme lu
- Placer ce Sujet en tête de liste pour l'utilisateur actuel
- Marquer
- S'abonner
- Page imprimable