From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 22067 invoked by alias); 10 May 2014 06:16:05 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 22047 invoked by uid 89); 10 May 2014 06:16:04 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.0 required=5.0 tests=AWL,BAYES_00 autolearn=ham version=3.3.2 X-Spam-User: qpsmtpd, 2 recipients X-HELO: mx01.qsc.de Received: from mx01.qsc.de (HELO mx01.qsc.de) (213.148.129.14) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-SHA encrypted) ESMTPS; Sat, 10 May 2014 06:16:02 +0000 Received: from tux.net-b.de (port-92-194-125-118.dynamic.qsc.de [92.194.125.118]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mx01.qsc.de (Postfix) with ESMTPSA id C66D23CD3E; Sat, 10 May 2014 08:15:58 +0200 (CEST) Message-ID: <536DC41D.3070301@net-b.de> Date: Sat, 10 May 2014 06:16:00 -0000 From: Tobias Burnus User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Thunderbird/24.4.0 MIME-Version: 1.0 To: Jakub Jelinek CC: gcc-patches@gcc.gnu.org, fortran@gcc.gnu.org Subject: Re: [PATCH] Fortran OpenMP 4.0 support, part 1 References: <20140507205303.GF10386@tucnak.redhat.com> <536D2DE7.8060701@net-b.de> <20140509202259.GO10386@tucnak.redhat.com> In-Reply-To: <20140509202259.GO10386@tucnak.redhat.com> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-SW-Source: 2014-05/txt/msg00663.txt.bz2 Jakub Jelinek wrpte: > On Fri, May 09, 2014 at 09:35:03PM +0200, Tobias Burnus wrote: >> Fortran - as also C and C++ - does not provide much support for >> aligned memory. [Well, C++ has now alignas and align(ment_)of.] But >> contrary to C/C++, using library functions for dynamic allocation is >> more difficult and gfortran doesn't support GCC's align attribute for >> non-heap allocation. I only know of one commercial compiler, which >> has alignment directives (for static and dynamically allocated >> memory). I also was considering adding support for it - but I haven't >> found the time to do so, yet. > Yeah, but besides alignas/_Alignas in C/C++ one has also posix_memalign etc. That's what I meant with calling library functions. But posix_memalign is restricted to POSIX systems while _mm_malloc only works on i*86 and x86_64 systems. > The OpenMP standard allows for aligned clause: > C_PTR or Cray pointer, or var with POINTER or ALLOCATABLE attribute. > so best would be to actually test all of those, but supposedly one can't > really test it e.g. with ALLOCATABLE attribute, unless say the test is > restricted to x86_64-linux or similar platform where we know glibc malloc > allocates 16 byte aligned chunks at least and we rely on libgfortran to use > glibc malloc. Well, as written before, you could use the manual alignment as I suggested before. My code assumes that malloc returns memory which is aligned to sizeof(data type); I think one can assume that this is aligned to at least 4-byte or sizeof(void*). I think that should be sufficient; if not, one can also first align the memory down to byte level and then associate it with a pointer variable. That should work with all sizeof(data type). Below, you have a small program which gives you access to C_PTR, Cray pointer and POINTER; combining ALLOCATABLE with aligned memory is more difficult. BTW: gfortran doesn't call libgfortran for allocating the memory but uses BUILTIN_MALLOC directy (since GCC 4.2?). Tobias program align_test use iso_c_binding implicit none real, target :: x, array1(1024) real, allocatable, target :: array2(:) real, pointer :: ptr(:) integer(c_ptrdiff_t) :: offset1 integer(c_ptrdiff_t) :: offset2 integer, parameter :: ALIGNVALUE = 128 offset1 = ALIGNVALUE - mod (loc (array1), ALIGNVALUE) if (offset1 == ALIGNVALUE) & offset1 = 0 offset1 = offset1/c_sizeof(x) allocate (array2(-5:1024)) offset2 = ALIGNVALUE - mod (loc (array2), ALIGNVALUE) if (offset2 == ALIGNVALUE) & offset2 = 0 offset2 = offset2/c_sizeof(x) ! Use a lower bound which is not "1" ! For some reasons, the following does not align the memory! !ptr(-5:) => array2(lbound(array2,dim=1)+offset2 :) ptr => array2(lbound(array2,dim=1)+offset2 :) call some_subroutine(array1(lbound(array1,dim=1)+offset1 : ), ptr) contains subroutine some_subroutine(a, b) real, pointer, intent(in) :: a(:), b(:) type(c_ptr) :: c ! Use an explicit size for the Cray pointer; can also be '*' instead real :: arr(1024-ALIGNVALUE) pointer (pt, arr) if (mod (loc(a), ALIGNVALUE) /= 0) & call abort() if (mod (loc(b), ALIGNVALUE) /= 0) & call abort() c = c_loc(a) pt = loc(b) ! ... end subroutine some_subroutine end program align_test