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

What is the maximum character length allowed?

fuji_s_
Beginner
2,804 Views

Hello,

I wrote this simple code (see below) that converts an array of real into a very long string of characters.
I have been running this little code on 2 different machines and I compiled it with the same compler on both machines :

Intel(R) Fortran Intel(R) 64 Compiler XE for applications running on Intel(R) 64, Version 14.0.1.106 Build 20131008
Copyright (C) 1985-2013 Intel Corporation.  All rights reserved.

Both machines are equipped with Intel processors,

  1. one with processors like : Intel(R) Xeon(R) CPU E5472  @ 3.00GHz
  2. and the other one with processor like : Intel(R) Xeon(R) CPU E5506  @ 2.13GHz

While on machine 1, the code works fine, on machine 2, I get a "Segmentation fault (core dumped)" message most of the time with n = 2093504.

So, is there a maximum character length allowed that is machine-dependant? How can I know this maximum?

Regards,
F.
 

program test

        implicit none

        integer :: i
        real, allocatable :: cube(:)
        integer :: n, length

        n = 2093503 ! OK
        n = 2093504 ! Segmentation fault
        length = 4*n
        write(*,*) n, length
        if (.not. allocated(cube)) allocate(cube(n))

        do i = 1, n
            call random(cube(i))
        end do

        call sub(cube, n, length)

    end program

    subroutine sub(array, n, length)

        implicit none

        integer :: n, len
        real :: array(n), f
        character(length) :: buf
        character(4) :: c
        integer :: i

        equivalence(f, c)

        write(*,*) n, length
        do i = 1, n
            f = array(i)

            buf(4*(i-1)+1:4*(i-1)+4) = c(1:4)
        end do

    end subroutine sub

 

0 Kudos
9 Replies
Kevin_D_Intel
Employee
2,804 Views

The issue on the system that fails relates to exhausting the available shell stack space related to the creation of stack-based arrays.

You can check the shell stack space with either ulimit -s (bash) or limit stacksize (csh).

To change either, use:   ulimit -s <value>   or limit stacksize <value>, where <value> is specified in kbytes. <value> can also be specified as: unlimited

For additional information about this type of failure refer to Determining Root Cause of Segmentation Faults SIGSEGV or SIGBUS errors 

0 Kudos
fuji_s_
Beginner
2,804 Views

Thanks Kevin,

That was it.

0 Kudos
jimdempseyatthecove
Honored Contributor III
2,804 Views

The correct way to have fixed this is with the foreknowledge that "length" is very large in

character(length) :: buf

would be to use:

character(:), allocatable :: buf
...
allocate (character(length)::buf)

The "ulimit" is fine if, and only if, the program is, and will always remain, single threaded.

BTW insert a test for allocation failure such that you can take appropriate action.

Jim Dempsey

0 Kudos
Steven_L_Intel1
Employee
2,804 Views

You can search the documentation index for "compiler limits". Online, the page for that is here.

I note that we don't document a limit for character lengths - the theoretical limit is 2**31-1 for IA-32 and 2**63-1 for Intel 64. I will suggest that we add this to the documentation.

0 Kudos
fuji_s_
Beginner
2,804 Views

@Jim, I learned something. I didn't know one could do this : allocate (character(length)::buf)
I'll try that.

@Steve, good idea.

Thank you.

F.

0 Kudos
FortranFan
Honored Contributor III
2,804 Views

fuji s. wrote:

@Jim, I learned something. I didn't know one could do this : allocate (character(length)::buf)

...

Do not forget to add the allocation status test as suggested by Jim:

    ALLOCATE( CHARACTER(LEN=DesiredLength) :: buf, STAT=IntErrorCodeVar)
    IF (IntErrorCodeVar /= 0) THEN
       !.. Handle the error

It's good to do so as a general practice, but especially important in your case as your string length will be stretching your system resources.

 

 

0 Kudos
fuji_s_
Beginner
2,804 Views

Hello,

I tried to allocate a character string works and it works well too even when the stacksize is low.

Thank you all for your help.

F.

0 Kudos
Steven_L_Intel1
Employee
2,804 Views

You rarely have to explicitly allocate an allocatable, deferred-length character value. Just assign to it and the allocation is handled automatically. However, if you are passing such a variable to a procedure which writes to it, you may need to allocate it first.

0 Kudos
jimdempseyatthecove
Honored Contributor III
2,804 Views

You also may want to explicitly allocate the deferred-length character value when you know the length is very large and may experience an allocation failure. (Such as in the original poster's example.)

Jim Dempsey

0 Kudos
Reply