What is the maximum character length allowed?

What is the maximum character length allowed?

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

 

10 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

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 

Thanks Kevin,

That was it.

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

www.quickthreadprogramming.com

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.

Retired 12/31/2016

@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.

Quote:

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.

 

 

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.

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.

Retired 12/31/2016

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

www.quickthreadprogramming.com

Leave a Comment

Please sign in to add a comment. Not a member? Join today