|
71 | 71 | "name": "stderr", |
72 | 72 | "output_type": "stream", |
73 | 73 | "text": [ |
| 74 | + "NUMA domain count autodetection failed, assuming 1\n", |
74 | 75 | "Operator `Kernel` ran in 0.01 s\n" |
75 | 76 | ] |
76 | 77 | }, |
|
158 | 159 | "output_type": "stream", |
159 | 160 | "text": [ |
160 | 161 | "\n", |
161 | | - " Symbol defining a non-convex iteration sub-space derived from a ``parent``\n", |
162 | | - " Dimension, implemented by the compiler generating conditional \"if-then\" code\n", |
163 | | - " within the parent Dimension's iteration space.\n", |
| 162 | + "Symbol defining a non-convex iteration sub-space derived from a ``parent``\n", |
| 163 | + "Dimension, implemented by the compiler generating conditional \"if-then\" code\n", |
| 164 | + "within the parent Dimension's iteration space.\n", |
164 | 165 | "\n", |
165 | | - " Parameters\n", |
166 | | - " ----------\n", |
167 | | - " name : str\n", |
168 | | - " Name of the dimension.\n", |
169 | | - " parent : Dimension\n", |
170 | | - " The parent Dimension.\n", |
171 | | - " factor : int, optional, default=None\n", |
172 | | - " The number of iterations between two executions of the if-branch. If None\n", |
173 | | - " (default), ``condition`` must be provided.\n", |
174 | | - " condition : expr-like, optional, default=None\n", |
175 | | - " An arbitrary SymPy expression, typically involving the ``parent``\n", |
176 | | - " Dimension. When it evaluates to True, the if-branch is executed. If None\n", |
177 | | - " (default), ``factor`` must be provided.\n", |
178 | | - " indirect : bool, optional, default=False\n", |
179 | | - " If True, use `self`, rather than the parent Dimension, to\n", |
180 | | - " index into arrays. A typical use case is when arrays are accessed\n", |
181 | | - " indirectly via the ``condition`` expression.\n", |
| 166 | + "Parameters\n", |
| 167 | + "----------\n", |
| 168 | + "name : str\n", |
| 169 | + " Name of the dimension.\n", |
| 170 | + "parent : Dimension\n", |
| 171 | + " The parent Dimension.\n", |
| 172 | + "factor : int, optional, default=None\n", |
| 173 | + " The number of iterations between two executions of the if-branch. If None\n", |
| 174 | + " (default), ``condition`` must be provided.\n", |
| 175 | + "condition : expr-like, optional, default=None\n", |
| 176 | + " An arbitrary SymPy expression, typically involving the ``parent``\n", |
| 177 | + " Dimension. When it evaluates to True, the if-branch is executed. If None\n", |
| 178 | + " (default), ``factor`` must be provided.\n", |
| 179 | + "indirect : bool, optional, default=False\n", |
| 180 | + " If True, use `self`, rather than the parent Dimension, to\n", |
| 181 | + " index into arrays. A typical use case is when arrays are accessed\n", |
| 182 | + " indirectly via the ``condition`` expression.\n", |
| 183 | + "relation: Or/And, default=And\n", |
| 184 | + " How this ConditionalDimension will be combined with other ones.\n", |
182 | 185 | "\n", |
183 | | - " Examples\n", |
184 | | - " --------\n", |
185 | | - " Among the other things, ConditionalDimensions are indicated to implement\n", |
186 | | - " Function subsampling. In the following example, an Operator evaluates the\n", |
187 | | - " Function ``g`` and saves its content into ``f`` every ``factor=4`` iterations.\n", |
| 186 | + "Examples\n", |
| 187 | + "--------\n", |
| 188 | + "Among the other things, ConditionalDimensions are indicated to implement\n", |
| 189 | + "Function subsampling. In the following example, an Operator evaluates the\n", |
| 190 | + "Function ``g`` and saves its content into ``f`` every ``factor=4`` iterations.\n", |
188 | 191 | "\n", |
189 | | - " >>> from devito import Dimension, ConditionalDimension, Function, Eq, Operator\n", |
190 | | - " >>> size, factor = 16, 4\n", |
191 | | - " >>> i = Dimension(name='i')\n", |
192 | | - " >>> ci = ConditionalDimension(name='ci', parent=i, factor=factor)\n", |
193 | | - " >>> g = Function(name='g', shape=(size,), dimensions=(i,))\n", |
194 | | - " >>> f = Function(name='f', shape=(int(size/factor),), dimensions=(ci,))\n", |
195 | | - " >>> op = Operator([Eq(g, 1), Eq(f, g)])\n", |
| 192 | + ">>> from devito import Dimension, ConditionalDimension, Function, Eq, Operator\n", |
| 193 | + ">>> size, factor = 16, 4\n", |
| 194 | + ">>> i = Dimension(name='i')\n", |
| 195 | + ">>> ci = ConditionalDimension(name='ci', parent=i, factor=factor)\n", |
| 196 | + ">>> g = Function(name='g', shape=(size,), dimensions=(i,))\n", |
| 197 | + ">>> f = Function(name='f', shape=(int(size/factor),), dimensions=(ci,))\n", |
| 198 | + ">>> op = Operator([Eq(g, 1), Eq(f, g)])\n", |
196 | 199 | "\n", |
197 | | - " The Operator generates the following for-loop (pseudocode)\n", |
| 200 | + "The Operator generates the following for-loop (pseudocode)\n", |
198 | 201 | "\n", |
199 | | - " .. code-block:: C\n", |
| 202 | + ".. code-block:: C\n", |
200 | 203 | "\n", |
201 | | - " for (int i = i_m; i <= i_M; i += 1) {\n", |
202 | | - " g[i] = 1;\n", |
203 | | - " if (i%4 == 0) {\n", |
204 | | - " f[i / 4] = g[i];\n", |
205 | | - " }\n", |
206 | | - " }\n", |
| 204 | + " for (int i = i_m; i <= i_M; i += 1) {\n", |
| 205 | + " g[i] = 1;\n", |
| 206 | + " if (i%4 == 0) {\n", |
| 207 | + " f[i / 4] = g[i];\n", |
| 208 | + " }\n", |
| 209 | + " }\n", |
207 | 210 | "\n", |
208 | | - " Another typical use case is when one needs to constrain the execution of\n", |
209 | | - " loop iterations so that certain conditions are honoured. The following\n", |
210 | | - " artificial example uses ConditionalDimension to guard against out-of-bounds\n", |
211 | | - " accesses in indirectly accessed arrays.\n", |
| 211 | + "Another typical use case is when one needs to constrain the execution of\n", |
| 212 | + "loop iterations so that certain conditions are honoured. The following\n", |
| 213 | + "artificial example uses ConditionalDimension to guard against out-of-bounds\n", |
| 214 | + "accesses in indirectly accessed arrays.\n", |
212 | 215 | "\n", |
213 | | - " >>> from sympy import And\n", |
214 | | - " >>> ci = ConditionalDimension(name='ci', parent=i,\n", |
215 | | - " ... condition=And(g[i] > 0, g[i] < 4, evaluate=False))\n", |
216 | | - " >>> f = Function(name='f', shape=(int(size/factor),), dimensions=(ci,))\n", |
217 | | - " >>> op = Operator(Eq(f[g[i]], f[g[i]] + 1))\n", |
| 216 | + ">>> from sympy import And\n", |
| 217 | + ">>> ci = ConditionalDimension(name='ci', parent=i,\n", |
| 218 | + "... condition=And(g[i] > 0, g[i] < 4, evaluate=False))\n", |
| 219 | + ">>> f = Function(name='f', shape=(int(size/factor),), dimensions=(ci,))\n", |
| 220 | + ">>> op = Operator(Eq(f[g[i]], f[g[i]] + 1))\n", |
218 | 221 | "\n", |
219 | | - " The Operator generates the following for-loop (pseudocode)\n", |
| 222 | + "The Operator generates the following for-loop (pseudocode)\n", |
220 | 223 | "\n", |
221 | | - " .. code-block:: C\n", |
| 224 | + ".. code-block:: C\n", |
222 | 225 | "\n", |
223 | | - " for (int i = i_m; i <= i_M; i += 1) {\n", |
224 | | - " if (g[i] > 0 && g[i] < 4) {\n", |
225 | | - " f[g[i]] = f[g[i]] + 1;\n", |
226 | | - " }\n", |
227 | | - " }\n", |
| 226 | + " for (int i = i_m; i <= i_M; i += 1) {\n", |
| 227 | + " if (g[i] > 0 && g[i] < 4) {\n", |
| 228 | + " f[g[i]] = f[g[i]] + 1;\n", |
| 229 | + " }\n", |
| 230 | + " }\n", |
228 | 231 | "\n", |
229 | | - " \n" |
| 232 | + "\n" |
230 | 233 | ] |
231 | 234 | } |
232 | 235 | ], |
|
248 | 251 | { |
249 | 252 | "cell_type": "code", |
250 | 253 | "execution_count": 5, |
251 | | - "metadata": { |
252 | | - "scrolled": true |
253 | | - }, |
| 254 | + "metadata": {}, |
254 | 255 | "outputs": [ |
255 | 256 | { |
256 | 257 | "name": "stderr", |
|
321 | 322 | "output_type": "stream", |
322 | 323 | "text": [ |
323 | 324 | "START(section0)\n", |
324 | | - "for (int x = x_m; x <= x_M; x += 1)\n", |
| 325 | + "#pragma omp parallel num_threads(nthreads)\n", |
325 | 326 | "{\n", |
326 | | - " #pragma omp simd aligned(f:32)\n", |
327 | | - " for (int y = y_m; y <= y_M; y += 1)\n", |
| 327 | + " #pragma omp for schedule(static,1)\n", |
| 328 | + " for (int x = x_m; x <= x_M; x += 1)\n", |
328 | 329 | " {\n", |
329 | | - " if (f[x + 1][y + 1] > 0)\n", |
| 330 | + " #pragma omp simd aligned(f:16)\n", |
| 331 | + " for (int y = y_m; y <= y_M; y += 1)\n", |
330 | 332 | " {\n", |
331 | | - " f[x + 1][y + 1] = f[x + 1][y + 1] + 1;\n", |
| 333 | + " if (f[x + 1][y + 1] > 0)\n", |
| 334 | + " {\n", |
| 335 | + " f[x + 1][y + 1] = f[x + 1][y + 1] + 1;\n", |
| 336 | + " }\n", |
332 | 337 | " }\n", |
333 | 338 | " }\n", |
334 | 339 | "}\n", |
|
397 | 402 | "output_type": "stream", |
398 | 403 | "text": [ |
399 | 404 | "START(section0)\n", |
400 | | - "for (int x = x_m; x <= x_M; x += 1)\n", |
| 405 | + "#pragma omp parallel num_threads(nthreads)\n", |
401 | 406 | "{\n", |
402 | | - " #pragma omp simd aligned(f,g:32)\n", |
403 | | - " for (int y = y_m; y <= y_M; y += 1)\n", |
| 407 | + " #pragma omp for schedule(static,1)\n", |
| 408 | + " for (int x = x_m; x <= x_M; x += 1)\n", |
404 | 409 | " {\n", |
405 | | - " if (y < 5 && g[x + 1][y + 1] != 0)\n", |
| 410 | + " #pragma omp simd aligned(f,g:16)\n", |
| 411 | + " for (int y = y_m; y <= y_M; y += 1)\n", |
406 | 412 | " {\n", |
407 | | - " f[x + 1][y + 1] = f[x + 1][y + 1] + g[x + 1][y + 1];\n", |
| 413 | + " if (y < 5 && g[x + 1][y + 1] != 0)\n", |
| 414 | + " {\n", |
| 415 | + " f[x + 1][y + 1] = f[x + 1][y + 1] + g[x + 1][y + 1];\n", |
| 416 | + " }\n", |
408 | 417 | " }\n", |
409 | 418 | " }\n", |
410 | 419 | "}\n", |
|
489 | 498 | "output_type": "stream", |
490 | 499 | "text": [ |
491 | 500 | "START(section0)\n", |
492 | | - "for (int x = x_m; x <= x_M; x += 1)\n", |
| 501 | + "#pragma omp parallel num_threads(nthreads)\n", |
493 | 502 | "{\n", |
494 | | - " for (int y = y_m; y <= y_M; y += 1)\n", |
| 503 | + " #pragma omp for schedule(static,1)\n", |
| 504 | + " for (int x = x_m; x <= x_M; x += 1)\n", |
495 | 505 | " {\n", |
496 | | - " if (y < 5 && g[x + 1][y + 1] != 0)\n", |
| 506 | + " for (int y = y_m; y <= y_M; y += 1)\n", |
497 | 507 | " {\n", |
498 | | - " h[x + 1][y + 1] = g[x + 1][y + 1] + h[x + 1][y + 1];\n", |
| 508 | + " if (y < 5 && g[x + 1][y + 1] != 0)\n", |
| 509 | + " {\n", |
| 510 | + " h[x + 1][y + 1] = g[x + 1][y + 1] + h[x + 1][y + 1];\n", |
| 511 | + " }\n", |
499 | 512 | " }\n", |
500 | 513 | " }\n", |
501 | 514 | "}\n", |
|
563 | 576 | "output_type": "stream", |
564 | 577 | "text": [ |
565 | 578 | "START(section0)\n", |
566 | | - "for (int i = i_m; i <= i_M; i += 1)\n", |
| 579 | + "#pragma omp parallel num_threads(nthreads)\n", |
567 | 580 | "{\n", |
568 | | - " if ((i)%(cif) == 0)\n", |
| 581 | + " #pragma omp for schedule(static,1)\n", |
| 582 | + " for (int i = i_m; i <= i_M; i += 1)\n", |
569 | 583 | " {\n", |
570 | | - " f[i / cif] = g[i];\n", |
| 584 | + " if ((i)%(cif) == 0)\n", |
| 585 | + " {\n", |
| 586 | + " f[i / cif] = g[i];\n", |
| 587 | + " }\n", |
571 | 588 | " }\n", |
572 | 589 | "}\n", |
573 | 590 | "STOP(section0,timers)\n", |
|
678 | 695 | "output_type": "stream", |
679 | 696 | "text": [ |
680 | 697 | "START(section0)\n", |
681 | | - "for (int x = x_m; x <= x_M; x += 1)\n", |
| 698 | + "#pragma omp parallel num_threads(nthreads)\n", |
682 | 699 | "{\n", |
683 | | - " for (int y = y_m; y <= y_M; y += 1)\n", |
| 700 | + " #pragma omp for collapse(2) schedule(static,1) reduction(+:g[1])\n", |
| 701 | + " for (int x = x_m; x <= x_M; x += 1)\n", |
684 | 702 | " {\n", |
685 | | - " if (f[x][y] != 0)\n", |
| 703 | + " for (int y = y_m; y <= y_M; y += 1)\n", |
686 | 704 | " {\n", |
687 | | - " g[1] += 1;\n", |
| 705 | + " if (f[x][y] != 0)\n", |
| 706 | + " {\n", |
| 707 | + " g[1] += 1;\n", |
| 708 | + " }\n", |
688 | 709 | " }\n", |
689 | 710 | " }\n", |
690 | 711 | "}\n", |
|
694 | 715 | { |
695 | 716 | "data": { |
696 | 717 | "text/plain": [ |
697 | | - "10" |
| 718 | + "np.int32(10)" |
698 | 719 | ] |
699 | 720 | }, |
700 | 721 | "execution_count": 11, |
|
831 | 852 | "name": "python", |
832 | 853 | "nbconvert_exporter": "python", |
833 | 854 | "pygments_lexer": "ipython3", |
834 | | - "version": "3.11.2" |
| 855 | + "version": "3.13.11" |
835 | 856 | } |
836 | 857 | }, |
837 | 858 | "nbformat": 4, |
|
0 commit comments