File: Allocating-aligned-memory-in-Fortran.html

package info (click to toggle)
fftw3 3.3.8-2
  • links: PTS, VCS
  • area: main
  • in suites: bullseye, buster
  • size: 28,428 kB
  • sloc: ansic: 259,592; ml: 5,474; sh: 4,442; perl: 1,648; makefile: 1,156; fortran: 110
file content (168 lines) | stat: -rw-r--r-- 8,544 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<!-- This manual is for FFTW
(version 3.3.8, 24 May 2018).

Copyright (C) 2003 Matteo Frigo.

Copyright (C) 2003 Massachusetts Institute of Technology.

Permission is granted to make and distribute verbatim copies of this
manual provided the copyright notice and this permission notice are
preserved on all copies.

Permission is granted to copy and distribute modified versions of this
manual under the conditions for verbatim copying, provided that the
entire resulting derived work is distributed under the terms of a
permission notice identical to this one.

Permission is granted to copy and distribute translations of this manual
into another language, under the above conditions for modified versions,
except that this permission notice may be stated in a translation
approved by the Free Software Foundation. -->
<!-- Created by GNU Texinfo 6.3, http://www.gnu.org/software/texinfo/ -->
<head>
<title>FFTW 3.3.8: Allocating aligned memory in Fortran</title>

<meta name="description" content="FFTW 3.3.8: Allocating aligned memory in Fortran">
<meta name="keywords" content="FFTW 3.3.8: Allocating aligned memory in Fortran">
<meta name="resource-type" content="document">
<meta name="distribution" content="global">
<meta name="Generator" content="makeinfo">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link href="index.html#Top" rel="start" title="Top">
<link href="Concept-Index.html#Concept-Index" rel="index" title="Concept Index">
<link href="index.html#SEC_Contents" rel="contents" title="Table of Contents">
<link href="Calling-FFTW-from-Modern-Fortran.html#Calling-FFTW-from-Modern-Fortran" rel="up" title="Calling FFTW from Modern Fortran">
<link href="Accessing-the-wisdom-API-from-Fortran.html#Accessing-the-wisdom-API-from-Fortran" rel="next" title="Accessing the wisdom API from Fortran">
<link href="Plan-execution-in-Fortran.html#Plan-execution-in-Fortran" rel="prev" title="Plan execution in Fortran">
<style type="text/css">
<!--
a.summary-letter {text-decoration: none}
blockquote.indentedblock {margin-right: 0em}
blockquote.smallindentedblock {margin-right: 0em; font-size: smaller}
blockquote.smallquotation {font-size: smaller}
div.display {margin-left: 3.2em}
div.example {margin-left: 3.2em}
div.lisp {margin-left: 3.2em}
div.smalldisplay {margin-left: 3.2em}
div.smallexample {margin-left: 3.2em}
div.smalllisp {margin-left: 3.2em}
kbd {font-style: oblique}
pre.display {font-family: inherit}
pre.format {font-family: inherit}
pre.menu-comment {font-family: serif}
pre.menu-preformatted {font-family: serif}
pre.smalldisplay {font-family: inherit; font-size: smaller}
pre.smallexample {font-size: smaller}
pre.smallformat {font-family: inherit; font-size: smaller}
pre.smalllisp {font-size: smaller}
span.nolinebreak {white-space: nowrap}
span.roman {font-family: initial; font-weight: normal}
span.sansserif {font-family: sans-serif; font-weight: normal}
ul.no-bullet {list-style: none}
-->
</style>


</head>

