- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I have a (somewhat cutdown) VS2019 solution using oneAPI 2022.1 that contains a DLL with two static library dependencies that produces a couple of duplicate symbol errors when linking:
1>------ Build started: Project: iw2d_sim1D (IFX), Configuration: Debug x64 ------
1>Linking...
1>lld-link: error: duplicate symbol: .omp.mold_ctor
1>>>> defined at Debug.x64/iw2d_1D_process.obj
1>>>> defined at iw2d_simlib.lib(iw2d_type_model.obj)
1>lld-link: error: duplicate symbol: .omp.dtor
1>>>> defined at Debug.x64/iw2d_1D_process.obj
1>>>> defined at iw2d_simlib.lib(iw2d_type_model.obj)
1>
1>Build log written to "file://C:\Source\repos\oneAPI_2022_1_5\infoworks_2d\iw_2d_sim\iw2d_sim1D\Debug.x64\BuildLog.htm"
1>iw2d_sim1D - 2 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 2 up-to-date, 0 skipped =========
- I can't share the solution as is, because the code is commercial confidential and could do with much more cutting down to submit as a reproducer, in my opinion.
- (DLL) iw2d_sim1D depends on (static libraries) iw2d_simlib & simlib.
- simlib is compiled with IFORT, the other two projects with IFX.
- Both iw2d_sim1D & iw2d_simlib contain OpenMP directives and are compiled with /Qiopenmp (Fortran->Language->OpenMP support->Generate Parallel Code).
- The solution links successfully if I disable OpenMP support in iw2d_sim1D , but this would lead to degraded performance, so wouldn't be desirable. In any case, see point 6 below.
- The original full solution uses IFORT and links/works fine with 2021.3 and 2021.5.
Has anybody encountered anything similar and submitted it to Intel Support? If not, I'll try to produce a more suitable reproducer.
As an aside, my experience so far with IFX has not been positive: I have 4 open support cases and there are at least another couple of issues I could report, if I get time to create reproducers. To be honest, I have only got round to testing IFX with our code in 2022.1 because the previous versions didn't support the subset of Fortran 2003 and 2008 we use. I don't think our code is particularly esoteric and compiles fine with GNU Fortran as well as IFORT.
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The Intel OpenMP developers told us to use /Qopenmp, instead of, /Qiopenmp. You'll get some Intel secret sauce for better performance especially for using the GPU.
I have no idea if that relates to your issue though.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
@Barbara_P_Intel I don't think the use of /Qopenmp v /Qiopenmp is relevant here. The original ifort project used /Qopenmp and had the same duplicate symbol issue when I changed the relevant projects to use IFX.
I switched to using /Qiopenmp to see if that would help and also because the release notes suggest "-fopenmp is deprecated and may be removed in a future release. Use -fiopenmp instead."
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I don't know that /Qopenmp v /Qiopenmp matters either. I just thought to add a bit of info.
According to the Fortran Developer Guide and Reference
-
Option -fopenmp has been deprecated, use option -qopenmp or option -fiopenmp
I'll clarify that in the Release Notes. (Glad to know that SOMEONE read those.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
It's awkward, but try compiling iw2d_sim1D with ifort and Qopenmp and use that object file in your final executable or library to avoid the performance issues.
Now to the underlying problem.
These entry points are created for FIRSTPRIVATE variables when the datatype of the variable is a derived type with allocatable components.
Does this describe some of your data usage?
If so, what is the usage-pattern of this data; is it defined in a module that is USEd by both a iw2d_sim1D and by iw2d_simd.lib? Or, are there multiple instances of the derived type, separately defined/declared between the two entities?
I'm really just trying to find the "pattern" to make it easier to create a reproducer.
Thanks --
--Lorri
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
@Lorri_M_Intel Thanks for the suggestions. My current (still huge) reproducer no longer has any FIRSTPRIVATE variables, but it looks like the PRIVATE clause also creates those entry points if the variable is a derived type with allocatable components.
An example in the module iw2d_type_model that produces these entry points is
subroutine model_apply_elem2_sub1(sub, array_size, aux, this)
!$ use omp_lib
procedure(elem_model_sub) :: sub
integer, intent(in) :: array_size
integer, dimension(array_size), intent(in) :: aux
type(model), intent(inout) :: this
type(element), pointer :: elem_
integer :: i
integer :: threads
logical :: do_in_parallel
integer, parameter :: parallel_threshold = generic_parallel_threshold ! Enable parallel code path with > 1 thread
integer :: num_data
! The following statement is only compiled when OpenMP directives are processed
!$ threads = omp_get_max_threads()
num_data = array_size
do_in_parallel = (threads > 1) .and. (num_data > parallel_threshold)
if (.not.do_in_parallel) threads = 1
call iw2d_set_in_parallel(.true.)
!$OMP parallel &
!$OMP & if(do_in_parallel) &
!$OMP & private (elem_) &
!$OMP & shared (array_size, this)
!$OMP do schedule(guided,128)
do i = 1, array_size
elem_ => model_get_elem(this, aux(i))
call sub(elem_, this)
end do
!$OMP end do
!$OMP end parallel
call iw2d_set_in_parallel(.false.)
end subroutine
Type element contains allocatable components. One way to eliminate the private clause and the generation of the entry points is to put the contents of the loop inside a contained subroutine with elem_ declared as a local variable in the contained subroutine instead of the host. There is code in iw2d_sim1D that uses a similar idiom, but with a different derived type that contains allocatable components.
Another workaround would be to just call sub(model_get_elem(this, aux(i)), this) and eliminate the need for elem_.
I'll see if I can come up with a small reproducer based on this and submit it to support.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page