Data alignment inside a structure in Intel Fortran











up vote
3
down vote

favorite












I'm trying to align in memory the following type of data:



type foo
real, allocatable, dimension(:) :: bar1, bar2
!dir$ attributes align:64 :: bar1
!dir$ attributes align:64 :: bar2
end type foo

type(foo), allocatable, dimension(:) :: my_foo
allocate(my_foo(1))
allocate(my_foo(1)%bar1(100))
allocate(my_foo(1)%bar2(100))

! somewhere here I need to tell the compiler that data is aligned
! for a simple array with name `bar` I would just do:
!dir$ assume_aligned bar1: 64
!dir$ assume_aligned bar2: 64
! but what do I do for the data type I have, something like this?
!dir$ assume_aligned my_foo(1)%bar1: 64
!dir$ assume_aligned my_foo(1)%bar2: 64

do i = 1, 100
my_foo(1)%bar1(i) = 10.
my_foo(1)%bar2(i) = 10.
end do


As you can see, it's an array of foo type structures, that has two large arrays bar1 and bar2 as variables that I need to be aligned near cache boundaries in the memory.



I kind of know how to do that for simple arrays (link), but I have no idea how to do that for this sort of complex data structure. And what if my_foo wasn't of size 1, but was of size, say, 100? Do I loop through them?