<body lang="en">
<a name="Allocating-aligned-memory-in-Fortran"></a>
<div class="header">
<p>
Next: <a href="Accessing-the-wisdom-API-from-Fortran.html#Accessing-the-wisdom-API-from-Fortran" accesskey="n" rel="next">Accessing the wisdom API from Fortran</a>, Previous: <a href="Plan-execution-in-Fortran.html#Plan-execution-in-Fortran" accesskey="p" rel="prev">Plan execution in Fortran</a>, Up: <a href="Calling-FFTW-from-Modern-Fortran.html#Calling-FFTW-from-Modern-Fortran" accesskey="u" rel="up">Calling FFTW from Modern Fortran</a> &nbsp; [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Concept-Index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
</div>
<hr>
<a name="Allocating-aligned-memory-in-Fortran-1"></a>
<h3 class="section">7.5 Allocating aligned memory in Fortran</h3>

<a name="index-alignment-5"></a>
<a name="index-fftw_005falloc_005freal-5"></a>
<a name="index-fftw_005falloc_005fcomplex-5"></a>
<p>In order to obtain maximum performance in FFTW, you should store your
data in arrays that have been specially aligned in memory (see <a href="SIMD-alignment-and-fftw_005fmalloc.html#SIMD-alignment-and-fftw_005fmalloc">SIMD alignment and fftw_malloc</a>).  Enforcing alignment also permits you to
safely use the new-array execute functions (see <a href="New_002darray-Execute-Functions.html#New_002darray-Execute-Functions">New-array Execute Functions</a>) to apply a given plan to more than one pair of in/out
arrays.  Unfortunately, standard Fortran arrays do <em>not</em> provide
any alignment guarantees.  The <em>only</em> way to allocate aligned
memory in standard Fortran is to allocate it with an external C
function, like the <code>fftw_alloc_real</code> and
<code>fftw_alloc_complex</code> functions.  Fortunately, Fortran 2003 provides
a simple way to associate such allocated memory with a standard Fortran
array pointer that you can then use normally.
</p>
<p>We therefore recommend allocating all your input/output arrays using
the following technique:
</p>
<ol>
<li> Declare a <code>pointer</code>, <code>arr</code>, to your array of the desired type
and dimensions.  For example, <code>real(C_DOUBLE), pointer :: a(:,:)</code>
for a 2d real array, or <code>complex(C_DOUBLE_COMPLEX), pointer ::
a(:,:,:)</code> for a 3d complex array.

</li><li> The number of elements to allocate must be an
<code>integer(C_SIZE_T)</code>.  You can either declare a variable of this
type, e.g. <code>integer(C_SIZE_T) :: sz</code>, to store the number of
elements to allocate, or you can use the <code>int(..., C_SIZE_T)</code>
intrinsic function. e.g. set <code>sz = L * M * N</code> or use
<code>int(L * M * N, C_SIZE_T)</code> for an L&nbsp;&times;&nbsp;M&nbsp;&times;&nbsp;N
 array.

</li><li> Declare a <code>type(C_PTR) :: p</code> to hold the return value from
FFTW&rsquo;s allocation routine.  Set <code>p = fftw_alloc_real(sz)</code> for a real array, or <code>p = fftw_alloc_complex(sz)</code> for a complex array.

</li><li> <a name="index-c_005ff_005fpointer-2"></a>
Associate your pointer <code>arr</code> with the allocated memory <code>p</code>
using the standard <code>c_f_pointer</code> subroutine: <code>call
c_f_pointer(p, arr, [...dimensions...])</code>, where
<code>[...dimensions...])</code> are an array of the dimensions of the array
(in the usual Fortran order). e.g. <code>call c_f_pointer(p, arr,
[L,M,N])</code> for an L&nbsp;&times;&nbsp;M&nbsp;&times;&nbsp;N
 array.  (Alternatively, you can
omit the dimensions argument if you specified the shape explicitly
when declaring <code>arr</code>.)  You can now use <code>arr</code> as a usual
multidimensional array.

</li><li> When you are done using the array, deallocate the memory by <code>call
fftw_free(p)</code> on <code>p</code>.

</li></ol>

<p>For example, here is how we would allocate an L&nbsp;&times;&nbsp;M
 2d real array:
</p>
<div class="example">
<pre class="example">  real(C_DOUBLE), pointer :: arr(:,:)
  type(C_PTR) :: p
  p = fftw_alloc_real(int(L * M, C_SIZE_T))
  call c_f_pointer(p, arr, [L,M])
  <em>...use arr and arr(i,j) as usual...</em>
  call fftw_free(p)
</pre></div>

<p>and here is an L&nbsp;&times;&nbsp;M&nbsp;&times;&nbsp;N
 3d complex array:
</p>
<div class="example">
<pre class="example">  complex(C_DOUBLE_COMPLEX), pointer :: arr(:,:,:)
  type(C_PTR) :: p
  p = fftw_alloc_complex(int(L * M * N, C_SIZE_T))
  call c_f_pointer(p, arr, [L,M,N])
  <em>...use arr and arr(i,j,k) as usual...</em>
  call fftw_free(p)
</pre></div>

<p>See <a href="Reversing-array-dimensions.html#Reversing-array-dimensions">Reversing array dimensions</a> for an example allocating a
single array and associating both real and complex array pointers with
it, for in-place real-to-complex transforms.
</p>
<hr>
<div class="header">
<p>
Next: <a href="Accessing-the-wisdom-API-from-Fortran.html#Accessing-the-wisdom-API-from-Fortran" accesskey="n" rel="next">Accessing the wisdom API from Fortran</a>, Previous: <a href="Plan-execution-in-Fortran.html#Plan-execution-in-Fortran" accesskey="p" rel="prev">Plan execution in Fortran</a>, Up: <a href="Calling-FFTW-from-Modern-Fortran.html#Calling-FFTW-from-Modern-Fortran" accesskey="u" rel="up">Calling FFTW from Modern Fortran</a> &nbsp; [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Concept-Index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
</div>



</body>
</html>