- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
I am using Intel IFX 2024.2 compiler on Linux. I am trying to build my executable and dynamic libraries (on Linux) with thread sanitizer instrumented to detect data races. I am using '-fsanitize=thread' flags for both compiling as well as linking. However when I attempt to build any shared library I get linking errors like this:
" ... libclang_rt.tsan.a(tsan_interceptors_posix.cpp.o): relocation R_X86_64_TPOFF32 against `_ZL10pglob_copy' can not be used when making a shared object; recompile with -fPIC"
" ... libclang_rt.tsan.a(tsan_rtl.cpp.o): relocation R_X86_64_TPOFF32 against hidden symbol `_ZN6__tsan22cur_thread_placeholderE' can not be used when making a shared object"
" ... libclang_rt.tsan.a(tsan_preinit.cpp.o): .preinit_array section is not allowed in DSO"
"ld: failed to set dynamic section sizes: Nonrepresentable section on output"
All my libraries have the '-fPIC' compile flag. So I think the issue is with the TSAN runtime library included with the compiler. How can can I avoid these errors?
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
If there is a way to link against the shared version of the library (libclang_rt.tsan.so) will this problem go away?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Here's a minimal example (a translation of C++ example from Intel) to reproduce the error. When attempting to compile into library using the following command
ifx -shared -fPIC -fsanitize=thread -o libmergesort.so mergeSortMod.f90I get the following errors:
" ... libclang_rt.tsan.a(tsan_interceptors_posix.cpp.o): relocation R_X86_64_TPOFF32 against `_ZL10pglob_copy' can not be used when making a shared object; recompile with -fPIC"
" ... libclang_rt.tsan.a(tsan_rtl.cpp.o): relocation R_X86_64_TPOFF32 against hidden symbol `_ZN6__tsan22cur_thread_placeholderE' can not be used when making a shared object"
"... libclang_rt.tsan.a(tsan_preinit.cpp.o): .preinit_array section is not allowed in DSO"
"ld: failed to set dynamic section sizes: Nonrepresentable section on output"
! Fortran Implementation of Intel C++ Code Example
module MergeSortModule
use omp_lib
implicit none
integer, parameter :: task_threshold = 5000 ! Threshold for creating OpenMP tasks
integer :: my_counter = 0 ! Counter to track function calls
contains
! Description: Initializes the array and shuffles the elements.
subroutine InitializeArray(a, n)
integer, intent(inout) :: a(:)
integer, intent(in) :: n
integer :: i, tmp, j
! Initialize the array
do i = 1, n
a(i) = i - 1
end do
print *, "Shuffling the array"
! Shuffle the array (Fisher-Yates Shuffle Algorithm)
call random_seed()
do i = n, 2, -1
call random_number(tmp)
j = floor(tmp * real(i)) + 1
tmp = a(i)
a(i) = a(j)
a(j) = tmp
end do
end subroutine InitializeArray
! Description: Checks if the array is correctly sorted
function CheckArray(a, n) result(error_flag)
integer, intent(in) :: a(:)
integer, intent(in) :: n
integer :: i, error_flag
error_flag = 0 ! Assume no errors
do i = 1, n - 1
if (a(i) >= a(i + 1) .or. a(i) /= (i - 1)) then
print *, "Sort failed at location", i, ", a(i)=", a(i), " a(i+1)=", a(i + 1)
error_flag = 1
return
end if
end do
end function CheckArray
! Description: Merges two sublists of the array
subroutine Merge(a, tmp_a, first, middle, last)
integer, intent(inout) :: a(:), tmp_a(:)
integer, intent(in) :: first, middle, last
integer :: p1, p2, p, i
p1 = first
p2 = middle
p = first
! Merge two portions of the array into the temporary array
do while (p <= last)
if (p1 < middle .and. (p2 > last .or. a(p1) < a(p2))) then
tmp_a(p) = a(p1)
p1 = p1 + 1
else
tmp_a(p) = a(p2)
p2 = p2 + 1
end if
p = p + 1
end do
! Copy the sorted portion back to the original array
do i = first, last
a(i) = tmp_a(i)
end do
end subroutine Merge
! Description: Recursive MergeSort algorithm
recursive subroutine MergeSort(a, tmp_a, first, last)
integer, intent(inout) :: a(:), tmp_a(:)
integer, intent(in) :: first, last
integer :: middle
if (first < last) then
middle = (first + last + 1) / 2
call MergeSort(a, tmp_a, first, middle - 1)
call MergeSort(a, tmp_a, middle, last)
call Merge(a, tmp_a, first, middle, last)
end if
end subroutine MergeSort
! Description: OpenMP Task-based version of MergeSort
recursive subroutine MergeSortOpenMP(a, tmp_a, first, last)
integer, intent(inout) :: a(:), tmp_a(:)
integer, intent(in) :: first, last
integer :: middle
if (first < last) then
middle = (first + last + 1) / 2
if (last - first < task_threshold) then
call MergeSort(a, tmp_a, first, middle - 1)
call MergeSort(a, tmp_a, middle, last)
else
!$omp task
call MergeSortOpenMP(a, tmp_a, first, middle - 1)
!$omp task
call MergeSortOpenMP(a, tmp_a, middle, last)
!$omp taskwait
end if
call Merge(a, tmp_a, first, middle, last)
my_counter = my_counter + 1
end if
end subroutine MergeSortOpenMP
end module MergeSortModule
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
There is small error in the call to random_number subroutine in the code snippet above. It needs a real argument 'rtmp' instead of integer 'tmp'. This needs to be declared as well.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The code snippet to reproduce the errors is below.
The command I tried is
ifx -shared -fPIC -fsanitize=thread -o libmergesort.so mergeSortMod.f90! Modern Fortran Implementation of the Given C++ Code
module MergeSortModule
use omp_lib
implicit none
integer, parameter :: task_threshold = 5000 ! Threshold for creating OpenMP tasks
integer :: my_counter = 0 ! Counter to track function calls
contains
! Description: Initializes the array and shuffles the elements.
subroutine InitializeArray(a, n)
integer, intent(inout) :: a(:)
integer, intent(in) :: n
integer :: i, tmp, j
real :: rtmp
! Initialize the array
do i = 1, n
a(i) = i - 1
end do
print *, "Shuffling the array"
! Shuffle the array (Fisher-Yates Shuffle Algorithm)
call random_seed()
do i = n, 2, -1
call random_number(rtmp)
j = floor(rtmp * real(i)) + 1
tmp = a(i)
a(i) = a(j)
a(j) = tmp
end do
end subroutine InitializeArray
! Description: Checks if the array is correctly sorted
function CheckArray(a, n) result(error_flag)
integer, intent(in) :: a(:)
integer, intent(in) :: n
integer :: i, error_flag
error_flag = 0 ! Assume no errors
do i = 1, n - 1
if (a(i) >= a(i + 1) .or. a(i) /= (i - 1)) then
print *, "Sort failed at location", i, ", a(i)=", a(i), " a(i+1)=", a(i + 1)
error_flag = 1
return
end if
end do
end function CheckArray
! Description: Merges two sublists of the array
subroutine Merge(a, tmp_a, first, middle, last)
integer, intent(inout) :: a(:), tmp_a(:)
integer, intent(in) :: first, middle, last
integer :: p1, p2, p, i
p1 = first
p2 = middle
p = first
! Merge two portions of the array into the temporary array
do while (p <= last)
if (p1 < middle .and. (p2 > last .or. a(p1) < a(p2))) then
tmp_a(p) = a(p1)
p1 = p1 + 1
else
tmp_a(p) = a(p2)
p2 = p2 + 1
end if
p = p + 1
end do
! Copy the sorted portion back to the original array
do i = first, last
a(i) = tmp_a(i)
end do
end subroutine Merge
! Description: Recursive MergeSort algorithm
recursive subroutine MergeSort(a, tmp_a, first, last)
integer, intent(inout) :: a(:), tmp_a(:)
integer, intent(in) :: first, last
integer :: middle
if (first < last) then
middle = (first + last + 1) / 2
call MergeSort(a, tmp_a, first, middle - 1)
call MergeSort(a, tmp_a, middle, last)
call Merge(a, tmp_a, first, middle, last)
end if
end subroutine MergeSort
! Description: OpenMP Task-based version of MergeSort
recursive subroutine MergeSortOpenMP(a, tmp_a, first, last)
integer, intent(inout) :: a(:), tmp_a(:)
integer, intent(in) :: first, last
integer :: middle
if (first < last) then
middle = (first + last + 1) / 2
if (last - first < task_threshold) then
call MergeSort(a, tmp_a, first, middle - 1)
call MergeSort(a, tmp_a, middle, last)
else
!$omp task
call MergeSortOpenMP(a, tmp_a, first, middle - 1)
!$omp task
call MergeSortOpenMP(a, tmp_a, middle, last)
!$omp taskwait
end if
call Merge(a, tmp_a, first, middle, last)
my_counter = my_counter + 1
end if
end subroutine MergeSortOpenMP
end module MergeSortModule
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page