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

aligned_alloc and ifort/icc v17

Todor_K_
Novice
969 Views

I have a code that wraps aligned_alloc C function using iso_c_binding in a module. This code, when compiled with gfortran v4.8 and newer, has no issues. However, compiling it with ifort (v17.0.1) produces linkage problems such as: testalign.f90:(.text+0x40): undefined reference to `aligned_alloc' .

As I understand it, aligned_alloc is part of c11 standard so there may be a switch that takes care of this. 

So, the question is how to compile the code below with ifort v17?

If this is not possible, is there an Intel Fortran version that supports something like this? Of course, if aligned_alloc is not supported, then I will need to detect a compiler using some ugly preprocessor code and replace aligned_alloc with allocate.

Here's the (almost) minimal example:

module align                                                                                                                                                                                                                                   
                                                                                                                                                                                                                                               
                                                                                                                                                                                                                                               
implicit none                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                               
public !Default access for the module is public .                                                                                                                                                                                              
    interface                                                                                                                                                                                                                                  
        function aligned_alloc(alg, sz) bind(c)                                                                                                                                                                                                
            use, intrinsic :: iso_c_binding                                                                                                                                                                                                    
                                                                                                                                                                                                                                               
            implicit none                                                                                                                                                                                                                      
            integer(kind=c_size_t), intent(in), value :: alg                                                                                                                                                                                   
            integer(kind=c_size_t), intent(in), value :: sz                                                                                                                                                                                    
                                                                                                                                                                                                                                               
            type(c_ptr) :: aligned_alloc                                                                                                                                                                                                       
                                                                                                                                                                                                                                               
        end function  aligned_alloc                                                                                                                                                                                                            
                                                                                                                                                                                                                                               
    end interface                                                                                                                                                                                                                              
                                                                                                                                                                                                                                               
                                                                                                                                                                                                                                               
contains                                                                                                                                                                                                                                       
    subroutine res_align(p, n, alg)                                                                                                                                                                                                            
	use, intrinsic :: iso_c_binding                                                                                                                                                                                                        
                                                                                                                                                                                                                                               
        implicit none                                                                                                                                                                                                                          
        real(kind=c_double), intent(out), pointer, contiguous :: p(:)                                                                                                                                                                          
        integer, intent(in) :: n                                                                                                                                                                                                               
        integer, intent(in) :: alg                                                                                                                                                                                                             
                                                                                                                                                                                                                                               
        integer(kind=c_size_t) :: aalg                                                                                                                                                                                                         
        integer :: bytesz                                                                                                                                                                                                                      
        integer(kind=c_size_t) :: bbytesz                                                                                                                                                                                                      
        type(c_ptr) :: ptr                                                                                                                                                                                                                     
        bytesz=n*storage_size(p)/8                                                                                                                                                                                                             
        aalg=int(alg,kind=kind(aalg))                                                                                                                                                                                                          
        bbytesz=int(bytesz,kind=kind(bbytesz))                                                                                                                                                                                                 
        ptr=aligned_alloc(aalg,bbytesz)                                                                                                                                                                                                        
        if (.not. c_associated(ptr)) stop 'error(res_align): unsuccessful allocation'                                                                                                                                                          
        call c_f_pointer(ptr,p,)                                                                                                                                                                                                            
                                                                                                                                                                                                                                               
    end subroutine  res_align                                                                                                                                                                                                                  
end module  align                                                                                                                                                                                                                              
                                                                                                                                                                                                                                               
program test                                                                                                                                                                                                                                   
  use, intrinsic :: iso_c_binding                                                                                                                                                                                                              
  use align                                                                                                                                                                                                                                    
  implicit none                                                                                                                                                                                                                                
  real(kind=c_double), pointer, contiguous :: parr(:)                                                                                                                                                                                          
  integer, parameter :: alg=64                                                                                                                                                                                                                 
  integer, parameter :: sz=399                                                                                                                                                                                                                 
                                                                                                                                                                                                                                               
  call res_align(parr,sz,alg)                                                                                                                                                                                                                  
                                                                                                                                                                                                                                               
  parr=77.                                                                                                                                                                                                                                     
                                                                                                                                                                                                                                               
end program test                   

 

 

0 Kudos
1 Solution
Steve_Lionel
Honored Contributor III
969 Views

I suggest that you write a simple C program that references aligned_malloc, build it (using gcc) with a link map, and see where the reference is pulled from.  ifort uses the gcc libraries, so you may just need to add one that isn't referenced by default.

View solution in original post

0 Kudos
5 Replies
Steve_Lionel
Honored Contributor III
969 Views

How do you know you're even linking to a library containing this procedure?

Intel Fortran supports !DEC$ ATTRIBUTES ALIGN on ALLOCATABLE variables.

0 Kudos
Todor_K_
Novice
969 Views

Good question. I don't. I only know that, for gfortran, the function exists in whatever gfortran(gcc) links in automatically (libc, i guess). I don't know where to look in case of intel fortran/c.

0 Kudos
Todor_K_
Novice
969 Views

As far as the Intel compiler's alignment control directives, I am aware of that. However they are compiler specific, so this is a plan B.

0 Kudos
Steve_Lionel
Honored Contributor III
970 Views

I suggest that you write a simple C program that references aligned_malloc, build it (using gcc) with a link map, and see where the reference is pulled from.  ifort uses the gcc libraries, so you may just need to add one that isn't referenced by default.

0 Kudos
Todor_K_
Novice
969 Views

For the record, it turned out that on our cluster we have an ancient version of glibc (2010) installed together with the newest Intel compilers. This did not have aligned_alloc.

0 Kudos
Reply