share|improve this question




























    up vote
    3
    down vote

    favorite












    I'm trying to align in memory the following type of data:



    type foo
    real, allocatable, dimension(:) :: bar1, bar2
    !dir$ attributes align:64 :: bar1
    !dir$ attributes align:64 :: bar2
    end type foo

    type(foo), allocatable, dimension(:) :: my_foo
    allocate(my_foo(1))
    allocate(my_foo(1)%bar1(100))
    allocate(my_foo(1)%bar2(100))

    ! somewhere here I need to tell the compiler that data is aligned
    ! for a simple array with name `bar` I would just do:
    !dir$ assume_aligned bar1: 64
    !dir$ assume_aligned bar2: 64
    ! but what do I do for the data type I have, something like this?
    !dir$ assume_aligned my_foo(1)%bar1: 64
    !dir$ assume_aligned my_foo(1)%bar2: 64

    do i = 1, 100
    my_foo(1)%bar1(i) = 10.
    my_foo(1)%bar2(i) = 10.
    end do


    As you can see, it's an array of foo type structures, that has two large arrays bar1 and bar2 as variables that I need to be aligned near cache boundaries in the memory.



    I kind of know how to do that for simple arrays (link), but I have no idea how to do that for this sort of complex data structure. And what if my_foo wasn't of size 1, but was of size, say, 100? Do I loop through them?










    share|improve this question


























      up vote
      3
      down vote

      favorite









      up vote
      3
      down vote

      favorite











      I'm trying to align in memory the following type of data:



      type foo
      real, allocatable, dimension(:) :: bar1, bar2
      !dir$ attributes align:64 :: bar1
      !dir$ attributes align:64 :: bar2
      end type foo

      type(foo), allocatable, dimension(:) :: my_foo
      allocate(my_foo(1))
      allocate(my_foo(1)%bar1(100))
      allocate(my_foo(1)%bar2(100))

      ! somewhere here I need to tell the compiler that data is aligned
      ! for a simple array with name `bar` I would just do:
      !dir$ assume_aligned bar1: 64
      !dir$ assume_aligned bar2: 64
      ! but what do I do for the data type I have, something like this?
      !dir$ assume_aligned my_foo(1)%bar1: 64
      !dir$ assume_aligned my_foo(1)%bar2: 64

      do i = 1, 100
      my_foo(1)%bar1(i) = 10.
      my_foo(1)%bar2(i) = 10.
      end do


      As you can see, it's an array of foo type structures, that has two large arrays bar1 and bar2 as variables that I need to be aligned near cache boundaries in the memory.



      I kind of know how to do that for simple arrays (link), but I have no idea how to do that for this sort of complex data structure. And what if my_foo wasn't of size 1, but was of size, say, 100? Do I loop through them?










      share|improve this question















      I'm trying to align in memory the following type of data:



      type foo
      real, allocatable, dimension(:) :: bar1, bar2
      !dir$ attributes align:64 :: bar1
      !dir$ attributes align:64 :: bar2
      end type foo

      type(foo), allocatable, dimension(:) :: my_foo
      allocate(my_foo(1))
      allocate(my_foo(1)%bar1(100))
      allocate(my_foo(1)%bar2(100))

      ! somewhere here I need to tell the compiler that data is aligned
      ! for a simple array with name `bar` I would just do:
      !dir$ assume_aligned bar1: 64
      !dir$ assume_aligned bar2: 64
      ! but what do I do for the data type I have, something like this?
      !dir$ assume_aligned my_foo(1)%bar1: 64
      !dir$ assume_aligned my_foo(1)%bar2: 64

      do i = 1, 100
      my_foo(1)%bar1(i) = 10.
      my_foo(1)%bar2(i) = 10.
      end do


      As you can see, it's an array of foo type structures, that has two large arrays bar1 and bar2 as variables that I need to be aligned near cache boundaries in the memory.



      I kind of know how to do that for simple arrays (link), but I have no idea how to do that for this sort of complex data structure. And what if my_foo wasn't of size 1, but was of size, say, 100? Do I loop through them?







      fortran vectorization memory-alignment intel-fortran






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 5 at 22:48









      Vladimir F

      39.4k44071




      39.4k44071










      asked Nov 5 at 20:24









      Hayk Hakobyan

      741211




      741211
























          1 Answer
          1






          active

          oldest

          votes

















          up vote
          0
          down vote



          accepted










          Ok, case semi-closed. The solution turned out to be pretty straightforward. You just use pointers and do an assume_aligned to them. That should take care of it.



          type foo
          real, allocatable, dimension(:) :: bar1, bar2
          !dir$ attributes align:64 :: bar1
          !dir$ attributes align:64 :: bar2
          end type foo

          type(foo), target, allocatable, dimension(:) :: my_foo
          real, pointer, contiguous :: pt_bar1(:)
          real, pointer, contiguous :: pt_bar2(:)
          allocate(my_foo(1))
          allocate(my_foo(1)%bar1(100))
          allocate(my_foo(1)%bar2(100))

          pt_bar1 = my_foo(1)%bar1
          pt_bar2 = my_foo(1)%bar2
          !dir$ assume_aligned pt_bar1:64, pt_bar2:64

          pt_bar1 = 10.
          pt_bar2 = 10.


          do loops are still not vectorized smh. Like if I do the same thing like this



          do i = 1, 100
          pt_bar1(i) = 10.
          pt_bar2(i) = 10.
          end do


          it won't be vectorized.



          UPD.
          Ok, this does the job (also need to add -qopenmp-simd flag to the compiler):



          !$omp simd
          !dir$ vector aligned
          do i = 1, 100
          pt_bar1(i) = 10.
          pt_bar2(i) = 10.
          end do


          Also if you're looping through my_foo(j)%... make sure to free the pointers after each iteration with pt_bar1 => null() etc.



          PS. Thanks to BW from our department for this help. :) Sometimes personal communication > stackoverflow (not always, only sometimes).






          share|improve this answer























          • What do you want to vectorize in that loop? It is a memory store operation, not a mathematical computation.
            – Vladimir F
            Nov 7 at 9:41












          • I just want to vectorize the do loop. If I write an implicit loop like this pt_bar = 10 it vectorizes, but when I do an explicit loop do i=1,100 ..., it doesn't.
            – Hayk Hakobyan
            Nov 7 at 18:26











          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53161673%2fdata-alignment-inside-a-structure-in-intel-fortran%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes








          up vote
          0
          down vote



          accepted










          Ok, case semi-closed. The solution turned out to be pretty straightforward. You just use pointers and do an assume_aligned to them. That should take care of it.



          type foo
          real, allocatable, dimension(:) :: bar1, bar2
          !dir$ attributes align:64 :: bar1
          !dir$ attributes align:64 :: bar2
          end type foo

          type(foo), target, allocatable, dimension(:) :: my_foo
          real, pointer, contiguous :: pt_bar1(:)
          real, pointer, contiguous :: pt_bar2(:)
          allocate(my_foo(1))
          allocate(my_foo(1)%bar1(100))
          allocate(my_foo(1)%bar2(100))

          pt_bar1 = my_foo(1)%bar1
          pt_bar2 = my_foo(1)%bar2
          !dir$ assume_aligned pt_bar1:64, pt_bar2:64

          pt_bar1 = 10.
          pt_bar2 = 10.


          do loops are still not vectorized smh. Like if I do the same thing like this



          do i = 1, 100
          pt_bar1(i) = 10.
          pt_bar2(i) = 10.
          end do


          it won't be vectorized.



          UPD.
          Ok, this does the job (also need to add -qopenmp-simd flag to the compiler):



          !$omp simd
          !dir$ vector aligned
          do i = 1, 100
          pt_bar1(i) = 10.
          pt_bar2(i) = 10.
          end do


          Also if you're looping through my_foo(j)%... make sure to free the pointers after each iteration with pt_bar1 => null() etc.



          PS. Thanks to BW from our department for this help. :) Sometimes personal communication > stackoverflow (not always, only sometimes).






          share|improve this answer























          • What do you want to vectorize in that loop? It is a memory store operation, not a mathematical computation.
            – Vladimir F
            Nov 7 at 9:41












          • I just want to vectorize the do loop. If I write an implicit loop like this pt_bar = 10 it vectorizes, but when I do an explicit loop do i=1,100 ..., it doesn't.
            – Hayk Hakobyan
            Nov 7 at 18:26















          up vote
          0
          down vote



          accepted










          Ok, case semi-closed. The solution turned out to be pretty straightforward. You just use pointers and do an assume_aligned to them. That should take care of it.



          type foo
          real, allocatable, dimension(:) :: bar1, bar2
          !dir$ attributes align:64 :: bar1
          !dir$ attributes align:64 :: bar2
          end type foo

          type(foo), target, allocatable, dimension(:) :: my_foo
          real, pointer, contiguous :: pt_bar1(:)
          real, pointer, contiguous :: pt_bar2(:)
          allocate(my_foo(1))
          allocate(my_foo(1)%bar1(100))
          allocate(my_foo(1)%bar2(100))

          pt_bar1 = my_foo(1)%bar1
          pt_bar2 = my_foo(1)%bar2
          !dir$ assume_aligned pt_bar1:64, pt_bar2:64

          pt_bar1 = 10.
          pt_bar2 = 10.


          do loops are still not vectorized smh. Like if I do the same thing like this



          do i = 1, 100
          pt_bar1(i) = 10.
          pt_bar2(i) = 10.
          end do


          it won't be vectorized.



          UPD.
          Ok, this does the job (also need to add -qopenmp-simd flag to the compiler):



          !$omp simd
          !dir$ vector aligned
          do i = 1, 100
          pt_bar1(i) = 10.
          pt_bar2(i) = 10.
          end do


          Also if you're looping through my_foo(j)%... make sure to free the pointers after each iteration with pt_bar1 => null() etc.



          PS. Thanks to BW from our department for this help. :) Sometimes personal communication > stackoverflow (not always, only sometimes).






          share|improve this answer























          • What do you want to vectorize in that loop? It is a memory store operation, not a mathematical computation.
            – Vladimir F
            Nov 7 at 9:41












          • I just want to vectorize the do loop. If I write an implicit loop like this pt_bar = 10 it vectorizes, but when I do an explicit loop do i=1,100 ..., it doesn't.
            – Hayk Hakobyan
            Nov 7 at 18:26













          up vote
          0
          down vote



          accepted







          up vote
          0
          down vote



          accepted






          Ok, case semi-closed. The solution turned out to be pretty straightforward. You just use pointers and do an assume_aligned to them. That should take care of it.



          type foo
          real, allocatable, dimension(:) :: bar1, bar2
          !dir$ attributes align:64 :: bar1
          !dir$ attributes align:64 :: bar2
          end type foo

          type(foo), target, allocatable, dimension(:) :: my_foo
          real, pointer, contiguous :: pt_bar1(:)
          real, pointer, contiguous :: pt_bar2(:)
          allocate(my_foo(1))
          allocate(my_foo(1)%bar1(100))
          allocate(my_foo(1)%bar2(100))

          pt_bar1 = my_foo(1)%bar1
          pt_bar2 = my_foo(1)%bar2
          !dir$ assume_aligned pt_bar1:64, pt_bar2:64

          pt_bar1 = 10.
          pt_bar2 = 10.


          do loops are still not vectorized smh. Like if I do the same thing like this



          do i = 1, 100
          pt_bar1(i) = 10.
          pt_bar2(i) = 10.
          end do


          it won't be vectorized.



          UPD.
          Ok, this does the job (also need to add -qopenmp-simd flag to the compiler):



          !$omp simd
          !dir$ vector aligned
          do i = 1, 100
          pt_bar1(i) = 10.
          pt_bar2(i) = 10.
          end do


          Also if you're looping through my_foo(j)%... make sure to free the pointers after each iteration with pt_bar1 => null() etc.



          PS. Thanks to BW from our department for this help. :) Sometimes personal communication > stackoverflow (not always, only sometimes).






          share|improve this answer














          Ok, case semi-closed. The solution turned out to be pretty straightforward. You just use pointers and do an assume_aligned to them. That should take care of it.



          type foo
          real, allocatable, dimension(:) :: bar1, bar2
          !dir$ attributes align:64 :: bar1
          !dir$ attributes align:64 :: bar2
          end type foo

          type(foo), target, allocatable, dimension(:) :: my_foo
          real, pointer, contiguous :: pt_bar1(:)
          real, pointer, contiguous :: pt_bar2(:)
          allocate(my_foo(1))
          allocate(my_foo(1)%bar1(100))
          allocate(my_foo(1)%bar2(100))

          pt_bar1 = my_foo(1)%bar1
          pt_bar2 = my_foo(1)%bar2
          !dir$ assume_aligned pt_bar1:64, pt_bar2:64

          pt_bar1 = 10.
          pt_bar2 = 10.


          do loops are still not vectorized smh. Like if I do the same thing like this



          do i = 1, 100
          pt_bar1(i) = 10.
          pt_bar2(i) = 10.
          end do


          it won't be vectorized.



          UPD.
          Ok, this does the job (also need to add -qopenmp-simd flag to the compiler):



          !$omp simd
          !dir$ vector aligned
          do i = 1, 100
          pt_bar1(i) = 10.
          pt_bar2(i) = 10.
          end do


          Also if you're looping through my_foo(j)%... make sure to free the pointers after each iteration with pt_bar1 => null() etc.



          PS. Thanks to BW from our department for this help. :) Sometimes personal communication > stackoverflow (not always, only sometimes).







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 9 at 21:08

























          answered Nov 6 at 22:00









          Hayk Hakobyan

          741211




          741211












          • What do you want to vectorize in that loop? It is a memory store operation, not a mathematical computation.
            – Vladimir F
            Nov 7 at 9:41












          • I just want to vectorize the do loop. If I write an implicit loop like this pt_bar = 10 it vectorizes, but when I do an explicit loop do i=1,100 ..., it doesn't.
            – Hayk Hakobyan
            Nov 7 at 18:26


















          • What do you want to vectorize in that loop? It is a memory store operation, not a mathematical computation.
            – Vladimir F
            Nov 7 at 9:41












          • I just want to vectorize the do loop. If I write an implicit loop like this pt_bar = 10 it vectorizes, but when I do an explicit loop do i=1,100 ..., it doesn't.
            – Hayk Hakobyan
            Nov 7 at 18:26
















          What do you want to vectorize in that loop? It is a memory store operation, not a mathematical computation.
          – Vladimir F
          Nov 7 at 9:41






          What do you want to vectorize in that loop? It is a memory store operation, not a mathematical computation.
          – Vladimir F
          Nov 7 at 9:41














          I just want to vectorize the do loop. If I write an implicit loop like this pt_bar = 10 it vectorizes, but when I do an explicit loop do i=1,100 ..., it doesn't.
          – Hayk Hakobyan
          Nov 7 at 18:26




          I just want to vectorize the do loop. If I write an implicit loop like this pt_bar = 10 it vectorizes, but when I do an explicit loop do i=1,100 ..., it doesn't.
          – Hayk Hakobyan
          Nov 7 at 18:26


















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.





          Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


          Please pay close attention to the following guidance:


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53161673%2fdata-alignment-inside-a-structure-in-intel-fortran%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Landwehr

          Reims

          Schenkenzell