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?
fortran vectorization memory-alignment intel-fortran
add a comment |
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?
fortran vectorization memory-alignment intel-fortran
add a comment |
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?
fortran vectorization memory-alignment intel-fortran
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
fortran vectorization memory-alignment intel-fortran
edited Nov 5 at 22:48
Vladimir F
39.4k44071
39.4k44071
asked Nov 5 at 20:24
Hayk Hakobyan
741211
741211
add a comment |
add a comment |
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).
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 thedoloop. If I write an implicit loop like thispt_bar = 10it vectorizes, but when I do an explicit loopdo i=1,100 ..., it doesn't.
– Hayk Hakobyan
Nov 7 at 18:26
add a comment |
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).
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 thedoloop. If I write an implicit loop like thispt_bar = 10it vectorizes, but when I do an explicit loopdo i=1,100 ..., it doesn't.
– Hayk Hakobyan
Nov 7 at 18:26
add a comment |
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).
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 thedoloop. If I write an implicit loop like thispt_bar = 10it vectorizes, but when I do an explicit loopdo i=1,100 ..., it doesn't.
– Hayk Hakobyan
Nov 7 at 18:26
add a comment |
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).
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).
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 thedoloop. If I write an implicit loop like thispt_bar = 10it vectorizes, but when I do an explicit loopdo i=1,100 ..., it doesn't.
– Hayk Hakobyan
Nov 7 at 18:26
add a comment |
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 thedoloop. If I write an implicit loop like thispt_bar = 10it vectorizes, but when I do an explicit loopdo 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
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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