From 59d1b8f4e5508a7a17bbc33a3c91e0b941f13324 Mon Sep 17 00:00:00 2001 From: Yonghong Yan Date: Thu, 3 Oct 2019 22:14:00 -0400 Subject: [PATCH 01/21] Create tex2notebook.py --- notebook/tex2notebook.py | 1 + 1 file changed, 1 insertion(+) create mode 100644 notebook/tex2notebook.py diff --git a/notebook/tex2notebook.py b/notebook/tex2notebook.py new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/notebook/tex2notebook.py @@ -0,0 +1 @@ + From 22049f2499ccb426f2c239b06539831d958f762e Mon Sep 17 00:00:00 2001 From: Yonghong Yan Date: Thu, 3 Oct 2019 22:14:41 -0400 Subject: [PATCH 02/21] Create README.md --- notebook/README.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 notebook/README.md diff --git a/notebook/README.md b/notebook/README.md new file mode 100644 index 0000000..46bdbfb --- /dev/null +++ b/notebook/README.md @@ -0,0 +1 @@ +## tex2notebook.py script generates Jupyter Notebooks from the tex file From 00228613d45f255c94ae0b9b035136ddd9739e88 Mon Sep 17 00:00:00 2001 From: Kewei Yan Date: Fri, 4 Oct 2019 09:34:40 -0400 Subject: [PATCH 03/21] tex2notebook updated --- .gitignore | 1 + notebook/NBSets/LanguageSet.txt | 16 ++ notebook/NBSets/code.txt | 7 + notebook/NBSets/markdown.txt | 5 + notebook/README.md | 15 ++ notebook/tex2notebook.py | 295 ++++++++++++++++++++++++++++++++ 6 files changed, 339 insertions(+) create mode 100644 .gitignore create mode 100644 notebook/NBSets/LanguageSet.txt create mode 100644 notebook/NBSets/code.txt create mode 100644 notebook/NBSets/markdown.txt diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e43b0f9 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.DS_Store diff --git a/notebook/NBSets/LanguageSet.txt b/notebook/NBSets/LanguageSet.txt new file mode 100644 index 0000000..ea61ee8 --- /dev/null +++ b/notebook/NBSets/LanguageSet.txt @@ -0,0 +1,16 @@ + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} \ No newline at end of file diff --git a/notebook/NBSets/code.txt b/notebook/NBSets/code.txt new file mode 100644 index 0000000..509b405 --- /dev/null +++ b/notebook/NBSets/code.txt @@ -0,0 +1,7 @@ + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + " \ No newline at end of file diff --git a/notebook/NBSets/markdown.txt b/notebook/NBSets/markdown.txt new file mode 100644 index 0000000..cda3065 --- /dev/null +++ b/notebook/NBSets/markdown.txt @@ -0,0 +1,5 @@ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \ No newline at end of file diff --git a/notebook/README.md b/notebook/README.md index 46bdbfb..276a0cc 100644 --- a/notebook/README.md +++ b/notebook/README.md @@ -1 +1,16 @@ ## tex2notebook.py script generates Jupyter Notebooks from the tex file + +#### run + +Convert .tex to .ipynb + +read .tex -> change .tex(template) -> write .ipynb + +``` +$ python ReadWrite.py +``` + +#### notes +`%load` is supported by python, then kernel of jupuyter should be set to python or python3. + +`%load` recognizes absolute path. Now the default one is `~/Documents/Examples/sources/Example_*` \ No newline at end of file diff --git a/notebook/tex2notebook.py b/notebook/tex2notebook.py index 8b13789..6522ff5 100644 --- a/notebook/tex2notebook.py +++ b/notebook/tex2notebook.py @@ -1 +1,296 @@ +#!/usr/bin/env python2.7 +# -*- coding: utf-8 -*- +import re +import os + +# ipynb sets +with open('NBSets/LanguageSet.txt', 'r') as f: + LanguageSet = f.read() + +with open('NBSets/markdown.txt', 'r') as f: + MB = f.read() + +with open('NBSets/code.txt', 'r') as f: + CB = f.read() + +E = '"\n ]\n },\n' +E1 = ' \n ]\n },\n' +E2 = '"\n ]\n }\n' + +# Do some changes +# ilegal symbols +def replace_underscore(Str): + Str = re.sub('"', '\'', Str) + Str = re.sub('\\\\_', '_', Str) + Str = re.sub('\\ifpdf', '', Str) + Str = re.sub('\\item ', '(item)', Str) + Str = re.sub('\\fi', '', Str) + Str = re.sub('\\fortranspecificstart', '', Str) + Str = re.sub('\\fortranspecificend', '', Str) + return Str + +def replace_dash(Str): + Str = re.sub('\\\\', '', Str) + return Str + +# pattern +def replce_pattern(Str): + if '[htbp]' in Str: + Str = '' + + if ' {figs or' in Str: + Str = '' + + return Str + +# \pagebreak +def replace_page(Str): + Str = re.sub(r'\\pagebreak', '', Str) + return Str + +# \label +def replace_label(Str): + Str = re.sub(r'\\label\{[^\{\}]*\}', '', Str) + Str = re.sub(r'\\specref\{[^\{\}]*\}', '', Str) + return Str + +# \chapter +def rep_chapter(match): + val = match.group() + l = len(val) + out = ' ## ' + val[9 :(l - 1)] + return out + +def replace_chapter(Str): + Str = re.sub(r'\\chapter\{[^\{\}]*\}', rep_chapter, Str) + return Str + +# \section +def rep_section(match): + val = match.group() + l = len(val) + out = ' ### ' + val[9 :(l - 1)] + return out + +def replace_section(Str): + Str = re.sub(r'\\section\{[^\{\}]*\}', rep_section, Str) + return Str + +# \subsection +def rep_subsec(match): + val = match.group() + l = len(val) + out = ' #### ' + val[12 :(l - 1)] + return out + +def replace_subsec(Str): + Str = re.sub(r'\\subsection\{[^\{\}]*\}', rep_subsec, Str) + return Str + +# % +def replace_perc(Str): + Str = re.sub(r'^[][%]', '', Str) + Str = re.sub(r'[%]', '\\\\n",\n"', Str) + Str = re.sub(r'begin\{[\w]*\}', '', Str) + Str = re.sub(r'end\{[\w]*\}', '', Str) + return Str + +# (item) +def replace_item(Str): + Str = re.sub(r'\(item\)', '\\\\n",\n"* ', Str) + return Str + +# \code +def rep_code(match): + val = match.group() + l = len(val) + out = ' `' + val[6 :(l - 1)] + '` ' + return out + +def replace_code(Str): + Str = re.sub(r'\\code\{[^\{\}]*\}', rep_code, Str) + if '\\code{' in Str: + Str = ' `' + Str[7 :(l - 1)] + '` ' + return Str + +# \plc +def rep_plc(match): + val = match.group() + l = len(val) + out = ' _' + val[5 :(l - 1)] + '_ ' + return out + +def replace_plc(Str): + Str = re.sub(r'\\plc\{[^\{\}]*\}', rep_plc, Str) + return Str + +# \texttt +def rep_texttt(match): + val = match.group() + l = len(val) + out = ' ' + val[8 :(l - 1)] + ' ' + return out + +def replace_texttt(Str): + Str = re.sub(r'\\texttt\{[\w\W\s]\}', rep_texttt, Str) + return Str + +# \href +def rep_href(match): + val = match.group() + l = len(val) + out = ' ' + val[6 :(l - 1)] + ' ' + return out + +def replace_href(Str): + Str = re.sub(r'\\href\{[^\{\}]*\}', rep_href, Str) + Str = re.sub(r'\{https:[^\{\}]*\}.', '', Str) + return Str + +# examples +def replace_example(Str): + Str = re.sub('{', '', Str) + Str = re.sub('}', '', Str) + l = len(Str) + if 'cexample' in Str: + if Str[l-2] not in ['1', '2', '3', '4']: + Str = Str[8 : l-1] + '.' + Str[l-1] + '.c' + else: + Str = Str[8 : l-2] + '.' + Str[l-2 :] + '.c' + + elif 'fexample' in Str: + # Str = Str[8 : ] + '.f' + if Str[l-2] not in ['1', '2', '3', '4']: + Str = Str[8 : l-1] + '.' + Str[l-1] + '.f' + else: + Str = Str[8 : l-2] + '.' + Str[l-2 :] + '.f' + + elif 'cppexample' in Str: + # Str = Str[10 : ] + '.cpp' + if Str[l-2] not in ['1', '2', '3', '4']: + Str = Str[10 : l-1] + '.' + Str[l-1] + '.cpp' + else: + Str = Str[10 : l-2] + '.' + Str[l-2 :] + '.cpp' + + elif 'cnexample' in Str: + # Str = Str[9 : ] + '.c' + if Str[l-2] not in ['1', '2', '3', '4']: + Str = Str[9 : l-1] + '.' + Str[l-1] + '.c' + else: + Str = Str[9 : l-2] + '.' + Str[l-2 :] + '.c' + + elif 'fnexample' in Str: + # Str = Str[9 : ] + '.f' + if Str[l-2] not in ['1', '2', '3', '4']: + Str = Str[9 : l-1] + '.' + Str[l-1] + '.f' + else: + Str = Str[9 : l-2] + '.' + Str[l-2 :] + '.f' + + elif 'cfreeexample' in Str: + # Str = Str[12 : ] + '.c' + if Str[l-2] not in ['1', '2', '3', '4']: + Str = Str[12 : l-1] + '.' + Str[l-1] + '.c' + else: + Str = Str[12 : l-2] + '.' + Str[l-2 :] + '.c' + + elif 'ffreeexample' in Str: + # Str = Str[12 : ] + '.f90' + if Str[l-2] not in ['1', '2', '3', '4']: + Str = Str[12 : l-1] + '.' + Str[l-1] + '.f90' + else: + Str = Str[12 : l-2] + '.' + Str[l-2 :] + '.f90' + + return '%load ~/Documents/Examples/sources/Example_' + Str + +# get file list +path = '../' +dir = os.listdir(path) + +with open('MyList.txt', 'w') as f: + for i in dir: + if os.path.splitext(i)[1] == '.tex': + f.write(i) + f.write('\n') + +with open('MyList.txt', 'r') as f: + mylist = f.read() + +mylist = mylist[: -1] +mylists = re.split('\n', mylist) +#print mylists + +# check grammar +LIST = ['\\pa', '\\ch', '\\se', '\\su', '\\la', '\\ce', '\\cn', '\\cp', '\\fe', '\\fn', '\\ff'] + +CodeList = ['ce', 'cn', 'cp', 'fe', 'fn', 'ff'] + +for FileName in mylists: + print(FileName) + FileLen = len(FileName) + input = '../' + FileName + output = FileName[:(FileLen - 4)] + '.ipynb' + testfile = 'TEST' + FileName + + with open(input, 'r') as f: + s = f.read() + + lines = re.split('\n', s) + + with open(testfile, 'w') as f: + for line in lines: + l = len(line) + if line[ : 3] in LIST: + f.write(line) + f.write('\n') + elif l == 0: + f.write('\n') + else : + f.write(' ') + f.write(line) + + # read and write + with open(testfile, 'r') as f: + s = f.read() + + lines = re.split('\n', s) + + with open(output, 'w') as f: + + f.write('{\n "cells": [\n') + + for line in lines: + line = replace_underscore(line) + line = replace_code(line) + line = replace_plc(line) + line = replace_texttt(line) + line = replace_href(line) + + line = replce_pattern(line) + + line = replace_page(line) + line = replace_chapter(line) + line = replace_section(line) + line = replace_subsec(line) + line = replace_label(line) + + line = replace_dash(line) + if len(line) == 0: + f.write('') + elif line[ : 2] in CodeList: + line = replace_example(line) + f.write(CB) + f.write(line) + f.write(E) + else : + line = replace_perc(line) + line = replace_item(line) + f.write(MB) + f.write(line) + f.write(E) + + f.write(MB) + f.write('---end---') + f.write(E2) + + f.write(LanguageSet) From 512bd804052dafd9f139c67fb790cd41457ec2b7 Mon Sep 17 00:00:00 2001 From: Kewei Yan Date: Tue, 8 Oct 2019 11:00:56 -0400 Subject: [PATCH 04/21] README is updated --- notebook/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/notebook/README.md b/notebook/README.md index 276a0cc..b39a26a 100644 --- a/notebook/README.md +++ b/notebook/README.md @@ -7,10 +7,10 @@ Convert .tex to .ipynb read .tex -> change .tex(template) -> write .ipynb ``` -$ python ReadWrite.py +$ python tex2notebook.py ``` #### notes `%load` is supported by python, then kernel of jupuyter should be set to python or python3. -`%load` recognizes absolute path. Now the default one is `~/Documents/Examples/sources/Example_*` \ No newline at end of file +`%load` recognizes absolute path. Now the default one is `~/Documents/Examples/sources/Example_*` From ae4100045a3bf742f833c5f7abca5535afe9e021 Mon Sep 17 00:00:00 2001 From: Kewei Yan Date: Tue, 8 Oct 2019 11:03:29 -0400 Subject: [PATCH 05/21] README is updated --- notebook/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/notebook/README.md b/notebook/README.md index b39a26a..2b4e158 100644 --- a/notebook/README.md +++ b/notebook/README.md @@ -13,4 +13,4 @@ $ python tex2notebook.py #### notes `%load` is supported by python, then kernel of jupuyter should be set to python or python3. -`%load` recognizes absolute path. Now the default one is `~/Documents/Examples/sources/Example_*` +`%load` recognizes both absolute path and related path. Now the default one is `../sources/Example_*`. From 8163af847dfea2d9c7ba2367829d87d1c892350a Mon Sep 17 00:00:00 2001 From: Kewei Yan Date: Tue, 8 Oct 2019 11:26:49 -0400 Subject: [PATCH 06/21] ipynb settings updated --- notebook/NBSets/LanguageSet.txt | 16 ---------- notebook/NBSets/code.txt | 7 ----- notebook/NBSets/markdown.txt | 5 ---- notebook/tex2notebook.py | 52 ++++++++++++++++++++++++++------- 4 files changed, 42 insertions(+), 38 deletions(-) delete mode 100644 notebook/NBSets/LanguageSet.txt delete mode 100644 notebook/NBSets/code.txt delete mode 100644 notebook/NBSets/markdown.txt diff --git a/notebook/NBSets/LanguageSet.txt b/notebook/NBSets/LanguageSet.txt deleted file mode 100644 index ea61ee8..0000000 --- a/notebook/NBSets/LanguageSet.txt +++ /dev/null @@ -1,16 +0,0 @@ - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/notebook/NBSets/code.txt b/notebook/NBSets/code.txt deleted file mode 100644 index 509b405..0000000 --- a/notebook/NBSets/code.txt +++ /dev/null @@ -1,7 +0,0 @@ - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - " \ No newline at end of file diff --git a/notebook/NBSets/markdown.txt b/notebook/NBSets/markdown.txt deleted file mode 100644 index cda3065..0000000 --- a/notebook/NBSets/markdown.txt +++ /dev/null @@ -1,5 +0,0 @@ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \ No newline at end of file diff --git a/notebook/tex2notebook.py b/notebook/tex2notebook.py index 6522ff5..6b7515b 100644 --- a/notebook/tex2notebook.py +++ b/notebook/tex2notebook.py @@ -1,18 +1,50 @@ -#!/usr/bin/env python2.7 +#!/usr/bin/env python3.6 # -*- coding: utf-8 -*- import re import os # ipynb sets -with open('NBSets/LanguageSet.txt', 'r') as f: - LanguageSet = f.read() - -with open('NBSets/markdown.txt', 'r') as f: - MB = f.read() - -with open('NBSets/code.txt', 'r') as f: - CB = f.read() +# previously these settings are from .txt, now they are included in this file +# with open('NBSets/LanguageSet.txt', 'r') as f: +# LanguageSet = f.read() + +# with open('NBSets/markdown.txt', 'r') as f: +# MB = f.read() + +# with open('NBSets/code.txt', 'r') as f: +# CB = f.read() + +LanguageSet = '],\n' + \ + '"metadata": {\n' + \ + ' "kernelspec": {\n' + \ + ' "display_name": "C",\n' + \ + ' "language": "c",\n' + \ + ' "name": "c"\n' + \ + ' },\n' + \ + ' "language_info": {\n' + \ + ' "file_extension": ".c",\n' + \ + ' "mimetype": "text/plain",\n' + \ + ' "name": "c"\n' + \ + ' }\n' + \ + '},\n' + \ + '"nbformat": 4,\n' + \ + '"nbformat_minor": 2\n' + \ + '}\n' + +MB = '{\n' + \ + ' "cell_type": "markdown",\n' + \ + ' "metadata": {},\n' + \ + ' "source": [\n' + \ + ' "' + +CB = '{\n' + \ + ' "cell_type": "code",\n' + \ + ' "execution_count": null,\n' + \ + ' "metadata": {},\n' + \ + ' "outputs": [],\n' + \ + ' "source": [\n' + \ + ' "' E = '"\n ]\n },\n' E1 = ' \n ]\n },\n' @@ -201,7 +233,7 @@ def replace_example(Str): else: Str = Str[12 : l-2] + '.' + Str[l-2 :] + '.f90' - return '%load ~/Documents/Examples/sources/Example_' + Str + return '%load ../sources/Example_' + Str # get file list path = '../' From 87cd7bd4064aee0adacbafd2dae6906a50b1b31b Mon Sep 17 00:00:00 2001 From: Kewei Yan Date: Tue, 8 Oct 2019 11:34:06 -0400 Subject: [PATCH 07/21] .py updated --- notebook/Chap_SIMD.ipynb | 73 ++ notebook/Chap_affinity.ipynb | 170 +++++ notebook/Chap_data_environment.ipynb | 121 +++ notebook/Chap_devices.ipynb | 81 ++ notebook/Chap_memory_model.ipynb | 146 ++++ notebook/Chap_parallel_execution.ipynb | 165 ++++ notebook/Chap_program_control.ipynb | 151 ++++ notebook/Chap_synchronization.ipynb | 90 +++ notebook/Chap_tasking.ipynb | 75 ++ notebook/Examples_Chapt.ipynb | 50 ++ notebook/Examples_SIMD.ipynb | 288 +++++++ notebook/Examples_affinity.ipynb | 705 ++++++++++++++++++ notebook/Examples_affinity_query.ipynb | 85 +++ notebook/Examples_array_sections.ipynb | 139 ++++ notebook/Examples_associate.ipynb | 94 +++ notebook/Examples_async_target_depend.ipynb | 53 ++ notebook/Examples_async_target_nowait.ipynb | 78 ++ .../Examples_async_target_nowait_depend.ipynb | 80 ++ .../Examples_async_target_with_tasks.ipynb | 124 +++ notebook/Examples_atomic.ipynb | 121 +++ notebook/Examples_atomic_restrict.ipynb | 105 +++ notebook/Examples_barrier_regions.ipynb | 71 ++ notebook/Examples_cancellation.ipynb | 96 +++ notebook/Examples_carrays_fpriv.ipynb | 124 +++ notebook/Examples_collapse.ipynb | 149 ++++ notebook/Examples_cond_comp.ipynb | 78 ++ notebook/Examples_copyin.ipynb | 57 ++ notebook/Examples_copyprivate.ipynb | 135 ++++ notebook/Examples_cpp_reference.ipynb | 66 ++ notebook/Examples_critical.ipynb | 82 ++ notebook/Examples_declare_target.ipynb | 326 ++++++++ notebook/Examples_default_none.ipynb | 71 ++ notebook/Examples_device.ipynb | 172 +++++ notebook/Examples_doacross.ipynb | 139 ++++ notebook/Examples_flush_nolist.ipynb | 57 ++ notebook/Examples_fort_do.ipynb | 78 ++ notebook/Examples_fort_loopvar.ipynb | 78 ++ notebook/Examples_fort_race.ipynb | 62 ++ notebook/Examples_fort_sa_private.ipynb | 106 +++ notebook/Examples_fort_sp_common.ipynb | 141 ++++ notebook/Examples_fpriv_sections.ipynb | 57 ++ notebook/Examples_get_nthrs.ipynb | 82 ++ notebook/Examples_icv.ipynb | 113 +++ notebook/Examples_init_lock.ipynb | 57 ++ notebook/Examples_init_lock_with_hint.ipynb | 58 ++ notebook/Examples_lastprivate.ipynb | 57 ++ notebook/Examples_linear_in_loop.ipynb | 57 ++ notebook/Examples_lock_owner.ipynb | 64 ++ notebook/Examples_locks.ipynb | 39 + notebook/Examples_master.ipynb | 57 ++ notebook/Examples_mem_model.ipynb | 114 +++ notebook/Examples_nestable_lock.ipynb | 57 ++ notebook/Examples_nested_loop.ipynb | 82 ++ notebook/Examples_nesting_restrict.ipynb | 189 +++++ notebook/Examples_nowait.ipynb | 89 +++ notebook/Examples_nthrs_dynamic.ipynb | 96 +++ notebook/Examples_nthrs_nesting.ipynb | 57 ++ notebook/Examples_ordered.ipynb | 107 +++ notebook/Examples_parallel.ipynb | 57 ++ notebook/Examples_ploop.ipynb | 57 ++ notebook/Examples_pra_iterator.ipynb | 66 ++ notebook/Examples_private.ipynb | 110 +++ notebook/Examples_psections.ipynb | 57 ++ notebook/Examples_reduction.ipynb | 202 +++++ notebook/Examples_set_dynamic_nthrs.ipynb | 71 ++ notebook/Examples_simple_lock.ipynb | 71 ++ notebook/Examples_single.ipynb | 57 ++ notebook/Examples_standalone.ipynb | 103 +++ notebook/Examples_target.ipynb | 282 +++++++ notebook/Examples_target_data.ipynb | 340 +++++++++ .../Examples_target_unstructured_data.ipynb | 118 +++ notebook/Examples_target_update.ipynb | 152 ++++ notebook/Examples_task_dep.ipynb | 220 ++++++ notebook/Examples_task_priority.ipynb | 73 ++ notebook/Examples_taskgroup.ipynb | 64 ++ notebook/Examples_tasking.ipynb | 417 +++++++++++ notebook/Examples_taskloop.ipynb | 60 ++ notebook/Examples_taskyield.ipynb | 57 ++ notebook/Examples_teams.ipynb | 308 ++++++++ notebook/Examples_threadprivate.ipynb | 284 +++++++ notebook/Examples_workshare.ipynb | 195 +++++ notebook/Examples_worksharing_critical.ipynb | 57 ++ notebook/History.ipynb | 128 ++++ notebook/Introduction_Chapt.ipynb | 139 ++++ notebook/Title_Page.ipynb | 217 ++++++ notebook/openmp-examples.ipynb | 255 +++++++ notebook/tex2notebook.py | 4 + 87 files changed, 10735 insertions(+) create mode 100644 notebook/Chap_SIMD.ipynb create mode 100644 notebook/Chap_affinity.ipynb create mode 100644 notebook/Chap_data_environment.ipynb create mode 100644 notebook/Chap_devices.ipynb create mode 100644 notebook/Chap_memory_model.ipynb create mode 100644 notebook/Chap_parallel_execution.ipynb create mode 100644 notebook/Chap_program_control.ipynb create mode 100644 notebook/Chap_synchronization.ipynb create mode 100644 notebook/Chap_tasking.ipynb create mode 100644 notebook/Examples_Chapt.ipynb create mode 100644 notebook/Examples_SIMD.ipynb create mode 100644 notebook/Examples_affinity.ipynb create mode 100644 notebook/Examples_affinity_query.ipynb create mode 100644 notebook/Examples_array_sections.ipynb create mode 100644 notebook/Examples_associate.ipynb create mode 100644 notebook/Examples_async_target_depend.ipynb create mode 100644 notebook/Examples_async_target_nowait.ipynb create mode 100644 notebook/Examples_async_target_nowait_depend.ipynb create mode 100644 notebook/Examples_async_target_with_tasks.ipynb create mode 100644 notebook/Examples_atomic.ipynb create mode 100644 notebook/Examples_atomic_restrict.ipynb create mode 100644 notebook/Examples_barrier_regions.ipynb create mode 100644 notebook/Examples_cancellation.ipynb create mode 100644 notebook/Examples_carrays_fpriv.ipynb create mode 100644 notebook/Examples_collapse.ipynb create mode 100644 notebook/Examples_cond_comp.ipynb create mode 100644 notebook/Examples_copyin.ipynb create mode 100644 notebook/Examples_copyprivate.ipynb create mode 100644 notebook/Examples_cpp_reference.ipynb create mode 100644 notebook/Examples_critical.ipynb create mode 100644 notebook/Examples_declare_target.ipynb create mode 100644 notebook/Examples_default_none.ipynb create mode 100644 notebook/Examples_device.ipynb create mode 100644 notebook/Examples_doacross.ipynb create mode 100644 notebook/Examples_flush_nolist.ipynb create mode 100644 notebook/Examples_fort_do.ipynb create mode 100644 notebook/Examples_fort_loopvar.ipynb create mode 100644 notebook/Examples_fort_race.ipynb create mode 100644 notebook/Examples_fort_sa_private.ipynb create mode 100644 notebook/Examples_fort_sp_common.ipynb create mode 100644 notebook/Examples_fpriv_sections.ipynb create mode 100644 notebook/Examples_get_nthrs.ipynb create mode 100644 notebook/Examples_icv.ipynb create mode 100644 notebook/Examples_init_lock.ipynb create mode 100644 notebook/Examples_init_lock_with_hint.ipynb create mode 100644 notebook/Examples_lastprivate.ipynb create mode 100644 notebook/Examples_linear_in_loop.ipynb create mode 100644 notebook/Examples_lock_owner.ipynb create mode 100644 notebook/Examples_locks.ipynb create mode 100644 notebook/Examples_master.ipynb create mode 100644 notebook/Examples_mem_model.ipynb create mode 100644 notebook/Examples_nestable_lock.ipynb create mode 100644 notebook/Examples_nested_loop.ipynb create mode 100644 notebook/Examples_nesting_restrict.ipynb create mode 100644 notebook/Examples_nowait.ipynb create mode 100644 notebook/Examples_nthrs_dynamic.ipynb create mode 100644 notebook/Examples_nthrs_nesting.ipynb create mode 100644 notebook/Examples_ordered.ipynb create mode 100644 notebook/Examples_parallel.ipynb create mode 100644 notebook/Examples_ploop.ipynb create mode 100644 notebook/Examples_pra_iterator.ipynb create mode 100644 notebook/Examples_private.ipynb create mode 100644 notebook/Examples_psections.ipynb create mode 100644 notebook/Examples_reduction.ipynb create mode 100644 notebook/Examples_set_dynamic_nthrs.ipynb create mode 100644 notebook/Examples_simple_lock.ipynb create mode 100644 notebook/Examples_single.ipynb create mode 100644 notebook/Examples_standalone.ipynb create mode 100644 notebook/Examples_target.ipynb create mode 100644 notebook/Examples_target_data.ipynb create mode 100644 notebook/Examples_target_unstructured_data.ipynb create mode 100644 notebook/Examples_target_update.ipynb create mode 100644 notebook/Examples_task_dep.ipynb create mode 100644 notebook/Examples_task_priority.ipynb create mode 100644 notebook/Examples_taskgroup.ipynb create mode 100644 notebook/Examples_tasking.ipynb create mode 100644 notebook/Examples_taskloop.ipynb create mode 100644 notebook/Examples_taskyield.ipynb create mode 100644 notebook/Examples_teams.ipynb create mode 100644 notebook/Examples_threadprivate.ipynb create mode 100644 notebook/Examples_workshare.ipynb create mode 100644 notebook/Examples_worksharing_critical.ipynb create mode 100644 notebook/History.ipynb create mode 100644 notebook/Introduction_Chapt.ipynb create mode 100644 notebook/Title_Page.ipynb create mode 100644 notebook/openmp-examples.ipynb diff --git a/notebook/Chap_SIMD.ipynb b/notebook/Chap_SIMD.ipynb new file mode 100644 index 0000000..158dc56 --- /dev/null +++ b/notebook/Chap_SIMD.ipynb @@ -0,0 +1,73 @@ +{ + "cells": [ +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ## SIMD" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Single instruction, multiple data (SIMD) is a form of parallel execution in which the same operation is performed on multiple data elements independently in hardware vector processing units (VPU), also called SIMD units. The addition of two vectors to form a third vector is a SIMD operation. Many processors have SIMD (vector) units that can perform simultaneously 2, 4, 8 or more executions of the same operation (by a single SIMD unit). " + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Loops without loop-carried backward dependency (or with dependency preserved using ordered simd) are candidates for vectorization by the compiler for execution with SIMD units. In addition, with state-of-the-art vectorization technology and `declare simd` construct extensions for function vectorization in the OpenMP 4.5 specification, loops with function calls can be vectorized as well. The basic idea is that a scalar function call in a loop can be replaced by a vector version of the function, and the loop can be vectorized simultaneously by combining a loop vectorization ( `simd` directive on the loop) and a function vectorization ( `declare simd` directive on the function)." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " A `simd` construct states that SIMD operations be performed on the data within the loop. A number of clauses are available to provide data-sharing attributes ( `private` , `linear` , `reduction` and `lastprivate` ). Other clauses provide vector length preference/restrictions ( `simdlen` / `safelen` ), loop fusion ( `collapse` ), and data alignment ( `aligned` )." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `declare simd` directive designates that a vector version of the function should also be constructed for execution within loops that contain the function and have a `simd` directive. Clauses provide argument specifications ( `linear` , `uniform` , and `aligned` ), a requested vector length ( `simdlen` ), and designate whether the function is always/never called conditionally in a loop ( `branch` / `inbranch` ). The latter is for optimizing peformance." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Also, the `simd` construct has been combined with the worksharing loop constructs ( `for simd` and `do simd` ) to enable simultaneous thread execution in different SIMD units. \n", +"Hence, the `simd` construct can be \n", +"used alone on a loop to direct vectorization (SIMD execution), or in \n", +"combination with a parallel loop construct to include thread parallelism \n", +"(a parallel loop sequentially followed by a `simd` construct, \n", +"or a combined construct such as `parallel do simd` or \n", +" `parallel for simd` )." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end---" + ] + } +], +"metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } +}, +"nbformat": 4, +"nbformat_minor": 2 +} diff --git a/notebook/Chap_affinity.ipynb b/notebook/Chap_affinity.ipynb new file mode 100644 index 0000000..8a20a81 --- /dev/null +++ b/notebook/Chap_affinity.ipynb @@ -0,0 +1,170 @@ +{ + "cells": [ +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ## OpenMP Affinity" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " OpenMP Affinity consists of a `proc_bind` policy (thread affinity policy) and a specification of places ( ' location units ' or _processors_ that may be cores, hardware threads, sockets, etc.). OpenMP Affinity enables users to bind computations on specific places. The placement will hold for the duration of the parallel region. However, the runtime is free to migrate the OpenMP threads to different cores (hardware threads, sockets, etc.) prescribed within a given place, if two or more cores (hardware threads, sockets, etc.) have been assigned to a given place." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Often the binding can be managed without resorting to explicitly setting places. Without the specification of places in the `OMP_PLACES` variable, the OpenMP runtime will distribute and bind threads using the entire range of processors for the OpenMP program, according to the `OMP_PROC_BIND` environment variable or the `proc_bind` clause. When places are specified, the OMP runtime binds threads to the places according to a default distribution policy, or those specified in the `OMP_PROC_BIND` environment variable or the `proc_bind` clause." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the OpenMP Specifications document a processor refers to an execution unit that is enabled for an OpenMP thread to use. A processor is a core when there is no SMT (Simultaneous Multi-Threading) support or SMT is disabled. When SMT is enabled, a processor is a hardware thread (HW-thread). (This is the usual case; but actually, the execution unit is implementation defined.) Processor numbers are numbered sequentially from 0 to the number of cores less one (without SMT), or 0 to the number HW-threads less one (with SMT). OpenMP places use the processor number to designate binding locations (unless an ' abstract name ' is used.) " + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The processors available to a process may be a subset of the system's processors. This restriction may be the result of a wrapper process controlling the execution (such as `numactl` on Linux systems), compiler options, library-specific environment variables, or default kernel settings. For instance, the execution of multiple MPI processes, launched on a single compute node, will each have a subset of processors as determined by the MPI launcher or set by MPI affinity environment variables for the MPI library. \n", +"Forked threads within an MPI process \n", +"(for a hybrid execution of MPI and OpenMP code) inherit the valid \n", +"processor set for execution from the parent process (the initial task region) \n", +"when a parallel region forks threads. The binding policy set in \n", +" `OMP_PROC_BIND` or the `proc_bind` clause will be applied to \n", +"the subset of processors available to _the particular_ MPI process." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"Also, setting an explicit list of processor numbers in the `OMP_PLACES` \n", +"variable before an MPI launch (which involves more than one MPI process) will \n", +"result in unspecified behavior (and doesn't make sense) because the set of \n", +"processors in the places list must not contain processors outside the subset \n", +"of processors for an MPI process. A separate `OMP_PLACES` variable must \n", +"be set for each MPI process, and is usually accomplished by launching a script \n", +"which sets `OMP_PLACES` specifically for the MPI process. " + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Threads of a team are positioned onto places in a compact manner, a scattered distribution, or onto the master's place, by setting the `OMP_PROC_BIND` environment variable or the `proc_bind` clause to _close_ , _spread_ , or _master_ , respectively. When `OMP_PROC_BIND` is set to FALSE no binding is enforced; and when the value is TRUE, the binding is implementation defined to a set of places in the `OMP_PLACES` variable or to places defined by the implementation if the `OMP_PLACES` variable is not set." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `OMP_PLACES` variable can also be set to an abstract name ( _threads_ , _cores_ , _sockets_ ) to specify that a place is either a single hardware thread, a core, or a socket, respectively. This description of the `OMP_PLACES` is most useful when the number of threads is equal to the number of hardware thread, cores or sockets. It can also be used with a _close_ or _spread_ distribution policy when the equality doesn't hold." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +" We need an example of using sockets, cores and threads:" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +" case 1 cores:" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +" Hyper-Threads on (2 hardware threads per core) \n", +" 1 socket x 4 cores x 2 HW-threads \n", +" \n", +" export OMP_NUM_THREADS=4 \n", +" export OMP_PLACES=threads \n", +" \n", +" core # 0 1 2 3 \n", +" processor # 0,1 2,3 4,5 6,7 \n", +" thread # 0 * _ _ _ _ _ _ _ #mask for thread 0 \n", +" thread # 1 _ _ * _ _ _ _ _ #mask for thread 1 \n", +" thread # 2 _ _ _ _ * _ _ _ #mask for thread 2 \n", +" thread # 3 _ _ _ _ _ _ * _ #mask for thread 3" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +" case 2 threads: \n", +" \n", +" Hyper-Threads on (2 hardware threads per core) \n", +" 1 socket x 4 cores x 2 HW-threads \n", +" \n", +" export OMP_NUM_THREADS=4 \n", +" export OMP_PLACES=cores \n", +" \n", +" core # 0 1 2 3 \n", +" processor # 0,1 2,3 4,5 6,7 \n", +" thread # 0 * * _ _ _ _ _ _ #mask for thread 0 \n", +" thread # 1 _ _ * * _ _ _ _ #mask for thread 1 \n", +" thread # 2 _ _ _ _ * * _ _ #mask for thread 2 \n", +" thread # 3 _ _ _ _ _ _ * * #mask for thread 3" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +" case 3 sockets: \n", +" \n", +" No Hyper-Threads \n", +" 3 socket x 4 cores \n", +" \n", +" export OMP_NUM_THREADS=3 \n", +" export OMP_PLACES=sockets \n", +" \n", +" socket # 0 1 2 \n", +" processor # 0,1,2,3 4,5,6,7 8,9,10,11 \n", +" thread # 0 * * * * _ _ _ _ _ _ _ _ #mask for thread 0 \n", +" thread # 0 _ _ _ _ * * * * _ _ _ _ #mask for thread 1 \n", +" thread # 0 _ _ _ _ _ _ _ _ * * * * #mask for thread 2" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end---" + ] + } +], +"metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } +}, +"nbformat": 4, +"nbformat_minor": 2 +} diff --git a/notebook/Chap_data_environment.ipynb b/notebook/Chap_data_environment.ipynb new file mode 100644 index 0000000..a96a244 --- /dev/null +++ b/notebook/Chap_data_environment.ipynb @@ -0,0 +1,121 @@ +{ + "cells": [ +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ## Data Environment" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The OpenMP _data environment_ contains data attributes of variables and objects. Many constructs (such as `parallel` , `simd` , `task` ) accept clauses to control _data-sharing_ attributes of referenced variables in the construct, where _data-sharing_ applies to whether the attribute of the variable is _shared_ , is _private_ storage, or has special operational characteristics (as found in the `firstprivate` , `lastprivate` , `linear` , or `reduction` clause)." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The data environment for a device (distinguished as a _device data environment_ ) is controlled on the host by _data-mapping_ attributes, which determine the relationship of the data on the host, the _original_ data, and the data on the device, the _corresponding_ data." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " bigskip DATA-SHARING ATTRIBUTES" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Data-sharing attributes of variables can be classified as being _predetermined_ , _explicitly determined_ or _implicitly determined_ ." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Certain variables and objects have predetermined attributes. A commonly found case is the loop iteration variable in associated loops of a `for` or `do` construct. It has a private data-sharing attribute. Variables with predetermined data-sharing attributes can not be listed in a data-sharing clause; but there are some exceptions (mainly concerning loop iteration variables)." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Variables with explicitly determined data-sharing attributes are those that are referenced in a given construct and are listed in a data-sharing attribute clause on the construct. Some of the common data-sharing clauses are: `shared` , `private` , `firstprivate` , `lastprivate` , `linear` , and `reduction` . \n", +" Are these all of them?" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Variables with implicitly determined data-sharing attributes are those that are referenced in a given construct, do not have predetermined data-sharing attributes, and are not listed in a data-sharing attribute clause of an enclosing construct. For a complete list of variables and objects with predetermined and implicitly determined attributes, please refer to the _Data-sharing Attribute Rules for Variables Referenced in a Construct_ subsection of the OpenMP Specifications document. " + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " bigskip DATA-MAPPING ATTRIBUTES" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `map` clause on a device construct explictly specifies how the list items in the clause are mapped from the encountering task's data environment (on the host) to the corresponding \n", +"* in the device data environment (on the device). The common _list items_ are arrays, array sections, scalars, pointers, and structure elements (members). " + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Procedures and global variables have predetermined data mapping if they appear within the list or block of a `declare target` directive. Also, a C/C++ pointer is mapped as a zero-length array section, as is a C++ variable that is a reference to a pointer. \n", +" Waiting for response from Eric on this." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Without explict mapping, non-scalar and non-pointer variables within the scope of the `target` construct are implicitly mapped with a _map-type_ of `tofrom` . Without explicit mapping, scalar variables within the scope of the `target` construct are not mapped, but have an implicit firstprivate data-sharing attribute. (That is, the value of the original variable is given to a private variable of the same name on the device.) This behavior can be changed with the `defaultmap` clause." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `map` clause can appear on `target` , `target data` and `target enter/exit data` constructs. The operations of creation and removal of device storage as well as assignment of the original list \n", +"* values to the corresponding list items may be complicated when the list \n", +"* appears on multiple constructs or when the host and device storage is shared. In these cases the item's reference count, the number of times it has been referenced (+1 on entry and -1 on exited) in nested (structured) map regions and/or accumulative (unstructured) mappings, determines the operation. Details of the `map` clause and reference count operation are specified in the _map Clause_ subsection of the OpenMP Specifications document." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end---" + ] + } +], +"metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } +}, +"nbformat": 4, +"nbformat_minor": 2 +} diff --git a/notebook/Chap_devices.ipynb b/notebook/Chap_devices.ipynb new file mode 100644 index 0000000..266aa16 --- /dev/null +++ b/notebook/Chap_devices.ipynb @@ -0,0 +1,81 @@ +{ + "cells": [ +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ## Devices" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `target` construct consists of a `target` directive and an execution region. The `target` region is executed on the default device or the device specified in the `device` clause. " + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In OpenMP version 4.0, by default, all variables within the lexical scope of the construct are copied _to_ and _from_ the device, unless the device is the host, or the data exists on the device from a previously executed data-type construct that has created space on the device and possibly copied host data to the device storage." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The constructs that explicitly create storage, transfer data, and free storage on the device are catagorized as structured and unstructured. The `target` `data` construct is structured. It creates a data region around `target` constructs, and is convenient for providing persistent data throughout multiple `target` regions. The `target` `enter` `data` and `target` `exit` `data` constructs are unstructured, because they can occur anywhere and do not support a 'structure' (a region) for enclosing `target` constructs, as does the `target` `data` construct. " + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `map` clause is used on `target` constructs and the data-type constructs to map host data. It specifies the device storage and data movement `to` and `from` the device, and controls on the storage duration." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " There is an important change in the OpenMP 4.5 specification that alters the data model for scalar variables and C/C++ pointer variables. The default behavior for scalar variables and C/C++ pointer variables in an 4.5 compliant code is `firstprivate` . Example codes that have been updated to reflect this new behavior are annotated with a description that describes changes required for correct execution. Often it is a simple matter of mapping the variable as `tofrom` to obtain the intended 4.0 behavior." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In OpenMP version 4.5 the mechanism for target execution is specified as occuring through a _target task_ . When the `target` construct is encountered a new _target task_ is generated. The _target task_ completes after the `target` region has executed and all data transfers have finished." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " This new specification does not affect the execution of pre-4.5 code; it is a necessary element for asynchronous execution of the `target` region when using the new `nowait` clause introduced in OpenMP 4.5." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end---" + ] + } +], +"metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } +}, +"nbformat": 4, +"nbformat_minor": 2 +} diff --git a/notebook/Chap_memory_model.ipynb b/notebook/Chap_memory_model.ipynb new file mode 100644 index 0000000..2289b84 --- /dev/null +++ b/notebook/Chap_memory_model.ipynb @@ -0,0 +1,146 @@ +{ + "cells": [ +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ## Memory Model" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In this chapter, examples illustrate race conditions on access to variables with shared data-sharing attributes. A race condition can exist when two or more threads are involved in accessing a variable in which not all of the accesses are reads; that is, a WaR, RaW or WaW condition exists (R=read, a=after, W=write). A RaR does not produce a race condition. Ensuring thread execution order at the processor level is not enough to avoid race conditions, because the local storage at the processor level (registers, caches, etc.) must be synchronized so that a consistent view of the variable in the memory hierarchy can be seen by the threads accessing the variable." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " OpenMP provides a shared-memory model which allows all threads access to _memory_ (shared data). Each thread also has exclusive access to _threadprivate memory_ (private data). A private variable referenced in an OpenMP directive's structured block is a new version of the original variable (with the same name) for each task (or SIMD lane) within the code block. A private variable is initially undefined (except for variables in `firstprivate` and `linear` clauses), and the original variable value is unaltered by assignments to the private variable, (except for `reduction` , `lastprivate` and `linear` clauses)." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Private variables in an outer `parallel` region can be shared by implicit tasks of an inner `parallel` region (with a `share` clause on the inner `parallel` directive). Likewise, a private variable may be shared in the region of an explicit `task` (through a `shared` clause)." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `flush` directive forces a consistent view of local variables of the thread executing the `flush` . When a list is supplied on the directive, only the items (variables) in the list are guaranteed to be flushed." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Implied flushes exist at prescribed locations of certain constructs. For the complete list of these locations and associated constructs, please refer to the _flush Construct_ section of the OpenMP Specifications document." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +" The following table lists construct in which implied flushes exist, and the \n", +" location of their execution. \n", +" \n", +" \n", +"[hb] \n", +" \n", +" \n", +"caption {Execution Location for Implicit Flushes. } \n", +" { | p{0.6linewidth} | l | } \n", +" hline \n", +" `CONSTRUCT` & makecell{ `EXECUTION` `LOCATION` } \n", +" hline \n", +" `parallel` & upon entry and exit \n", +" hline \n", +" makecell[l]{worksharing hspace{1.5em} `for` , `do` \n", +" hspace{1.5em} `sections` \n", +" hspace{1.5em} `single` \n", +" hspace{1.5em} `workshare` } \n", +" & upon exit \n", +" hline \n", +" `critical` & upon entry and exit \n", +" hline \n", +" `target` & upon entry and exit \n", +" hline \n", +" `barrier` & during \n", +" hline \n", +" `atomic` operation with _seq_cst_ clause & upon entry and exit \n", +" hline \n", +" `ordered` * & upon entry and exit \n", +" hline \n", +" `cancel` ** and `cancellation point` ** & during \n", +" hline \n", +" `target data` & upon entry and exit \n", +" hline \n", +" `target update` + `to` clause, \n", +" `target enter data` & on entry \n", +" hline \n", +" `target update` + `from` clause, \n", +" `target exit data` & on exit \n", +" hline \n", +" `omp_set_lock` & during \n", +" hline \n", +" makecell[l]{ `omp_set/unset_lock` , `omp_test_lock` *** \n", +" `omp_set/unset/test_nest_lock` *** } \n", +" & during \n", +" hline \n", +" task scheduling point & makecell[l]{immediately before and after} \n", +" hline \n", +" \n", +" \n", +"caption {Execution Location for Implicit Flushes. } \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" * without clauses and with `threads` or `depend` clauses newline \n", +" ** when _cancel-var_ ICV is _true_ (cancellation is turned on) and cancellation is activated newline \n", +" *** if the region causes the lock to be set or unset \n", +" \n", +" A flush with a list is implied for non-sequentially consistent `atomic` operations \n", +" ( `atomic` directive without a `seq_cst` clause), where the list \n", +"* is the \n", +" specific storage location accessed atomically (specified as the _x_ variable \n", +" in _atomic Construct_ subsection of the OpenMP Specifications document)." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Examples 1-3 show the difficulty of synchronizing threads through `flush` and `atomic` directives." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end---" + ] + } +], +"metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } +}, +"nbformat": 4, +"nbformat_minor": 2 +} diff --git a/notebook/Chap_parallel_execution.ipynb b/notebook/Chap_parallel_execution.ipynb new file mode 100644 index 0000000..2252786 --- /dev/null +++ b/notebook/Chap_parallel_execution.ipynb @@ -0,0 +1,165 @@ +{ + "cells": [ +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ## Parallel Execution" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " A single thread, the _initial thread_ , begins sequential execution of an OpenMP enabled program, as if the whole program is in an implicit parallel region consisting of an implicit task executed by the _initial thread_ ." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " A `parallel` construct encloses code, forming a parallel region. An _initial thread_ encountering a `parallel` region forks (creates) a team of threads at the beginning of the `parallel` region, and joins them (removes from execution) at the end of the region. The initial thread becomes the master thread of the team in a `parallel` region with a _thread_ number equal to zero, the other threads are numbered from 1 to number of threads minus 1. A team may be comprised of just a single thread." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Each thread of a team is assigned an implicit task consisting of code within the parallel region. The task that creates a parallel region is suspended while the tasks of the team are executed. A thread is tied to its task; that is, only the thread assigned to the task can execute that task. After completion of the `parallel` region, the master thread resumes execution of the generating task. " + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"After the `parallel` region the master thread becomes the initial \n", +"thread again, and continues to execute the _sequential part_ . " + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Any task within a `parallel` region is allowed to encounter another `parallel` region to form a nested `parallel` region. The parallelism of a nested `parallel` region (whether it forks additional threads, or is executed serially by the encountering task) can be controlled by the `OMP_NESTED` environment variable or the `omp_set_nested()` API routine with arguments indicating true or false." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The number of threads of a `parallel` region can be set by the `OMP_NUM_THREADS` environment variable, the `omp_set_num_threads()` routine, or on the `parallel` directive with the `num_threads` clause. The routine overrides the environment variable, and the clause overrides all. Use the `OMP_DYNAMIC` or the `omp_set_dynamic()` function to specify that the OpenMP implementation dynamically adjust the number of threads for `parallel` regions. The default setting for dynamic adjustment is implementation defined. When dynamic adjustment is on and the number of threads is specified, the number of threads becomes an upper limit for the number of threads to be provided by the OpenMP runtime." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " WORKSHARING CONSTRUCTS" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " A worksharing construct distributes the execution of the associated region among the members of the team that encounter it. There is an implied barrier at the end of the worksharing region (there is no barrier at the beginning). The worksharing constructs are:" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* loop constructs: { `for` and `do` } \n", +"* `sections` \n", +"* `single` \n", +"* `workshare` " + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `for` and `do` constructs (loop constructs) create a region consisting of a loop. A loop controlled by a loop construct is called an _associated_ loop. Nested loops can form a single region when the `collapse` clause (with an integer argument) designates the number of _associated_ loops to be executed in parallel, by forming a 'single iteration space' for the specified number of nested loops. The `ordered` clause can also control multiple associated loops." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " An associated loop must adhere to a 'canonical form' (specified in the _Canonical Loop Form_ of the OpenMP Specifications document) which allows the iteration count (of all associated loops) to be computed before the (outermost) loop is executed. \n", +"[58:27-29]. Most common loops comply with the canonical form, including C++ iterators." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " A `single` construct forms a region in which only one thread (any one of the team) executes the region. The other threads wait at the implied barrier at the end, unless the `nowait` clause is specified." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `sections` construct forms a region that contains one or more structured blocks. Each block of a `sections` directive is constructed with a `section` construct, and executed once by one of the threads (any one) in the team. (If only one block is formed in the region, the `section` construct, which is used to separate blocks, is not required.) The other threads wait at the implied barrier at the end, unless the `nowait` clause is specified." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `workshare` construct is a Fortran feature that consists of a region with a single structure block (section of code). Statements in the `workshare` region are divided into units of work, and executed (once) by threads of the team. " + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " bigskip MASTER CONSTRUCT" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `master` construct is not a worksharing construct. The master region is is executed only by the master thread. There is no implicit barrier (and flush) at the end of the `master` region; hence the other threads of the team continue execution beyond code statements beyond the `master` region." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end---" + ] + } +], +"metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } +}, +"nbformat": 4, +"nbformat_minor": 2 +} diff --git a/notebook/Chap_program_control.ipynb b/notebook/Chap_program_control.ipynb new file mode 100644 index 0000000..84e65c8 --- /dev/null +++ b/notebook/Chap_program_control.ipynb @@ -0,0 +1,151 @@ +{ + "cells": [ +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ## Program Control" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Some specific and elementary concepts of controlling program execution are illustrated in the examples of this chapter. Control can be directly managed with conditional control code (ifdef's with the `_OPENMP` macro, and the Fortran sentinel ( `!$` ) for conditionally compiling). The `if` clause on some constructs can direct the runtime to ignore or alter the behavior of the construct. Of course, the base-language `if` statements can be used to control the 'execution' of stand-alone directives (such as `flush` , `barrier` , `taskwait` , and `taskyield` ). However, the directives must appear in a block structure, and not as a substatement as shown in examples 1 and 2 of this chapter." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " bigskip CANCELLATION" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Cancellation (termination) of the normal sequence of execution for the threads in an OpenMP region can be accomplished with the `cancel` construct. The construct uses a _construct-type-clause_ to set the region-type to activate for the cancellation. That is, inclusion of one of the _construct-type-clause_ names `parallel` , `for` , `do` , `sections` or `taskgroup` on the directive line activates the corresponding region. The `cancel` construct is activated by the first encountering thread, and it continues execution at the end of the named region. The `cancel` construct is also a concellation point for any other thread of the team to also continue execution at the end of the named region. " + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Also, once the specified region has been activated for cancellation any thread that encounnters a `cancellation point` construct with the same named region ( _construct-type-clause_ ), continues execution at the end of the region." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " For an activated `cancel taskgroup` construct, the tasks that belong to the taskgroup set of the innermost enclosing taskgroup region will be canceled. " + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " A task that encounters the cancel taskgroup construct continues execution at the end of its task region. Any task of the taskgroup that has already begun execution will run to completion, unless it encounters a `cancellation point` ; tasks that have not begun execution 'may' be discarded as completed tasks." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " bigskip CONTROL VARIABLES " + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Internal control variables (ICV) are used by implementations to hold values which control the execution of OpenMP regions. Control (and hence the ICVs) may be set as implementation defaults, or set and adjusted through environment variables, clauses, and API functions. Many of the ICV control values are accessible through API function calls. Also, initial ICV values are reported by the runtime if the `OMP_DISPLAY_ENV` environment variable has been set to `TRUE` . " + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"As an example, the _nthreads-var_ is the ICV that holds the number of threads \n", +"to be used in a `parallel` region. It can be set with the `OMP_NUM_THREADS` environment variable, \n", +"the `omp_set_num_threads()` API function, or the `num_threads` clause. The default _nthreads-var_ \n", +"value is implementation defined. All of the ICVs are presented in the _Internal Control Variables_ section \n", +"of the _Directives_ chapter of the OpenMP Specifications document. Within the same document section, override \n", +"relationships and scoping information can be found for applying user specifications and understanding the \n", +"extent of the control." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " bigskip NESTED CONSTRUCTS" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Certain combinations of nested constructs are permitted, giving rise to a _combined_ construct consisting of two or more constructs. These can be used when the two (or several) constructs would be used immediately in succession (closely nested). A combined construct can use the clauses of the component constructs without restrictions. A _composite_ construct is a combined construct which has one or more clauses with (an often obviously) modified or restricted meaning, relative to when the constructs are uncombined. \n", +"\n", +"[appear separately (singly)." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"The combined `parallel do` and `parallel for` constructs are formed by combining the `parallel` \n", +"construct with one of the loops constructs `do` or `for` . The \n", +" `parallel do SIMD` and `parallel for SIMD` constructs are composite constructs (composed from \n", +"the parallel loop constructs and the `SIMD` construct), because the `collapse` clause must \n", +"explicitly address the ordering of loop chunking _and_ SIMD 'combined' execution." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Certain nestings are forbidden, and often the reasoning is obvious. Worksharing constructs cannot be nested, and the `barrier` construct cannot be nested inside a worksharing construct, or a `critical` construct. Also, `target` constructs cannot be nested. " + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `parallel` construct can be nested, as well as the `task` construct. The parallel execution in the nested `parallel` construct(s) is control by the `OMP_NESTED` and `OMP_MAX_ACTIVE_LEVELS` environment variables, and the `omp_set_nested()` and `omp_set_max_active_levels()` functions." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " More details on nesting can be found in the _Nesting of Regions_ of the _Directives_ chapter in the OpenMP Specifications document." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end---" + ] + } +], +"metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } +}, +"nbformat": 4, +"nbformat_minor": 2 +} diff --git a/notebook/Chap_synchronization.ipynb b/notebook/Chap_synchronization.ipynb new file mode 100644 index 0000000..d64fbf0 --- /dev/null +++ b/notebook/Chap_synchronization.ipynb @@ -0,0 +1,90 @@ +{ + "cells": [ +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ## Synchronization" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `barrier` construct is a stand-alone directive that requires all threads of a team (within a contention group) to execute the barrier and complete execution of all tasks within the region, before continuing past the barrier." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `critical` construct is a directive that contains a structured block. The construct allows only a single thread at a time to execute the structured block (region). Multiple critical regions may exist in a parallel region, and may act cooperatively (only one thread at a time in all `critical` regions), or separately (only one thread at a time in each `critical` regions when a unique name is supplied on each `critical` construct). An optional (lock) `hint` clause may be specified on a named `critical` construct to provide the OpenMP runtime guidance in selection a locking mechanism." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " On a finer scale the `atomic` construct allows only a single thread at a time to have atomic access to a storage location involving a single read, write, update or capture statement, and a limited number of combinations when specifying the `capture` _atomic-clause_ clause. The _atomic-clause_ clause is required for some expression statements, but are not required for `update` statements. Please see the details in the _atomic Construct_ subsection of the _Directives_ chapter in the OpenMP Specifications document." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +" The following three sentences were stolen from the spec. The `ordered` construct either specifies a structured block in a loop, simd, or loop SIMD region that will be executed in the order of the loop iterations. The ordered construct sequentializes and orders the execution of ordered regions while allowing code outside the region to run in parallel." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Since OpenMP 4.5 the `ordered` construct can also be a stand-alone directive that specifies cross-iteration dependences in a doacross loop nest. The `depend` clause uses a `sink` _dependence-type_ , along with a iteration vector argument (vec) to indicate the iteration that satisfies the dependence. The `depend` clause with a `source` _dependence-type_ specifies dependence satisfaction." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `flush` directive is a stand-alone construct that forces a thread's temporal local storage (view) of a variable to memory where a consistent view of the variable storage can be accesses. When the construct is used without a variable list, all the locally thread-visible data as defined by the base language are flushed. A construct with a list applies the flush operation only to the items in the list. The `flush` construct also effectively insures that no memory (load or store) operation for the variable set (list items, or default set) may be reordered across the `flush` directive. " + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " General-purpose routines provide mutual exclusion semantics through locks, represented by lock variables. The semantics allows a task to _set_ , and hence _own_ a lock, until it is _unset_ by the task that set it. A _nestable_ lock can be set multiple times by a task, and is used when in code requires nested control of locks. A _simple lock_ can only be set once by the owning task. There are specific calls for the two types of locks, and the variable of a specific lock type cannot be used by the other lock type. " + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Any explicit task will observe the synchronization prescribed in a `barrier` construct and an implied barrier. Also, additional synchronizations are available for tasks. All children of a task will wait at a `taskwait` (for their siblings to complete). A `taskgroup` construct creates a region in which the current task is suspended at the end of the region until all sibling tasks, and their descendants, have completed. Scheduling constraints on task execution can be prescribed by the `depend` clause to enforce dependence on previously generated tasks. More details on controlling task executions can be found in the _Tasking_ Chapter in the OpenMP Specifications document. \n", +"(DO REF. RIGHT.)" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end---" + ] + } +], +"metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } +}, +"nbformat": 4, +"nbformat_minor": 2 +} diff --git a/notebook/Chap_tasking.ipynb b/notebook/Chap_tasking.ipynb new file mode 100644 index 0000000..40e9ca2 --- /dev/null +++ b/notebook/Chap_tasking.ipynb @@ -0,0 +1,75 @@ +{ + "cells": [ +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ## Tasking" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Tasking constructs provide units of work to a thread for execution. Worksharing constructs do this, too (e.g. `for` , `do` , `sections` , and `singles` constructs); but the work units are tightly controlled by an iteration limit and limited scheduling, or a limited number of `sections` or `single` regions. Worksharing was designed with ' data parallel ' computing in mind. Tasking was designed for ' task parallel ' computing and often involves non-locality or irregularity in memory access." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `task` construct can be used to execute work chunks: in a while loop; while traversing nodes in a list; at nodes in a tree graph; or in a normal loop (with a `taskloop` construct). Unlike the statically scheduled loop iterations of worksharing, a task is often enqueued, and then dequeued for execution by any of the threads of the team within a parallel region. The generation of tasks can be from a single generating thread (creating sibling tasks), or from multiple generators in a recursive graph tree traversals. \n", +"(creating a parent-descendents hierarchy of tasks, see example 4 and 7 below). A `taskloop` construct bundles iterations of an associated loop into tasks, and provides similar controls found in the `task` construct." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Sibling tasks are synchronized by the `taskwait` construct, and tasks and their descendent tasks can be synchronized by containing them in a `taskgroup` region. Ordered execution is accomplished by specifying dependences with a `depend` clause. Also, priorities can be specified as hints to the scheduler through a `priority` clause." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Various clauses can be used to manage and optimize task generation, as well as reduce the overhead of execution and to relinquish control of threads for work balance and forward progress. " + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Once a thread starts executing a task, it is the designated thread for executing the task to completion, even though it may leave the execution at a scheduling point and return later. The thread is tied to the task. Scheduling points can be introduced with the `taskyield` construct. With an `untied` clause any other thread is allowed to continue the task. An `if` clause with a _true_ expression allows the generating thread to immediately execute the task as an undeferred task. By including the data environment of the generating task into the generated task with the `mergeable` and `final` clauses, task generation overhead can be reduced." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " A complete list of the tasking constructs and details of their clauses can be found in the _Tasking Constructs_ chapter of the OpenMP Specifications, in the _OpenMP Application Programming Interface_ section." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end---" + ] + } +], +"metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } +}, +"nbformat": 4, +"nbformat_minor": 2 +} diff --git a/notebook/Examples_Chapt.ipynb b/notebook/Examples_Chapt.ipynb new file mode 100644 index 0000000..3575d43 --- /dev/null +++ b/notebook/Examples_Chapt.ipynb @@ -0,0 +1,50 @@ +{ + "cells": [ +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "chapter*{Examples}" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " addcontentsline{toc}{chapter}{protectnumberline{}Examples} The following are examples of the OpenMP API directives, constructs, and routines. ccppspecificstart A statement following a directive is compound only when necessary, and a non-compound statement is indented with respect to a directive preceding it. ccppspecificend" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Each example is labeled as _ename.seqno.ext_ , where _ename_ is the example name, _seqno_ is the sequence number in a section, and _ext_ is the source file extension to indicate the code type and source form. _ext_ is one of the following: \n", +"* _c_ -- C code, \n", +"* _cpp_ -- C++ code, \n", +"* _f_ -- Fortran code in fixed form, and \n", +"* _f90_ -- Fortran code in free form. " + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end---" + ] + } +], +"metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } +}, +"nbformat": 4, +"nbformat_minor": 2 +} diff --git a/notebook/Examples_SIMD.ipynb b/notebook/Examples_SIMD.ipynb new file mode 100644 index 0000000..cf3a0bf --- /dev/null +++ b/notebook/Examples_SIMD.ipynb @@ -0,0 +1,288 @@ +{ + "cells": [ +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +" ### `simd` and `declare` `simd` Constructs" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example illustrates the basic use of the `simd` construct to assure the compiler that the loop can be vectorized." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_SIMD.1.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_SIMD.1.f90" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " When a function can be inlined within a loop the compiler has an opportunity to vectorize the loop. By guaranteeing SIMD behavior of a function's operations, characterizing the arguments of the function and privatizing temporary variables of the loop, the compiler can often create faster, vector code for the loop. In the examples below the `declare` `simd` construct is used on the _add1_ and _add2_ functions to enable creation of their corresponding SIMD function versions for execution within the associated SIMD loop. The functions characterize two different approaches of accessing data within the function: by a single variable and as an element in a data array, respectively. The _add3_ C function uses dereferencing." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `declare` `simd` constructs also illustrate the use of `uniform` and `linear` clauses. The `uniform(fact)` clause indicates that the variable _fact_ is invariant across the SIMD lanes. In the _add2_ function _a_ and _b_ are included in the `unform` list because the C pointer and the Fortran array references are constant. The _i_ index used in the _add2_ function is included in a `linear` clause with a constant-linear-step of 1, to guarantee a unity increment of the associated loop. In the `declare` `simd` construct for the _add3_ C function the `linear(a,b:1)` clause instructs the compiler to generate unit-stride loads across the SIMD lanes; otherwise, costly emph{gather} instructions would be generated for the unknown sequence of access of the pointer dereferences." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the `simd` constructs for the loops the `private(tmp)` clause is necessary to assure that the each vector operation has its own _tmp_ variable." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_SIMD.2.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_SIMD.2.f90" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " A thread that encounters a SIMD construct executes a vectorized code of the iterations. Similar to the concerns of a worksharing loop a loop vectorized with a SIMD construct must assure that temporary and reduction variables are privatized and declared as reductions with clauses. The example below illustrates the use of `private` and `reduction` clauses in a SIMD construct." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_SIMD.3.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_SIMD.3.f90" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " A `safelen(N)` clause in a `simd` construct assures the compiler that there are no loop-carried dependencies for vectors of size _N_ or below. If the `safelen` clause is not specified, then the default safelen value is the number of loop iterations. The `safelen(16)` clause in the example below guarantees that the vector code is safe for vectors up to and including size 16. In the loop, _m_ can be 16 or greater, for correct code execution. If the value of _m_ is less than 16, the behavior is undefined." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_SIMD.4.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_SIMD.4.f90" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following SIMD construct instructs the compiler to collapse the _i_ and _j_ loops into a single SIMD loop in which SIMD chunks are executed by threads of the team. Within the workshared loop chunks of a thread, the SIMD chunks are executed in the lanes of the vector units." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_SIMD.5.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_SIMD.5.f90" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"\n", +"\n", +" section ### `inbranch` and `notinbranch` Clauses" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following examples illustrate the use of the `declare` `simd` construct with the `inbranch` and `notinbranch` clauses. The `notinbranch` clause informs the compiler that the function _foo_ is never called conditionally in the SIMD loop of the function _myaddint_ . On the other hand, the `inbranch` clause for the function goo indicates that the function is always called conditionally in the SIMD loop inside the function _myaddfloat_ ." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_SIMD.6.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_SIMD.6.f90" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the code below, the function _fib()_ is called in the main program and also recursively called in the function _fib()_ within an `if` condition. The compiler creates a masked vector version and a non-masked vector version for the function _fib()_ while retaining the original scalar version of the _fib()_ function." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_SIMD.7.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_SIMD.7.f90" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"\n", +"\n", +" section ### Loop-Carried Lexical Forward Dependence" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example tests the restriction on an SIMD loop with the loop-carried lexical forward-dependence. This dependence must be preserved for the correct execution of SIMD loops." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " A loop can be vectorized even though the iterations are not completely independent when it has loop-carried dependences that are forward lexical dependences, indicated in the code below by the read of _A[j+1]_ and the write to _A[j]_ in C/C++ code (or _A(j+1)_ and _A(j)_ in Fortran). That is, the read of _A[j+1]_ (or _A(j+1)_ in Fortran) before the write to _A[j]_ (or _A(j)_ in Fortran) ordering must be preserved for each iteration in _j_ for valid SIMD code generation." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " This test assures that the compiler preserves the loop carried lexical forward-dependence for generating a correct SIMD code." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_SIMD.8.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_SIMD.8.f90" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end---" + ] + } +], +"metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } +}, +"nbformat": 4, +"nbformat_minor": 2 +} diff --git a/notebook/Examples_affinity.ipynb b/notebook/Examples_affinity.ipynb new file mode 100644 index 0000000..97e96d0 --- /dev/null +++ b/notebook/Examples_affinity.ipynb @@ -0,0 +1,705 @@ +{ + "cells": [ +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### The `proc_bind` Clause" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following examples demonstrate how to use the `proc_bind` clause to control the thread binding for a team of threads in a `parallel` region. The machine architecture is depicted in the figure below. It consists of two sockets, each equipped with a quad-core processor and configured to execute two hardware threads simultaneously on each core. These examples assume a contiguous core numbering starting from 0, such that the hardware threads 0,1 form the first physical core." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " {figs/proc_bind_fig.pdf}} \n", +" fi" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following equivalent place list declarations consist of eight places (which we designate as p0 to p7):" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " `OMP_PLACES= ' {0,1},{2,3},{4,5},{6,7},{8,9},{10,11},{12,13},{14,15} ' ` " + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " or" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " `OMP_PLACES= ' {0:2}:8:2 ' ` " + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### Spread Affinity Policy" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows the result of the `spread` affinity policy on the partition list when the number of threads is less than or equal to the number of places in the parent's place partition, for the machine architecture depicted above. Note that the threads are bound to the first place of each subpartition." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_affinity.1.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_affinity.1.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " It is unspecified on which place the master thread is initially started. If the master thread is initially started on p0, the following placement of threads will be applied in the parallel region:" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* thread 0 executes on p0 with the place partition p0,p1" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* thread 1 executes on p2 with the place partition p2,p3" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* thread 2 executes on p4 with the place partition p4,p5" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* thread 3 executes on p6 with the place partition p6,p7 " + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " If the master thread would initially be started on p2, the placement of threads and distribution of the place partition would be as follows:" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* thread 0 executes on p2 with the place partition p2,p3" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* thread 1 executes on p4 with the place partition p4,p5" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* thread 2 executes on p6 with the place partition p6,p7" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* thread 3 executes on p0 with the place partition p0,p1 " + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example illustrates the `spread` thread affinity policy when the number of threads is greater than the number of places in the parent's place partition." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Let _T_ be the number of threads in the team, and _P_ be the number of places in the parent's place partition. The first _T/P_ threads of the team (including the master thread) execute on the parent's place. The next _T/P_ threads execute on the next place in the place partition, and so on, with wrap around. " + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_affinity.2.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_affinity.2.f90" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " It is unspecified on which place the master thread is initially started. If the master thread is initially started on p0, the following placement of threads will be applied in the parallel region:" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* threads 0,1 execute on p0 with the place partition p0" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* threads 2,3 execute on p1 with the place partition p1" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* threads 4,5 execute on p2 with the place partition p2" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* threads 6,7 execute on p3 with the place partition p3" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* threads 8,9 execute on p4 with the place partition p4" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* threads 10,11 execute on p5 with the place partition p5" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* threads 12,13 execute on p6 with the place partition p6" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* threads 14,15 execute on p7 with the place partition p7 " + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " If the master thread would initially be started on p2, the placement of threads and distribution of the place partition would be as follows:" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* threads 0,1 execute on p2 with the place partition p2" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* threads 2,3 execute on p3 with the place partition p3" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* threads 4,5 execute on p4 with the place partition p4" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* threads 6,7 execute on p5 with the place partition p5" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* threads 8,9 execute on p6 with the place partition p6" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* threads 10,11 execute on p7 with the place partition p7" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* threads 12,13 execute on p0 with the place partition p0" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* threads 14,15 execute on p1 with the place partition p1 " + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### Close Affinity Policy" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows the result of the `close` affinity policy on the partition list when the number of threads is less than or equal to the number of places in parent's place partition, for the machine architecture depicted above. The place partition is not changed by the `close` policy." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_affinity.3.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_affinity.3.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " It is unspecified on which place the master thread is initially started. If the master thread is initially started on p0, the following placement of threads will be applied in the `parallel` region:" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* thread 0 executes on p0 with the place partition p0-p7" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* thread 1 executes on p1 with the place partition p0-p7" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* thread 2 executes on p2 with the place partition p0-p7" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* thread 3 executes on p3 with the place partition p0-p7 " + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " If the master thread would initially be started on p2, the placement of threads and distribution of the place partition would be as follows:" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* thread 0 executes on p2 with the place partition p0-p7" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* thread 1 executes on p3 with the place partition p0-p7" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* thread 2 executes on p4 with the place partition p0-p7" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* thread 3 executes on p5 with the place partition p0-p7 " + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example illustrates the `close` thread affinity policy when the number of threads is greater than the number of places in the parent's place partition." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Let _T_ be the number of threads in the team, and _P_ be the number of places in the parent's place partition. The first _T/P_ threads of the team (including the master thread) execute on the parent's place. The next _T/P_ threads execute on the next place in the place partition, and so on, with wrap around. The place partition is not changed by the `close` policy." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_affinity.4.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_affinity.4.f90" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " It is unspecified on which place the master thread is initially started. If the master thread is initially running on p0, the following placement of threads will be applied in the parallel region:" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* threads 0,1 execute on p0 with the place partition p0-p7" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* threads 2,3 execute on p1 with the place partition p0-p7" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* threads 4,5 execute on p2 with the place partition p0-p7" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* threads 6,7 execute on p3 with the place partition p0-p7" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* threads 8,9 execute on p4 with the place partition p0-p7" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* threads 10,11 execute on p5 with the place partition p0-p7" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* threads 12,13 execute on p6 with the place partition p0-p7" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* threads 14,15 execute on p7 with the place partition p0-p7 " + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " If the master thread would initially be started on p2, the placement of threads and distribution of the place partition would be as follows:" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* threads 0,1 execute on p2 with the place partition p0-p7" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* threads 2,3 execute on p3 with the place partition p0-p7" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* threads 4,5 execute on p4 with the place partition p0-p7" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* threads 6,7 execute on p5 with the place partition p0-p7" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* threads 8,9 execute on p6 with the place partition p0-p7" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* threads 10,11 execute on p7 with the place partition p0-p7" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* threads 12,13 execute on p0 with the place partition p0-p7" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* threads 14,15 execute on p1 with the place partition p0-p7 " + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### Master Affinity Policy" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows the result of the `master` affinity policy on the partition list for the machine architecture depicted above. The place partition is not changed by the master policy." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_affinity.5.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_affinity.5.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " It is unspecified on which place the master thread is initially started. If the master thread is initially running on p0, the following placement of threads will be applied in the parallel region:" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* threads 0-3 execute on p0 with the place partition p0-p7 " + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " If the master thread would initially be started on p2, the placement of threads and distribution of the place partition would be as follows:" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* threads 0-3 execute on p2 with the place partition p0-p7 " + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end---" + ] + } +], +"metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } +}, +"nbformat": 4, +"nbformat_minor": 2 +} diff --git a/notebook/Examples_affinity_query.ipynb b/notebook/Examples_affinity_query.ipynb new file mode 100644 index 0000000..1b70cec --- /dev/null +++ b/notebook/Examples_affinity_query.ipynb @@ -0,0 +1,85 @@ +{ + "cells": [ +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Affinity Query Functions" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the example below a team of threads is generated on each socket of the system, using nested parallelism. Several query functions are used to gather information to support the creation of the teams and to obtain socket and thread numbers." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " For proper execution of the code, the user must create a place partition, such that each place is a listing of the core numbers for a socket. For example, in a 2 socket system with 8 cores in each socket, and sequential numbering in the socket for the core numbers, the `OMP_PLACES` variable would be set to '{0:8},{8:8}', using the place syntax { _lower_bound_ : _length_ : _stride_ }, and the default stride of 1." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The code determines the number of sockets ( _n_sockets_ ) using the `omp_get_num_places()` query function. In this example each place is constructed with a list of each socket's core numbers, hence the number of places is equal to the number of sockets. " + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The outer parallel region forms a team of threads, and each thread executes on a socket (place) because the `proc_bind` clause uses `spread` in the outer `parallel` construct. Next, in the _socket_init_ function, an inner parallel region creates a team of threads equal to the number of elements (core numbers) from the place of the parent thread. Because the outer `parallel` construct uses a `spread` affinity policy, each of its threads inherits a subpartition of the original partition. Hence, the `omp_get_place_num_procs` query function returns the number of elements (here procs = cores) in the subpartition of the thread. After each parent thread creates its nested parallel region on the section, the socket number and thread number are reported." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Note: Portable tools like hwloc (Portable HardWare LOCality package), which support many common operating systems, can be used to determine the configuration of a system. On some systems there are utilities, files or user guides that provide configuration information. For instance, the socket number and proc_id's for a socket can be found in the /proc/cpuinfo text file on Linux systems." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_affinity.6.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_affinity.6.f90" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end---" + ] + } +], +"metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } +}, +"nbformat": 4, +"nbformat_minor": 2 +} diff --git a/notebook/Examples_array_sections.ipynb b/notebook/Examples_array_sections.ipynb new file mode 100644 index 0000000..dee493a --- /dev/null +++ b/notebook/Examples_array_sections.ipynb @@ -0,0 +1,139 @@ +{ + "cells": [ +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Array Sections in Device Constructs" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following examples show the usage of array sections in `map` clauses on `target` and `target` `data` constructs." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " This example shows the invalid usage of two seperate sections of the same array inside of a `target` construct." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_array_sections.1.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_array_sections.1.f90" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " This example shows the invalid usage of two separate sections of the same array inside of a `target` construct." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_array_sections.2.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_array_sections.2.f90" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " This example shows the valid usage of two separate sections of the same array inside of a `target` construct." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_array_sections.3.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_array_sections.3.f90" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " This example shows the valid usage of a wholly contained array section of an already mapped array section inside of a `target` construct." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_array_sections.4.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_array_sections.4.f90" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end---" + ] + } +], +"metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } +}, +"nbformat": 4, +"nbformat_minor": 2 +} diff --git a/notebook/Examples_associate.ipynb b/notebook/Examples_associate.ipynb new file mode 100644 index 0000000..91aada5 --- /dev/null +++ b/notebook/Examples_associate.ipynb @@ -0,0 +1,94 @@ +{ + "cells": [ +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Fortran `ASSOCIATE` Construct" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " fortranspecificstart" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following is an invalid example of specifying an associate name on a data-sharing attribute clause. The constraint in the Data Sharing Attribute Rules section in the OpenMP 4.0 API Specifications states that an associate name preserves the association with the selector established at the `ASSOCIATE` statement. The associate name _b_ is associated with the shared variable _a_ . With the predetermined data-sharing attribute rule, the associate name _b_ is not allowed to be specified on the `private` clause." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_associate.1.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In next example, within the `parallel` construct, the association name _thread_id_ is associated with the private copy of _i_ . The print statement should output the unique thread number." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_associate.2.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example illustrates the effect of specifying a selector name on a data-sharing attribute clause. The associate name _u_ is associated with _v_ and the variable _v_ is specified on the `private` clause of the `parallel` construct. The construct association is established prior to the `parallel` region. The association between _u_ and the original _v_ is retained (see the Data Sharing Attribute Rules section in the OpenMP 4.0 API Specifications). Inside the `parallel` region, _v_ has the value of -1 and _u_ has the value of the original _v_ ." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_ffreenexampleassociate3" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " fortranspecificend" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end---" + ] + } +], +"metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } +}, +"nbformat": 4, +"nbformat_minor": 2 +} diff --git a/notebook/Examples_async_target_depend.ipynb b/notebook/Examples_async_target_depend.ipynb new file mode 100644 index 0000000..1561876 --- /dev/null +++ b/notebook/Examples_async_target_depend.ipynb @@ -0,0 +1,53 @@ +{ + "cells": [ +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Asynchronous `target` Execution and Dependences" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Asynchronous execution of a `target` region can be accomplished by creating an explicit task around the `target` region. Examples with explicit tasks are shown at the beginning of this section. " + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " As of OpenMP 4.5 and beyond the `nowait` clause can be used on the `target` directive for asynchronous execution. Examples with `nowait` clauses follow the explicit `task` examples." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " This section also shows the use of `depend` clauses to order executions through dependences." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end---" + ] + } +], +"metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } +}, +"nbformat": 4, +"nbformat_minor": 2 +} diff --git a/notebook/Examples_async_target_nowait.ipynb b/notebook/Examples_async_target_nowait.ipynb new file mode 100644 index 0000000..9380ed9 --- /dev/null +++ b/notebook/Examples_async_target_nowait.ipynb @@ -0,0 +1,78 @@ +{ + "cells": [ +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### `nowait` Clause on `target` Construct" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows how to execute code asynchronously on a device without an explicit task. The `nowait` clause on a `target` construct allows the thread of the _target task_ to perform other work while waiting for the `target` region execution to complete. Hence, the the `target` region can execute asynchronously on the device (without requiring a host thread to idle while waiting for the _target task_ execution to complete)." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In this example the product of two vectors (arrays), _v1_ and _v2_ , is formed. One half of the operations is performed on the device, and the last half on the host, concurrently." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " After a team of threads is formed the master thread generates the _target task_ while the other threads can continue on, without a barrier, to the execution of the host portion of the vector product. The completion of the _target task_ (asynchronous target execution) is guaranteed by the synchronization in the implicit barrier at the end of the host vector-product worksharing loop region. See the `barrier` glossary entry in the OpenMP specification for details." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The host loop scheduling is `dynamic` , to balance the host thread executions, since one thread is being used for offload generation. In the situation where little time is spent by the _target task_ in setting up and tearing down the the target execution, `static` scheduling may be desired. " + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_async_target.3.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_async_target.3.f90" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end---" + ] + } +], +"metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } +}, +"nbformat": 4, +"nbformat_minor": 2 +} diff --git a/notebook/Examples_async_target_nowait_depend.ipynb b/notebook/Examples_async_target_nowait_depend.ipynb new file mode 100644 index 0000000..c1dc205 --- /dev/null +++ b/notebook/Examples_async_target_nowait_depend.ipynb @@ -0,0 +1,80 @@ +{ + "cells": [ +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"begin #### Asynchronous `target` with `nowait` and `depend` Clauses" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " More details on dependences can be found in , Task Dependences. In this example, there are three flow dependences. In the first two dependences the target task does not execute until the preceding explicit tasks have finished. These dependences are produced by arrays _v1_ and _v2_ with the `out` dependence type in the first two tasks, and the `in` dependence type in the target task. " + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The last dependence is produced by array _p_ with the `out` dependence type in the target task, and the `in` dependence type in the last task. The last task does not execute until the target task finishes. " + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `nowait` clause on the `target` construct creates a deferrable _target task_ , allowing the encountering task to continue execution without waiting for the completion of the _target task_ ." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_async_target.4.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_async_target.4.f90" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"end" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end---" + ] + } +], +"metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } +}, +"nbformat": 4, +"nbformat_minor": 2 +} diff --git a/notebook/Examples_async_target_with_tasks.ipynb b/notebook/Examples_async_target_with_tasks.ipynb new file mode 100644 index 0000000..44b665c --- /dev/null +++ b/notebook/Examples_async_target_with_tasks.ipynb @@ -0,0 +1,124 @@ +{ + "cells": [ +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### Asynchronous `target` with Tasks" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows how the `task` and `target` constructs are used to execute multiple `target` regions asynchronously. The task that encounters the `task` construct generates an explicit task that contains a `target` region. The thread executing the explicit task encounters a task scheduling point while waiting for the execution of the `target` region to complete, allowing the thread to switch back to the execution of the encountering task or one of the previously generated explicit tasks." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_async_target.1.c" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The Fortran version has an interface block that contains the `declare` `target` . An identical statement exists in the function declaration (not shown here)." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_async_target.1.f90" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows how the `task` and `target` constructs are used to execute multiple `target` regions asynchronously. The task dependence ensures that the storage is allocated and initialized on the device before it is accessed." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_async_target.2.c" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The Fortran example below is similar to the C version above. Instead of pointers, though, it uses the convenience of Fortran allocatable arrays on the device. In order to preserve the arrays allocated on the device across multiple `target` regions, a `target` ~ `data` region is used in this case." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " If there is no shape specified for an allocatable array in a `map` clause, only the array descriptor (also called a dope vector) is mapped. That is, device space is created for the descriptor, and it is initially populated with host values. In this case, the _v1_ and _v2_ arrays will be in a non-associated state on the device. When space for _v1_ and _v2_ is allocated on the device in the first `target` region the addresses to the space will be included in their descriptors." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " At the end of the first `target` region, the arrays _v1_ and _v2_ are preserved on the device for access in the second `target` region. At the end of the second `target` region, the data in array _p_ is copied back, the arrays _v1_ and _v2_ are not." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " A `depend` clause is used in the `task` directive to provide a wait at the beginning of the second `target` region, to insure that there is no race condition with _v1_ and _v2_ in the two tasks. It would be noncompliant to use _v1_ and/or _v2_ in lieu of _N_ in the `depend` clauses, because the use of non-allocated allocatable arrays as list items in a `depend` clause would lead to unspecified behavior. " + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " noteheader{--} This example is not strictly compliant with the OpenMP 4.5 specification since the allocation status of allocatable arrays _v1_ and _v2_ is changed inside the `target` region, which is not allowed. (See the restrictions for the `map` clause in the _Data-mapping Attribute Rules and Clauses_ section of the specification.) However, the intention is to relax the restrictions on mapping of allocatable variables in the next release of the specification so that the example will be compliant." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_async_target.2.f90" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end---" + ] + } +], +"metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } +}, +"nbformat": 4, +"nbformat_minor": 2 +} diff --git a/notebook/Examples_atomic.ipynb b/notebook/Examples_atomic.ipynb new file mode 100644 index 0000000..7d9311d --- /dev/null +++ b/notebook/Examples_atomic.ipynb @@ -0,0 +1,121 @@ +{ + "cells": [ +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### The `atomic` Construct" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example avoids race conditions (simultaneous updates of an element of _x_ by multiple threads) by using the `atomic` construct ." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The advantage of using the `atomic` construct in this example is that it allows updates of two different elements of _x_ to occur in parallel. If a `critical` construct were used instead, then all updates to elements of _x_ would be executed serially (though not in any guaranteed order)." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Note that the `atomic` directive applies only to the statement immediately following it. As a result, elements of _y_ are not updated atomically in this example." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_atomic.1.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_atomic.1.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example illustrates the `read` and `write` clauses for the `atomic` directive. These clauses ensure that the given variable is read or written, respectively, as a whole. Otherwise, some other thread might read or write part of the variable while the current thread was reading or writing another part of the variable. Note that most hardware provides atomic reads and writes for some set of properly aligned variables of specific sizes, but not necessarily for all the variable types supported by the OpenMP API." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_atomic.2.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_atomic.2.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example illustrates the `capture` clause for the `atomic` directive. In this case the value of a variable is captured, and then the variable is incremented. These operations occur atomically. This particular example could be implemented using the fetch-and-add instruction available on many kinds of hardware. The example also shows a way to implement a spin lock using the `capture` and `read` clauses." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_atomic.3.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_atomic.3.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end---" + ] + } +], +"metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } +}, +"nbformat": 4, +"nbformat_minor": 2 +} diff --git a/notebook/Examples_atomic_restrict.ipynb b/notebook/Examples_atomic_restrict.ipynb new file mode 100644 index 0000000..2e9f100 --- /dev/null +++ b/notebook/Examples_atomic_restrict.ipynb @@ -0,0 +1,105 @@ +{ + "cells": [ +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Restrictions on the `atomic` Construct" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following non-conforming examples illustrate the restrictions on the `atomic` construct. " + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_atomic_restrict.1.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_atomic_restrict.1.f" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_atomic_restrict.2.c" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " fortranspecificstart The following example is non-conforming because `I` and `R` reference the same location but have different types." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_atomic_restrict.2.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Although the following example might work on some implementations, this is also non-conforming:" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_atomic_restrict.3.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " fortranspecificend" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end---" + ] + } +], +"metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } +}, +"nbformat": 4, +"nbformat_minor": 2 +} diff --git a/notebook/Examples_barrier_regions.ipynb b/notebook/Examples_barrier_regions.ipynb new file mode 100644 index 0000000..f0979f3 --- /dev/null +++ b/notebook/Examples_barrier_regions.ipynb @@ -0,0 +1,71 @@ +{ + "cells": [ +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Binding of `barrier` Regions" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The binding rules call for a `barrier` region to bind to the closest enclosing `parallel` region. " + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the following example, the call from the main program to _sub2_ is conforming because the `barrier` region (in _sub3_ ) binds to the `parallel` region in _sub2_ . The call from the main program to _sub1_ is conforming because the `barrier` region binds to the `parallel` region in subroutine _sub2_ ." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The call from the main program to _sub3_ is conforming because the `barrier` region binds to the implicit inactive `parallel` region enclosing the sequential part. Also note that the `barrier` region in _sub3_ when called from _sub2_ only synchronizes the team of threads in the enclosing `parallel` region and not all the threads created in _sub1_ ." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_barrier_regions.1.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_barrier_regions.1.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end---" + ] + } +], +"metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } +}, +"nbformat": 4, +"nbformat_minor": 2 +} diff --git a/notebook/Examples_cancellation.ipynb b/notebook/Examples_cancellation.ipynb new file mode 100644 index 0000000..48fce7d --- /dev/null +++ b/notebook/Examples_cancellation.ipynb @@ -0,0 +1,96 @@ +{ + "cells": [ +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Cancellation Constructs" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows how the `cancel` directive can be used to terminate an OpenMP region. Although the `cancel` construct terminates the OpenMP worksharing region, programmers must still track the exception through the pointer ex and issue a cancellation for the `parallel` region if an exception has been raised. The master thread checks the exception pointer to make sure that the exception is properly handled in the sequential part. If cancellation of the `parallel` region has been requested, some threads might have executed `phase_1()` . However, it is guaranteed that none of the threads executed `phase_2()` ." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_cancellation.1.cpp" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example illustrates the use of the `cancel` construct in error handling. If there is an error condition from the `allocate` statement, the cancellation is activated. The encountering thread sets the shared variable `err` and other threads of the binding thread set proceed to the end of the worksharing construct after the cancellation has been activated. " + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_cancellation.1.f90" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows how to cancel a parallel search on a binary tree as soon as the search value has been detected. The code creates a task to descend into the child nodes of the current tree node. If the search value has been found, the code remembers the tree node with the found value through an `atomic` write to the result variable and then cancels execution of all search tasks. The function `search_tree_parallel` groups all search tasks into a single task group to control the effect of the `cancel taskgroup` directive. The _level_ argument is used to create undeferred tasks after the first ten levels of the tree." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_cancellation.2.c" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following is the equivalent parallel search example in Fortran." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_cancellation.2.f90" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end---" + ] + } +], +"metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } +}, +"nbformat": 4, +"nbformat_minor": 2 +} diff --git a/notebook/Examples_carrays_fpriv.ipynb b/notebook/Examples_carrays_fpriv.ipynb new file mode 100644 index 0000000..f2687fa --- /dev/null +++ b/notebook/Examples_carrays_fpriv.ipynb @@ -0,0 +1,124 @@ +{ + "cells": [ +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### C/C++ Arrays in a `firstprivate` Clause" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ccppspecificstart" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example illustrates the size and value of list items of array or pointer type in a `firstprivate` clause . The size of new list items is based on the type of the corresponding original list item, as determined by the base language." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In this example:" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* The type of `A` is array of two arrays of two ints." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* The type of `B` is adjusted to pointer to array of `n` ints, because it is a function parameter." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* The type of `C` is adjusted to pointer to int, because it is a function parameter." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* The type of `D` is array of two arrays of two ints." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* The type of `E` is array of `n` arrays of `n` ints. " + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Note that `B` and `E` involve variable length array types." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The new items of array type are initialized as if each integer element of the original array is assigned to the corresponding element of the new array. Those of pointer type are initialized as if by assignment from the original \n", +"* to the new item." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_carrays_fpriv.1.c" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ccppspecificend" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end---" + ] + } +], +"metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } +}, +"nbformat": 4, +"nbformat_minor": 2 +} diff --git a/notebook/Examples_collapse.ipynb b/notebook/Examples_collapse.ipynb new file mode 100644 index 0000000..7d2dce0 --- /dev/null +++ b/notebook/Examples_collapse.ipynb @@ -0,0 +1,149 @@ +{ + "cells": [ +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### The `collapse` Clause" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the following example, the `k` and `j` loops are associated with the loop construct. So the iterations of the `k` and `j` loops are collapsed into one loop with a larger iteration space, and that loop is then divided among the threads in the current team. Since the `i` loop is not associated with the loop construct, it is not collapsed, and the `i` loop is executed sequentially in its entirety in every iteration of the collapsed `k` and `j` loop. " + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The variable `j` can be omitted from the `private` clause when the `collapse` clause is used since it is implicitly private. However, if the `collapse` clause is omitted then `j` will be shared if it is omitted from the `private` clause. In either case, `k` is implicitly private and could be omitted from the `private` clause." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_collapse.1.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_collapse.1.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the next example, the `k` and `j` loops are associated with the loop construct. So the iterations of the `k` and `j` loops are collapsed into one loop with a larger iteration space, and that loop is then divided among the threads in the current team." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The sequential execution of the iterations in the `k` and `j` loops determines the order of the iterations in the collapsed iteration space. This implies that in the sequentially last iteration of the collapsed iteration space, `k` will have the value `2` and `j` will have the value `3` . Since `klast` and `jlast` are `lastprivate` , their values are assigned by the sequentially last iteration of the collapsed `k` and `j` loop. This example prints: `2 3` ." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_collapse.2.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_collapse.2.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The next example illustrates the interaction of the `collapse` and `ordered` clauses." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the example, the loop construct has both a `collapse` clause and an `ordered` clause. The `collapse` clause causes the iterations of the `k` and `j` loops to be collapsed into one loop with a larger iteration space, and that loop is divided among the threads in the current team. An `ordered` clause is added to the loop construct, because an ordered region binds to the loop region arising from the loop construct." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " According to Section 2.12.8 of the OpenMP 4.0 specification, a thread must not execute more than one ordered region that binds to the same loop region. So the `collapse` clause is required for the example to be conforming. With the `collapse` clause, the iterations of the `k` and `j` loops are collapsed into one loop, and therefore only one ordered region will bind to the collapsed `k` and `j` loop. Without the `collapse` clause, there would be two ordered regions that bind to each iteration of the `k` loop (one arising from the first iteration of the `j` loop, and the other arising from the second iteration of the `j` loop)." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The code prints" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " `0 1 1` `0 1 2` `0 2 1` `1 2 2` `1 3 1` `1 3 2` " + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_collapse.3.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_collapse.3.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end---" + ] + } +], +"metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } +}, +"nbformat": 4, +"nbformat_minor": 2 +} diff --git a/notebook/Examples_cond_comp.ipynb b/notebook/Examples_cond_comp.ipynb new file mode 100644 index 0000000..864f9fb --- /dev/null +++ b/notebook/Examples_cond_comp.ipynb @@ -0,0 +1,78 @@ +{ + "cells": [ +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Conditional Compilation" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ccppspecificstart The following example illustrates the use of conditional compilation using the OpenMP macro `_OPENMP` . With OpenMP compilation, the `_OPENMP` macro becomes defined." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_cond_comp.1.c" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ccppspecificend" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " fortranspecificstart The following example illustrates the use of the conditional compilation sentinel. With OpenMP compilation, the conditional compilation sentinel `!$` is recognized and treated as two spaces. In fixed form source, statements guarded by the sentinel must start after column 6." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_cond_comp.1.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " fortranspecificend" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end---" + ] + } +], +"metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } +}, +"nbformat": 4, +"nbformat_minor": 2 +} diff --git a/notebook/Examples_copyin.ipynb b/notebook/Examples_copyin.ipynb new file mode 100644 index 0000000..7ce6dfb --- /dev/null +++ b/notebook/Examples_copyin.ipynb @@ -0,0 +1,57 @@ +{ + "cells": [ +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### The `copyin` Clause" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `copyin` clause is used to initialize threadprivate data upon entry to a `parallel` region. The value of the threadprivate variable in the master thread is copied to the threadprivate variable of each other team member." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_copyin.1.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_copyin.1.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end---" + ] + } +], +"metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } +}, +"nbformat": 4, +"nbformat_minor": 2 +} diff --git a/notebook/Examples_copyprivate.ipynb b/notebook/Examples_copyprivate.ipynb new file mode 100644 index 0000000..e887184 --- /dev/null +++ b/notebook/Examples_copyprivate.ipynb @@ -0,0 +1,135 @@ +{ + "cells": [ +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### The `copyprivate` Clause" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `copyprivate` clause can be used to broadcast values acquired by a single thread directly to all instances of the private variables in the other threads. In this example, if the routine is called from the sequential part, its behavior is not affected by the presence of the directives. If it is called from a `parallel` region, then the actual arguments with which `a` and `b` are associated must be private. " + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The thread that executes the structured block associated with the `single` construct broadcasts the values of the private variables `a` , `b` , `x` , and `y` from its implicit task's data environment to the data environments of the other implicit tasks in the thread team. The broadcast completes before any of the threads have left the barrier at the end of the construct." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_copyprivate.1.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_copyprivate.1.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In this example, assume that the input must be performed by the master thread. Since the `master` construct does not support the `copyprivate` clause, it cannot broadcast the input value that is read. However, `copyprivate` is used to broadcast an address where the input value is stored." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_copyprivate.2.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_copyprivate.2.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Suppose that the number of lock variables required within a `parallel` region cannot easily be determined prior to entering it. The `copyprivate` clause can be used to provide access to shared lock variables that are allocated within that `parallel` region." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_copyprivate.3.c" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " fortranspecificstartfnexample{copyprivate}{3}" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Note that the effect of the `copyprivate` clause on a variable with the `allocatable` attribute is different than on a variable with the `pointer` attribute. The value of `A` is copied (as if by intrinsic assignment) and the pointer `B` is copied (as if by pointer assignment) to the corresponding list items in the other implicit tasks belonging to the `parallel` region. " + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_copyprivate.4.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " fortranspecificend" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end---" + ] + } +], +"metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } +}, +"nbformat": 4, +"nbformat_minor": 2 +} diff --git a/notebook/Examples_cpp_reference.ipynb b/notebook/Examples_cpp_reference.ipynb new file mode 100644 index 0000000..dfffba8 --- /dev/null +++ b/notebook/Examples_cpp_reference.ipynb @@ -0,0 +1,66 @@ +{ + "cells": [ +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### C++ Reference in Data-Sharing Clauses" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_cppspecificstart" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " C++ reference types are allowed in data-sharing attribute clauses as of OpenMP 4.5, except for the `threadprivate` , `copyin` and `copyprivate` clauses. (See the Data-Sharing Attribute Clauses Section of the 4.5 OpenMP specification.) When a variable with C++ reference type is privatized, the object the reference refers to is privatized in addition to the reference itself. The following example shows the use of reference types in data-sharing clauses in the usual way. Additionally it shows how the data-sharing of formal arguments with a C++ reference type on an orphaned task generating construct is determined implicitly. (See the Data-sharing Attribute Rules for Variables Referenced in a Construct Section of the 4.5 OpenMP specification.)" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_cppnexamplecpp_reference1" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_cppspecificend" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end---" + ] + } +], +"metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } +}, +"nbformat": 4, +"nbformat_minor": 2 +} diff --git a/notebook/Examples_critical.ipynb b/notebook/Examples_critical.ipynb new file mode 100644 index 0000000..9b3cb3f --- /dev/null +++ b/notebook/Examples_critical.ipynb @@ -0,0 +1,82 @@ +{ + "cells": [ +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### The `critical` Construct" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example includes several `critical` constructs. The example illustrates a queuing model in which a task is dequeued and worked on. To guard against multiple threads dequeuing the same task, the dequeuing operation must be in a `critical` region. Because the two queues in this example are independent, they are protected by `critical` constructs with different names, _xaxis_ and _yaxis_ ." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_critical.1.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_critical.1.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example extends the previous example by adding the `hint` clause to the `critical` constructs." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_critical.2.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_critical.2.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end---" + ] + } +], +"metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } +}, +"nbformat": 4, +"nbformat_minor": 2 +} diff --git a/notebook/Examples_declare_target.ipynb b/notebook/Examples_declare_target.ipynb new file mode 100644 index 0000000..99625a4 --- /dev/null +++ b/notebook/Examples_declare_target.ipynb @@ -0,0 +1,326 @@ +{ + "cells": [ +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### `declare` `target` Construct" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### `declare` `target` and `end` `declare` `target` for a Function" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows how the `declare` `target` directive is used to indicate that the corresponding call inside a `target` region is to a `fib` function that can execute on the default target device." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " A version of the function is also available on the host device. When the `if` clause conditional expression on the `target` construct evaluates to _false_ , the `target` region (thus `fib` ) will execute on the host device." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " For C/C++ codes the declaration of the function `fib` appears between the `declare` `target` and `end` `declare` `target` directives." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_declare_target.1.c" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The Fortran `fib` subroutine contains a `declare` `target` declaration to indicate to the compiler to create an device executable version of the procedure. The subroutine name has not been included on the `declare` `target` directive and is, therefore, implicitly assumed." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The program uses the `module_fib` module, which presents an explicit interface to the compiler with the `declare` `target` declarations for processing the `fib` call." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_declare_target.1.f90" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The next Fortran example shows the use of an external subroutine. Without an explicit interface (through module use or an interface block) the `declare` `target` declarations within a external subroutine are unknown to the main program unit; therefore, a `declare` `target` must be provided within the program scope for the compiler to determine that a target binary should be available." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_declare_target.2.f90" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### `declare` `target` Construct for Class Type" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_cppspecificstart" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows how the `declare` `target` and `end` `declare` `target` directives are used to enclose the declaration of a variable _varY_ with a class type `typeY` . The member function `typeY::foo()` cannot be accessed on a target device because its declaration did not appear between `declare` `target` and `end` `declare` `target` directives." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_cppnexampledeclare_target2" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_cppspecificend" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### `declare` `target` and `end` `declare` `target` for Variables" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following examples show how the `declare` `target` and `end` `declare` `target` directives are used to indicate that global variables are mapped to the implicit device data environment of each target device." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the following example, the declarations of the variables _p_ , _v1_ , and _v2_ appear between `declare` `target` and `end` `declare` `target` directives indicating that the variables are mapped to the implicit device data environment of each target device. The `target` `update` directive is then used to manage the consistency of the variables _p_ , _v1_ , and _v2_ between the data environment of the encountering host device task and the implicit device data environment of the default target device." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_declare_target.3.c" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The Fortran version of the above C code uses a different syntax. Fortran modules use a list syntax on the `declare` `target` directive to declare mapped variables." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_declare_target.3.f90" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example also indicates that the function `Pfun()` is available on the target device, as well as the variable _Q_ , which is mapped to the implicit device data environment of each target device. The `target` `update` directive is then used to manage the consistency of the variable _Q_ between the data environment of the encountering host device task and the implicit device data environment of the default target device." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the following example, the function and variable declarations appear between the `declare` `target` and `end` `declare` `target` directives." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_declare_target.4.c" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The Fortran version of the above C code uses a different syntax. In Fortran modules a list syntax on the `declare` `target` directive is used to declare mapped variables and procedures. The _N_ and _Q_ variables are declared as a comma separated list. When the `declare` `target` directive is used to declare just the procedure, the procedure name need not be listed -- it is implicitly assumed, as illustrated in the `Pfun()` function." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_declare_target.4.f90" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### `declare` `target` and `end` `declare` `target` with `declare` `simd` " + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows how the `declare` `target` and `end` `declare` `target` directives are used to indicate that a function is available on a target device. The `declare` `simd` directive indicates that there is a SIMD version of the function `P()` that is available on the target device as well as one that is available on the host device." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_declare_target.5.c" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The Fortran version of the above C code uses a different syntax. Fortran modules use a list syntax of the `declare` `target` declaration for the mapping. Here the _N_ and _Q_ variables are declared in the list form as a comma separated list. The function declaration does not use a list and implicitly assumes the function name. In this Fortran example row and column indices are reversed relative to the C/C++ example, as is usual for codes optimized for memory access." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_declare_target.5.f90" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### `declare` ~ `target` Directive with `link` Clause" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the OpenMP 4.5 standard the `declare` ~ `target` directive was extended to allow static data to be mapped, emph{when needed}, through a `link` clause." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Data storage for items listed in the `link` clause becomes available on the device when it is mapped implicitly or explicitly in a `map` clause, and it persists for the scope of the mapping (as specified by a `target` construct, a `target` ~ `data` construct, or `target` ~ `enter/exit` ~ `data` constructs)." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Tip: When all the global data items will not fit on a device and are not needed simultaneously, use the `link` clause and map the data only when it is needed." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following C and Fortran examples show two sets of data (single precision and double precision) that are global on the host for the entire execution on the host; but are only used globally on the device for part of the program execution. The single precision data are allocated and persist only for the first `target` region. Similarly, the double precision data are in scope on the device only for the second `target` region." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_declare_target.6.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_declare_target.6.f90" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end---" + ] + } +], +"metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } +}, +"nbformat": 4, +"nbformat_minor": 2 +} diff --git a/notebook/Examples_default_none.ipynb b/notebook/Examples_default_none.ipynb new file mode 100644 index 0000000..e4dd1c0 --- /dev/null +++ b/notebook/Examples_default_none.ipynb @@ -0,0 +1,71 @@ +{ + "cells": [ +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### The `default(none)` Clause" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example distinguishes the variables that are affected by the `default(none)` clause from those that are not. " + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ccppspecificstart Beginning with OpenMP 4.0, variables with `const` -qualified type and no mutable member are no longer predetermined shared. Thus, these variables (variable _c_ in the example) need to be explicitly listed in data-sharing attribute clauses when the `default(none)` clause is specified." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_default_none.1.c" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ccppspecificend" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_default_none.1.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end---" + ] + } +], +"metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } +}, +"nbformat": 4, +"nbformat_minor": 2 +} diff --git a/notebook/Examples_device.ipynb b/notebook/Examples_device.ipynb new file mode 100644 index 0000000..c7e7123 --- /dev/null +++ b/notebook/Examples_device.ipynb @@ -0,0 +1,172 @@ +{ + "cells": [ +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Device Routines" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### `omp_is_initial_device` Routine" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows how the `omp_is_initial_device` runtime library routine can be used to query if a code is executing on the initial host device or on a target device. The example then sets the number of threads in the `parallel` region based on where the code is executing." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_device.1.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_device.1.f90" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### `omp_get_num_devices` Routine" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows how the `omp_get_num_devices` runtime library routine can be used to determine the number of devices." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_device.2.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_device.2.f90" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "subsection{ `omp_set_default_device` and " + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " `omp_get_default_device` Routines}" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows how the `omp_set_default_device` and `omp_get_default_device` runtime library routines can be used to set the default device and determine the default device respectively." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_device.3.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_device.3.f90" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### Target Memory and Device Pointers Routines" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows how to create space on a device, transfer data to and from that space, and free the space, using API calls. The API calls directly execute allocation, copy and free operations on the device, without invoking any mapping through a `target` directive. The `omp_target_alloc` routine allocates space and returns a device pointer for referencing the space in the `omp_target_memcpy` API routine on the host. The `omp_target_free` routine frees the space on the device." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The example also illustrates how to access that space in a `target` region by exposing the device pointer in an `is_device_ptr` clause." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The example creates an array of cosine values on the default device, to be used on the host device. The function fails if a default device is not available." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_device.4.c" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end---" + ] + } +], +"metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } +}, +"nbformat": 4, +"nbformat_minor": 2 +} diff --git a/notebook/Examples_doacross.ipynb b/notebook/Examples_doacross.ipynb new file mode 100644 index 0000000..f21e198 --- /dev/null +++ b/notebook/Examples_doacross.ipynb @@ -0,0 +1,139 @@ +{ + "cells": [ +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Doacross Loop Nest" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " An `ordered` clause can be used on a loop construct with an integer parameter argument to define the number of associated loops within a _doacross loop nest_ where cross-iteration dependences exist. A `depend` clause on an `ordered` construct within an ordered loop describes the dependences of the _doacross_ loops. " + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the code below, the `depend(sink:i-1)` clause defines an _i-1_ to _i_ cross-iteration dependence that specifies a wait point for the completion of computation from iteration _i-1_ before proceeding to the subsequent statements. The `depend(source)` clause indicates the completion of computation from the current iteration ( _i_ ) to satisfy the cross-iteration dependence that arises from the iteration. For this example the same sequential ordering could have been achieved with an `ordered` clause without a parameter, on the loop directive, and a single `ordered` directive without the `depend` clause specified for the statement executing the _bar_ function." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_doacross.1.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_doacross.1.f90" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following code is similar to the previous example but with _doacross loop nest_ extended to two nested loops, _i_ and _j_ , as specified by the `ordered(2)` clause on the loop directive. In the C/C++ code, the _i_ and _j_ loops are the first and second associated loops, respectively, whereas in the Fortran code, the _j_ and _i_ loops are the first and second associated loops, respectively. The `depend(sink:i-1,j)` and `depend(sink:i,j-1)` clauses in the C/C++ code define cross-iteration dependences in two dimensions from iterations ( _i-1, j_ ) and ( _i, j-1_ ) to iteration ( _i, j_ ). Likewise, the `depend(sink:j-1,i)` and `depend(sink:j,i-1)` clauses in the Fortran code define cross-iteration dependences from iterations ( _j-1, i_ ) and ( _j, i-1_ ) to iteration ( _j, i_ )." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_doacross.2.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_doacross.2.f90" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows the incorrect use of the `ordered` directive with a `depend` clause. There are two issues with the code. The first issue is a missing `ordered` ~ `depend(source)` directive, which could cause a deadlock. The second issue is the `depend(sink:i+1,j)` and `depend(sink:i,j+1)` clauses define dependences on lexicographically later source iterations ( _i+1, j_ ) and ( _i, j+1_ ), which could cause a deadlock as well since they may not start to execute until the current iteration completes." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_doacross.3.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_doacross.3.f90" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example illustrates the use of the `collapse` clause for a _doacross loop nest_ . The _i_ and _j_ loops are the associated loops for the collapsed loop as well as for the _doacross loop nest_ . The example also shows a compliant usage of the dependence source directive placed before the corresponding sink directive. Checking the completion of computation from previous iterations at the sink point can occur after the source statement." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_doacross.4.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_doacross.4.f90" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end---" + ] + } +], +"metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } +}, +"nbformat": 4, +"nbformat_minor": 2 +} diff --git a/notebook/Examples_flush_nolist.ipynb b/notebook/Examples_flush_nolist.ipynb new file mode 100644 index 0000000..bb6132a --- /dev/null +++ b/notebook/Examples_flush_nolist.ipynb @@ -0,0 +1,57 @@ +{ + "cells": [ +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### The `flush` Construct without a List" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example distinguishes the shared variables affected by a `flush` construct with no list from the shared objects that are not affected:" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_flush_nolist.1.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_flush_nolist.1.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end---" + ] + } +], +"metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } +}, +"nbformat": 4, +"nbformat_minor": 2 +} diff --git a/notebook/Examples_fort_do.ipynb b/notebook/Examples_fort_do.ipynb new file mode 100644 index 0000000..7369207 --- /dev/null +++ b/notebook/Examples_fort_do.ipynb @@ -0,0 +1,78 @@ +{ + "cells": [ +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Fortran Restrictions on the `do` Construct" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " fortranspecificstart" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " If an `end do` directive follows a _do-construct_ in which several `DO` statements share a `DO` termination statement, then a `do` directive can only be specified for the outermost of these `DO` statements. The following example contains correct usages of loop constructs:" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_fort_do.1.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example is non-conforming because the matching `do` directive for the `end do` does not precede the outermost loop:" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_fort_do.2.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " fortranspecificend" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end---" + ] + } +], +"metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } +}, +"nbformat": 4, +"nbformat_minor": 2 +} diff --git a/notebook/Examples_fort_loopvar.ipynb b/notebook/Examples_fort_loopvar.ipynb new file mode 100644 index 0000000..c6822a8 --- /dev/null +++ b/notebook/Examples_fort_loopvar.ipynb @@ -0,0 +1,78 @@ +{ + "cells": [ +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Fortran Private Loop Iteration Variables" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " fortranspecificstart" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In general loop iteration variables will be private, when used in the _do-loop_ of a `do` and `parallel do` construct or in sequential loops in a `parallel` construct (see Section 2.7.1 and Section 2.14.1 of the OpenMP 4.0 specification). In the following example of a sequential loop in a `parallel` construct the loop iteration variable _I_ will be private." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_ffreenexamplefort_loopvar1" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In exceptional cases, loop iteration variables can be made shared, as in the following example:" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_ffreenexamplefort_loopvar2" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Note however that the use of shared loop iteration variables can easily lead to race conditions. fortranspecificend" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end---" + ] + } +], +"metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } +}, +"nbformat": 4, +"nbformat_minor": 2 +} diff --git a/notebook/Examples_fort_race.ipynb b/notebook/Examples_fort_race.ipynb new file mode 100644 index 0000000..1fa34d3 --- /dev/null +++ b/notebook/Examples_fort_race.ipynb @@ -0,0 +1,62 @@ +{ + "cells": [ +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Race Conditions Caused by Implied Copies of Shared Variables in Fortran" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " fortranspecificstart" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example contains a race condition, because the shared variable, which is an array section, is passed as an actual argument to a routine that has an assumed-size array as its dummy argument. The subroutine call passing an array section argument may cause the compiler to copy the argument into a temporary location prior to the call and copy from the temporary location into the original variable when the subroutine returns. This copying would cause races in the `parallel` region." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_ffreenexamplefort_race1" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " fortranspecificend" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end---" + ] + } +], +"metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } +}, +"nbformat": 4, +"nbformat_minor": 2 +} diff --git a/notebook/Examples_fort_sa_private.ipynb b/notebook/Examples_fort_sa_private.ipynb new file mode 100644 index 0000000..590ac9b --- /dev/null +++ b/notebook/Examples_fort_sa_private.ipynb @@ -0,0 +1,106 @@ +{ + "cells": [ +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Fortran Restrictions on Storage Association with the `private` Clause" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " fortranspecificstart" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following non-conforming examples illustrate the implications of the `private` clause rules with regard to storage association. " + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_fort_sa_private.1.f" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_fort_sa_private.2.f" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_fort_sa_private.3.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +" blue line floater at top of this page for 'Fortran, cont.' [t!] linewitharrows{-1}{dashed}{Fortran (cont.)}{8em} " + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_fort_sa_private.4.f" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_fort_sa_private.5.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " fortranspecificend" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end---" + ] + } +], +"metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } +}, +"nbformat": 4, +"nbformat_minor": 2 +} diff --git a/notebook/Examples_fort_sp_common.ipynb b/notebook/Examples_fort_sp_common.ipynb new file mode 100644 index 0000000..fdd2d55 --- /dev/null +++ b/notebook/Examples_fort_sp_common.ipynb @@ -0,0 +1,141 @@ +{ + "cells": [ +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Fortran Restrictions on `shared` and `private` Clauses with Common Blocks" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " fortranspecificstart" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " When a named common block is specified in a `private` , `firstprivate` , or `lastprivate` clause of a construct, none of its members may be declared in another data-sharing attribute clause on that construct. The following examples illustrate this point. " + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example is conforming:" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_fort_sp_common.1.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example is also conforming:" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_fort_sp_common.2.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +" blue line floater at top of this page for 'Fortran, cont.' [t!] linewitharrows{-1}{dashed}{Fortran (cont.)}{8em} " + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example is conforming:" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_fort_sp_common.3.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example is non-conforming because `x` is a constituent element of `c` :" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_fort_sp_common.4.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example is non-conforming because a common block may not be declared both shared and private:" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_fort_sp_common.5.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " fortranspecificend" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end---" + ] + } +], +"metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } +}, +"nbformat": 4, +"nbformat_minor": 2 +} diff --git a/notebook/Examples_fpriv_sections.ipynb b/notebook/Examples_fpriv_sections.ipynb new file mode 100644 index 0000000..76d29de --- /dev/null +++ b/notebook/Examples_fpriv_sections.ipynb @@ -0,0 +1,57 @@ +{ + "cells": [ +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### The `firstprivate` Clause and the `sections` Construct" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the following example of the `sections` construct the `firstprivate` clause is used to initialize the private copy of `section_count` of each thread. The problem is that the `section` constructs modify `section_count` , which breaks the independence of the `section` constructs. When different threads execute each section, both sections will print the value 1. When the same thread executes the two sections, one section will print the value 1 and the other will print the value 2. Since the order of execution of the two sections in this case is unspecified, it is unspecified which section prints which value. " + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_fpriv_sections.1.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_fpriv_sections.1.f90" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end---" + ] + } +], +"metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } +}, +"nbformat": 4, +"nbformat_minor": 2 +} diff --git a/notebook/Examples_get_nthrs.ipynb b/notebook/Examples_get_nthrs.ipynb new file mode 100644 index 0000000..73561e5 --- /dev/null +++ b/notebook/Examples_get_nthrs.ipynb @@ -0,0 +1,82 @@ +{ + "cells": [ +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### The `omp_get_num_threads` Routine" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the following example, the `omp_get_num_threads` call returns 1 in the sequential part of the code, so `np` will always be equal to 1. To determine the number of threads that will be deployed for the `parallel` region, the call should be inside the `parallel` region." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_get_nthrs.1.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_get_nthrs.1.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows how to rewrite this program without including a query for the number of threads:" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_get_nthrs.2.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_get_nthrs.2.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end---" + ] + } +], +"metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } +}, +"nbformat": 4, +"nbformat_minor": 2 +} diff --git a/notebook/Examples_icv.ipynb b/notebook/Examples_icv.ipynb new file mode 100644 index 0000000..7027659 --- /dev/null +++ b/notebook/Examples_icv.ipynb @@ -0,0 +1,113 @@ +{ + "cells": [ +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Internal Control Variables (ICVs)" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " According to Section 2.3 of the OpenMP 4.0 specification, an OpenMP implementation must act as if there are ICVs that control the behavior of the program. This example illustrates two ICVs, _nthreads-var_ and _max-active-levels-var_ . The _nthreads-var_ ICV controls the number of threads requested for encountered parallel regions; there is one copy of this ICV per task. The _max-active-levels-var_ ICV controls the maximum number of nested active parallel regions; there is one copy of this ICV for the whole program." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the following example, the _nest-var_ , _max-active-levels-var_ , _dyn-var_ , and _nthreads-var_ ICVs are modified through calls to the runtime library routines `omp_set_nested` , `omp_set_max_active_levels` , ` omp_set_dynamic` , and `omp_set_num_threads` respectively. These ICVs affect the operation of `parallel` regions. Each implicit task generated by a `parallel` region has its own copy of the _nest-var, dyn-var_ , and _nthreads-var_ ICVs." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the following example, the new value of _nthreads-var_ applies only to the implicit tasks that execute the call to `omp_set_num_threads` . There is one copy of the _max-active-levels-var_ ICV for the whole program and its value is the same for all tasks. This example assumes that nested parallelism is supported." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The outer `parallel` region creates a team of two threads; each of the threads will execute one of the two implicit tasks generated by the outer `parallel` region." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Each implicit task generated by the outer `parallel` region calls `omp_set_num_threads(3)` , assigning the value 3 to its respective copy of _nthreads-var_ . Then each implicit task encounters an inner `parallel` region that creates a team of three threads; each of the threads will execute one of the three implicit tasks generated by that inner `parallel` region." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Since the outer `parallel` region is executed by 2 threads, and the inner by 3, there will be a total of 6 implicit tasks generated by the two inner `parallel` regions." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Each implicit task generated by an inner `parallel` region will execute the call to `omp_set_num_threads(4)` , assigning the value 4 to its respective copy of _nthreads-var_ ." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The print statement in the outer `parallel` region is executed by only one of the threads in the team. So it will be executed only once." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The print statement in an inner `parallel` region is also executed by only one of the threads in the team. Since we have a total of two inner `parallel` regions, the print statement will be executed twice -- once per inner `parallel` region." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_icv.1.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_icv.1.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end---" + ] + } +], +"metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } +}, +"nbformat": 4, +"nbformat_minor": 2 +} diff --git a/notebook/Examples_init_lock.ipynb b/notebook/Examples_init_lock.ipynb new file mode 100644 index 0000000..4b5fca7 --- /dev/null +++ b/notebook/Examples_init_lock.ipynb @@ -0,0 +1,57 @@ +{ + "cells": [ +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### The `omp_init_lock` Routine" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example demonstrates how to initialize an array of locks in a `parallel` region by using `omp_init_lock` ." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_init_lock.1.cpp" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_init_lock.1.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end---" + ] + } +], +"metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } +}, +"nbformat": 4, +"nbformat_minor": 2 +} diff --git a/notebook/Examples_init_lock_with_hint.ipynb b/notebook/Examples_init_lock_with_hint.ipynb new file mode 100644 index 0000000..e0a1c75 --- /dev/null +++ b/notebook/Examples_init_lock_with_hint.ipynb @@ -0,0 +1,58 @@ +{ + "cells": [ +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +" #### The `omp_init_lock_with_hint` Routine" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example demonstrates how to initialize an array of locks in a `parallel` region by using `omp_init_lock_with_hint` . Note, hints are combined with an `|` or `+` operator in C/C++ and a `+` operator in Fortran." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_init_lock_with_hint.1.cpp" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_init_lock_with_hint.1.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end---" + ] + } +], +"metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } +}, +"nbformat": 4, +"nbformat_minor": 2 +} diff --git a/notebook/Examples_lastprivate.ipynb b/notebook/Examples_lastprivate.ipynb new file mode 100644 index 0000000..ef4da87 --- /dev/null +++ b/notebook/Examples_lastprivate.ipynb @@ -0,0 +1,57 @@ +{ + "cells": [ +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### The `lastprivate` Clause" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Correct execution sometimes depends on the value that the last iteration of a loop assigns to a variable. Such programs must list all such variables in a `lastprivate` clause so that the values of the variables are the same as when the loop is executed sequentially." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_lastprivate.1.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_lastprivate.1.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end---" + ] + } +], +"metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } +}, +"nbformat": 4, +"nbformat_minor": 2 +} diff --git a/notebook/Examples_linear_in_loop.ipynb b/notebook/Examples_linear_in_loop.ipynb new file mode 100644 index 0000000..3b365d6 --- /dev/null +++ b/notebook/Examples_linear_in_loop.ipynb @@ -0,0 +1,57 @@ +{ + "cells": [ +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### `linear` Clause in Loop Constructs" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows the use of the `linear` clause in a loop construct to allow the proper parallelization of a loop that contains an induction variable ( _j_ ). At the end of the execution of the loop construct, the original variable _j_ is updated with the value _N/2_ from the last iteration of the loop." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_linear_in_loop.1.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_linear_in_loop.1.f90" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end---" + ] + } +], +"metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } +}, +"nbformat": 4, +"nbformat_minor": 2 +} diff --git a/notebook/Examples_lock_owner.ipynb b/notebook/Examples_lock_owner.ipynb new file mode 100644 index 0000000..b87883e --- /dev/null +++ b/notebook/Examples_lock_owner.ipynb @@ -0,0 +1,64 @@ +{ + "cells": [ +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### Ownership of Locks" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Ownership of locks has changed since OpenMP 2.5. In OpenMP 2.5, locks are owned by threads; so a lock released by the `omp_unset_lock` routine must be owned by the same thread executing the routine. Beginning with OpenMP 3.0, locks are owned by task regions; so a lock released by the `omp_unset_lock` routine in a task region must be owned by the same task region." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " This change in ownership requires extra care when using locks. The following program is conforming in OpenMP 2.5 because the thread that releases the lock `lck` in the parallel region is the same thread that acquired the lock in the sequential part of the program (master thread of parallel region and the initial thread are the same). However, it is not conforming beginning with OpenMP 3.0, because the task region that releases the lock `lck` is different from the task region that acquires the lock." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_lock_owner.1.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_lock_owner.1.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end---" + ] + } +], +"metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } +}, +"nbformat": 4, +"nbformat_minor": 2 +} diff --git a/notebook/Examples_locks.ipynb b/notebook/Examples_locks.ipynb new file mode 100644 index 0000000..ee7c5ff --- /dev/null +++ b/notebook/Examples_locks.ipynb @@ -0,0 +1,39 @@ +{ + "cells": [ +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Lock Routines" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " This section is about the use of lock routines for synchronization." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end---" + ] + } +], +"metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } +}, +"nbformat": 4, +"nbformat_minor": 2 +} diff --git a/notebook/Examples_master.ipynb b/notebook/Examples_master.ipynb new file mode 100644 index 0000000..2c0c141 --- /dev/null +++ b/notebook/Examples_master.ipynb @@ -0,0 +1,57 @@ +{ + "cells": [ +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### The `master` Construct" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example demonstrates the master construct . In the example, the master keeps track of how many iterations have been executed and prints out a progress report. The other threads skip the master region without waiting." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_master.1.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_master.1.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end---" + ] + } +], +"metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } +}, +"nbformat": 4, +"nbformat_minor": 2 +} diff --git a/notebook/Examples_mem_model.ipynb b/notebook/Examples_mem_model.ipynb new file mode 100644 index 0000000..cd03f90 --- /dev/null +++ b/notebook/Examples_mem_model.ipynb @@ -0,0 +1,114 @@ +{ + "cells": [ +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### The OpenMP Memory Model" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the following example, at Print 1, the value of _x_ could be either 2 or 5, depending on the timing of the threads, and the implementation of the assignment to _x_ . There are two reasons that the value at Print 1 might not be 5. First, Print 1 might be executed before the assignment to _x_ is executed. Second, even if Print 1 is executed after the assignment, the value 5 is not guaranteed to be seen by thread 1 because a flush may not have been executed by thread 0 since the assignment." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The barrier after Print 1 contains implicit flushes on all threads, as well as a thread synchronization, so the programmer is guaranteed that the value 5 will be printed by both Print 2 and Print 3." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_mem_model.1.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_mem_model.1.f90" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example demonstrates why synchronization is difficult to perform correctly through variables. The value of flag is undefined in both prints on thread 1 and the value of data is only well-defined in the second print." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_mem_model.2.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_mem_model.2.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The next example demonstrates why synchronization is difficult to perform correctly through variables. Because the _write_ (1)- _flush_ (1)- _flush_ (2)- _read_ (2) sequence cannot be guaranteed in the example, the statements on thread 0 and thread 1 may execute in either order." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_mem_model.3.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_mem_model.3.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end---" + ] + } +], +"metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } +}, +"nbformat": 4, +"nbformat_minor": 2 +} diff --git a/notebook/Examples_nestable_lock.ipynb b/notebook/Examples_nestable_lock.ipynb new file mode 100644 index 0000000..f78dc1d --- /dev/null +++ b/notebook/Examples_nestable_lock.ipynb @@ -0,0 +1,57 @@ +{ + "cells": [ +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### Nestable Lock Routines" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example demonstrates how a nestable lock can be used to synchronize updates both to a whole structure and to one of its members." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_nestable_lock.1.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_nestable_lock.1.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end---" + ] + } +], +"metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } +}, +"nbformat": 4, +"nbformat_minor": 2 +} diff --git a/notebook/Examples_nested_loop.ipynb b/notebook/Examples_nested_loop.ipynb new file mode 100644 index 0000000..28aeedb --- /dev/null +++ b/notebook/Examples_nested_loop.ipynb @@ -0,0 +1,82 @@ +{ + "cells": [ +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Nested Loop Constructs" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example of loop construct nesting is conforming because the inner and outer loop regions bind to different `parallel` regions:" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_nested_loop.1.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_nested_loop.1.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following variation of the preceding example is also conforming:" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_nested_loop.2.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_nested_loop.2.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end---" + ] + } +], +"metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } +}, +"nbformat": 4, +"nbformat_minor": 2 +} diff --git a/notebook/Examples_nesting_restrict.ipynb b/notebook/Examples_nesting_restrict.ipynb new file mode 100644 index 0000000..e2d2fd6 --- /dev/null +++ b/notebook/Examples_nesting_restrict.ipynb @@ -0,0 +1,189 @@ +{ + "cells": [ +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Restrictions on Nesting of Regions" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The examples in this section illustrate the region nesting rules. " + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example is non-conforming because the inner and outer loop regions are closely nested:" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_nesting_restrict.1.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_nesting_restrict.1.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following orphaned version of the preceding example is also non-conforming:" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_nesting_restrict.2.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_nesting_restrict.2.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example is non-conforming because the loop and `single` regions are closely nested:" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_nesting_restrict.3.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_nesting_restrict.3.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example is non-conforming because a `barrier` region cannot be closely nested inside a loop region:" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_nesting_restrict.4.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_nesting_restrict.4.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example is non-conforming because the `barrier` region cannot be closely nested inside the `critical` region. If this were permitted, it would result in deadlock due to the fact that only one thread at a time can enter the `critical` region:" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_nesting_restrict.5.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_nesting_restrict.5.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example is non-conforming because the `barrier` region cannot be closely nested inside the `single` region. If this were permitted, it would result in deadlock due to the fact that only one thread executes the `single` region:" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_nesting_restrict.6.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_nesting_restrict.6.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end---" + ] + } +], +"metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } +}, +"nbformat": 4, +"nbformat_minor": 2 +} diff --git a/notebook/Examples_nowait.ipynb b/notebook/Examples_nowait.ipynb new file mode 100644 index 0000000..cd42c69 --- /dev/null +++ b/notebook/Examples_nowait.ipynb @@ -0,0 +1,89 @@ +{ + "cells": [ +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### The `nowait` Clause" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " If there are multiple independent loops within a `parallel` region, you can use the `nowait` clause to avoid the implied barrier at the end of the loop construct, as follows:" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_nowait.1.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_nowait.1.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the following example, static scheduling distributes the same logical iteration numbers to the threads that execute the three loop regions. This allows the `nowait` clause to be used, even though there is a data dependence between the loops. The dependence is satisfied as long the same thread executes the same logical iteration numbers in each loop." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Note that the iteration count of the loops must be the same. The example satisfies this requirement, since the iteration space of the first two loops is from `0` to `n-1` (from `1` to `N` in the Fortran version), while the iteration space of the last loop is from `1` to `n` ( `2` to `N+1` in the Fortran version)." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_nowait.2.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_nowait.2.f90" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end---" + ] + } +], +"metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } +}, +"nbformat": 4, +"nbformat_minor": 2 +} diff --git a/notebook/Examples_nthrs_dynamic.ipynb b/notebook/Examples_nthrs_dynamic.ipynb new file mode 100644 index 0000000..2d63bf8 --- /dev/null +++ b/notebook/Examples_nthrs_dynamic.ipynb @@ -0,0 +1,96 @@ +{ + "cells": [ +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Interaction Between the `num_threads` Clause and `omp_set_dynamic` " + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example demonstrates the `num_threads` clause and the effect of the `omp_set_dynamic` routine on it." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The call to the `omp_set_dynamic` routine with argument `0` in C/C++, or `.FALSE.` in Fortran, disables the dynamic adjustment of the number of threads in OpenMP implementations that support it. In this case, 10 threads are provided. Note that in case of an error the OpenMP implementation is free to abort the program or to supply any number of threads available." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_nthrs_dynamic.1.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_nthrs_dynamic.1.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The call to the `omp_set_dynamic` routine with a non-zero argument in C/C++, or `.TRUE.` in Fortran, allows the OpenMP implementation to choose any number of threads between 1 and 10." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_nthrs_dynamic.2.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_nthrs_dynamic.2.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " It is good practice to set the _dyn-var_ ICV explicitly by calling the `omp_set_dynamic` routine, as its default setting is implementation defined." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end---" + ] + } +], +"metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } +}, +"nbformat": 4, +"nbformat_minor": 2 +} diff --git a/notebook/Examples_nthrs_nesting.ipynb b/notebook/Examples_nthrs_nesting.ipynb new file mode 100644 index 0000000..41e1015 --- /dev/null +++ b/notebook/Examples_nthrs_nesting.ipynb @@ -0,0 +1,57 @@ +{ + "cells": [ +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Controlling the Number of Threads on Multiple Nesting Levels" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following examples demonstrate how to use the `OMP_NUM_THREADS` environment variable to control the number of threads on multiple nesting levels:" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_nthrs_nesting.1.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_nthrs_nesting.1.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end---" + ] + } +], +"metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } +}, +"nbformat": 4, +"nbformat_minor": 2 +} diff --git a/notebook/Examples_ordered.ipynb b/notebook/Examples_ordered.ipynb new file mode 100644 index 0000000..bca663c --- /dev/null +++ b/notebook/Examples_ordered.ipynb @@ -0,0 +1,107 @@ +{ + "cells": [ +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### The `ordered` Clause and the `ordered` Construct" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Ordered constructs are useful for sequentially ordering the output from work that is done in parallel. The following program prints out the indices in sequential order:" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_ordered.1.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_ordered.1.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " It is possible to have multiple `ordered` constructs within a loop region with the `ordered` clause specified. The first example is non-conforming because all iterations execute two `ordered` regions. An iteration of a loop must not execute more than one `ordered` region:" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_ordered.2.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_ordered.2.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following is a conforming example with more than one `ordered` construct. Each iteration will execute only one `ordered` region:" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_ordered.3.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_ordered.3.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end---" + ] + } +], +"metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } +}, +"nbformat": 4, +"nbformat_minor": 2 +} diff --git a/notebook/Examples_parallel.ipynb b/notebook/Examples_parallel.ipynb new file mode 100644 index 0000000..cce0438 --- /dev/null +++ b/notebook/Examples_parallel.ipynb @@ -0,0 +1,57 @@ +{ + "cells": [ +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### The `parallel` Construct" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `parallel` construct can be used in coarse-grain parallel programs. In the following example, each thread in the `parallel` region decides what part of the global array _x_ to work on, based on the thread number:" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_parallel.1.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_parallel.1.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end---" + ] + } +], +"metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } +}, +"nbformat": 4, +"nbformat_minor": 2 +} diff --git a/notebook/Examples_ploop.ipynb b/notebook/Examples_ploop.ipynb new file mode 100644 index 0000000..284d5e4 --- /dev/null +++ b/notebook/Examples_ploop.ipynb @@ -0,0 +1,57 @@ +{ + "cells": [ +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### A Simple Parallel Loop" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example demonstrates how to parallelize a simple loop using the parallel loop construct. The loop iteration variable is private by default, so it is not necessary to specify it explicitly in a `private` clause." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_ploop.1.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_ploop.1.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end---" + ] + } +], +"metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } +}, +"nbformat": 4, +"nbformat_minor": 2 +} diff --git a/notebook/Examples_pra_iterator.ipynb b/notebook/Examples_pra_iterator.ipynb new file mode 100644 index 0000000..bbc714d --- /dev/null +++ b/notebook/Examples_pra_iterator.ipynb @@ -0,0 +1,66 @@ +{ + "cells": [ +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Parallel Random Access Iterator Loop" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_cppspecificstart" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows a parallel random access iterator loop." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_cppnexamplepra_iterator1" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_cppspecificend" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end---" + ] + } +], +"metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } +}, +"nbformat": 4, +"nbformat_minor": 2 +} diff --git a/notebook/Examples_private.ipynb b/notebook/Examples_private.ipynb new file mode 100644 index 0000000..d4e4249 --- /dev/null +++ b/notebook/Examples_private.ipynb @@ -0,0 +1,110 @@ +{ + "cells": [ +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### The `private` Clause" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the following example, the values of original list items _i_ and _j_ are retained on exit from the `parallel` region, while the private list items _i_ and _j_ are modified within the `parallel` construct. " + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_private.1.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_private.1.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the following example, all uses of the variable _a_ within the loop construct in the routine _f_ refer to a private list \n", +"* _a_ , while it is unspecified whether references to _a_ in the routine _g_ are to a private list \n", +"* or the original list item." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_private.2.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_private.2.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example demonstrates that a list \n", +"* that appears in a `private` clause in a `parallel` construct may also appear in a `private` clause in an enclosed worksharing construct, which results in an additional private copy." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_private.3.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_private.3.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end---" + ] + } +], +"metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } +}, +"nbformat": 4, +"nbformat_minor": 2 +} diff --git a/notebook/Examples_psections.ipynb b/notebook/Examples_psections.ipynb new file mode 100644 index 0000000..49eeed4 --- /dev/null +++ b/notebook/Examples_psections.ipynb @@ -0,0 +1,57 @@ +{ + "cells": [ +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### The `parallel` `sections` Construct" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the following example routines `XAXIS` , `YAXIS` , and `ZAXIS` can be executed concurrently. The first `section` directive is optional. Note that all `section` directives need to appear in the `parallel sections` construct." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_psections.1.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_psections.1.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end---" + ] + } +], +"metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } +}, +"nbformat": 4, +"nbformat_minor": 2 +} diff --git a/notebook/Examples_reduction.ipynb b/notebook/Examples_reduction.ipynb new file mode 100644 index 0000000..17cae6f --- /dev/null +++ b/notebook/Examples_reduction.ipynb @@ -0,0 +1,202 @@ +{ + "cells": [ +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### The `reduction` Clause" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example demonstrates the `reduction` clause ; note that some reductions can be expressed in the loop in several ways, as shown for the `max` and `min` reductions below:" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_reduction.1.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_reduction.1.f90" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " A common implementation of the preceding example is to treat it as if it had been written as follows:" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_reduction.2.c" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " fortranspecificstartffreenexample{reduction}{2}" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following program is non-conforming because the reduction is on the emph{intrinsic procedure name} `MAX` but that name has been redefined to be the variable named `MAX` ." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_ffreenexamplereduction3" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +" blue line floater at top of this page for 'Fortran, cont.' [t!] linewitharrows{-1}{dashed}{Fortran (cont.)}{8em} " + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following conforming program performs the reduction using the emph{intrinsic procedure name} `MAX` even though the intrinsic `MAX` has been renamed to `REN` ." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_ffreenexamplereduction4" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following conforming program performs the reduction using _intrinsic procedure name_ `MAX` even though the intrinsic `MAX` has been renamed to `MIN` ." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_ffreenexamplereduction5" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " fortranspecificend" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example is non-conforming because the initialization ( `a = 0` ) of the original list \n", +"* `a` is not synchronized with the update of `a` as a result of the reduction computation in the `for` loop. Therefore, the example may print an incorrect value for `a` ." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " To avoid this problem, the initialization of the original list \n", +"* `a` should complete before any update of `a` as a result of the `reduction` clause. This can be achieved by adding an explicit barrier after the assignment `a = 0` , or by enclosing the assignment `a = 0` in a `single` directive (which has an implied barrier), or by initializing `a` before the start of the `parallel` region." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_reduction.6.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_reduction.6.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example demonstrates the reduction of array _a_ . In C/C++ this is illustrated by the explicit use of an array section _a[0:N]_ in the `reduction` clause. The corresponding Fortran example uses array syntax supported in the base language. As of the OpenMP 4.5 specification the explicit use of array section in the `reduction` clause in Fortran is not permitted. But this oversight will be fixed in the next release of the specification." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_reduction.7.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_reduction.7.f90" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end---" + ] + } +], +"metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } +}, +"nbformat": 4, +"nbformat_minor": 2 +} diff --git a/notebook/Examples_set_dynamic_nthrs.ipynb b/notebook/Examples_set_dynamic_nthrs.ipynb new file mode 100644 index 0000000..3b7cbb7 --- /dev/null +++ b/notebook/Examples_set_dynamic_nthrs.ipynb @@ -0,0 +1,71 @@ +{ + "cells": [ +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "section{The `omp_set_dynamic` and " + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " `omp_set_num_threads` Routines}" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Some programs rely on a fixed, prespecified number of threads to execute correctly. Because the default setting for the dynamic adjustment of the number of threads is implementation defined, such programs can choose to turn off the dynamic threads capability and set the number of threads explicitly to ensure portability. The following example shows how to do this using `omp_set_dynamic` , and `omp_set_num_threads` ." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In this example, the program executes correctly only if it is executed by 16 threads. If the implementation is not capable of supporting 16 threads, the behavior of this example is implementation defined. Note that the number of threads executing a `parallel` region remains constant during the region, regardless of the dynamic threads setting. The dynamic threads mechanism determines the number of threads to use at the start of the `parallel` region and keeps it constant for the duration of the region." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_set_dynamic_nthrs.1.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_set_dynamic_nthrs.1.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end---" + ] + } +], +"metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } +}, +"nbformat": 4, +"nbformat_minor": 2 +} diff --git a/notebook/Examples_simple_lock.ipynb b/notebook/Examples_simple_lock.ipynb new file mode 100644 index 0000000..cf23300 --- /dev/null +++ b/notebook/Examples_simple_lock.ipynb @@ -0,0 +1,71 @@ +{ + "cells": [ +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### Simple Lock Routines" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the following example, the lock routines cause the threads to be idle while waiting for entry to the first critical section, but to do other work while waiting for entry to the second. The `omp_set_lock` function blocks, but the `omp_test_lock` function does not, allowing the work in `skip` to be done. " + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Note that the argument to the lock routines should have type `omp_lock_t` , and that there is no need to flush it. " + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_simple_lock.1.c" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Note that there is no need to flush the lock variable. " + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_simple_lock.1.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end---" + ] + } +], +"metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } +}, +"nbformat": 4, +"nbformat_minor": 2 +} diff --git a/notebook/Examples_single.ipynb b/notebook/Examples_single.ipynb new file mode 100644 index 0000000..49f3569 --- /dev/null +++ b/notebook/Examples_single.ipynb @@ -0,0 +1,57 @@ +{ + "cells": [ +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### The `single` Construct" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example demonstrates the `single` construct. In the example, only one thread prints each of the progress messages. All other threads will skip the `single` region and stop at the barrier at the end of the `single` construct until all threads in the team have reached the barrier. If other threads can proceed without waiting for the thread executing the `single` region, a `nowait` clause can be specified, as is done in the third `single` construct in this example. The user must not make any assumptions as to which thread will execute a `single` region." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_single.1.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_single.1.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end---" + ] + } +], +"metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } +}, +"nbformat": 4, +"nbformat_minor": 2 +} diff --git a/notebook/Examples_standalone.ipynb b/notebook/Examples_standalone.ipynb new file mode 100644 index 0000000..93849df --- /dev/null +++ b/notebook/Examples_standalone.ipynb @@ -0,0 +1,103 @@ +{ + "cells": [ +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "section{Placement of `flush` , `barrier` , `taskwait` " + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " and `taskyield` Directives}" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example is non-conforming, because the `flush` , `barrier` , `taskwait` , and `taskyield` directives are stand-alone directives and cannot be the immediate substatement of an `if` statement. " + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_standalone.1.c" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example is non-conforming, because the `flush` , `barrier` , `taskwait` , and `taskyield` directives are stand-alone directives and cannot be the action statement of an `if` statement or a labeled branch target." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_standalone.1.f90" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following version of the above example is conforming because the `flush` , `barrier` , `taskwait` , and `taskyield` directives are enclosed in a compound statement. " + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_standalone.2.c" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example is conforming because the `flush` , `barrier` , `taskwait` , and `taskyield` directives are enclosed in an `if` construct or follow the labeled branch target." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_standalone.2.f90" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end---" + ] + } +], +"metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } +}, +"nbformat": 4, +"nbformat_minor": 2 +} diff --git a/notebook/Examples_target.ipynb b/notebook/Examples_target.ipynb new file mode 100644 index 0000000..d0f7a52 --- /dev/null +++ b/notebook/Examples_target.ipynb @@ -0,0 +1,282 @@ +{ + "cells": [ +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### `target` Construct" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### `target` Construct on `parallel` Construct" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " This following example shows how the `target` construct offloads a code region to a target device. The variables _p_ , _v1_ , _v2_ , and _N_ are implicitly mapped to the target device." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target.1.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target.1.f90" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### `target` Construct with `map` Clause" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " This following example shows how the `target` construct offloads a code region to a target device. The variables _p_ , _v1_ and _v2_ are explicitly mapped to the target device using the `map` clause. The variable _N_ is implicitly mapped to the target device." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target.2.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target.2.f90" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### `map` Clause with `to` / `from` map-types" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows how the `target` construct offloads a code region to a target device. In the `map` clause, the `to` and `from` map-types define the mapping between the original (host) data and the target (device) data. The `to` map-type specifies that the data will only be read on the device, and the `from` map-type specifies that the data will only be written to on the device. By specifying a guaranteed access on the device, data transfers can be reduced for the `target` region." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `to` map-type indicates that at the start of the `target` region the variables _v1_ and _v2_ are initialized with the values of the corresponding variables on the host device, and at the end of the `target` region the variables _v1_ and _v2_ are not assigned to their corresponding variables on the host device." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `from` map-type indicates that at the start of the `target` region the variable _p_ is not initialized with the value of the corresponding variable on the host device, and at the end of the `target` region the variable _p_ is assigned to the corresponding variable on the host device." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target.3.c" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `to` and `from` map-types allow programmers to optimize data motion. Since data for the _v_ arrays are not returned, and data for the _p_ array are not transferred to the device, only one-half of the data is moved, compared to the default behavior of an implicit mapping." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target.3.f90" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### `map` Clause with Array Sections" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows how the `target` construct offloads a code region to a target device. In the `map` clause, map-types are used to optimize the mapping of variables to the target device. Because variables _p_ , _v1_ and _v2_ are pointers, array section notation must be used to map the arrays. The notation `:N` is equivalent to `0:N` ." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target.4.c" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In C, the length of the pointed-to array must be specified. In Fortran the extent of the array is known and the length need not be specified. A section of the array can be specified with the usual Fortran syntax, as shown in the following example. The value 1 is assumed for the lower bound for array section _v2(:N)_ ." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target.4.f90" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " A more realistic situation in which an assumed-size array is passed to `vec_mult` requires that the length of the arrays be specified, because the compiler does not know the size of the storage. A section of the array must be specified with the usual Fortran syntax, as shown in the following example. The value 1 is assumed for the lower bound for array section _v2(:N)_ ." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target.4b.f90" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### `target` Construct with `if` Clause" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows how the `target` construct offloads a code region to a target device." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `if` clause on the `target` construct indicates that if the variable _N_ is smaller than a given threshold, then the `target` region will be executed by the host device." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `if` clause on the `parallel` construct indicates that if the variable _N_ is smaller than a second threshold then the `parallel` region is inactive." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target.5.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target.5.f90" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example is a modification of the above _target.5_ code to show the combined `target` and parallel loop directives. It uses the _directive-name_ modifier in multiple `if` clauses to specify the component directive to which it applies. " + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `if` clause with the `target` modifier applies to the `target` component of the combined directive, and the `if` clause with the `parallel` modifier applies to the `parallel` component of the combined directive. " + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target.6.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target.6.f90" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end---" + ] + } +], +"metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } +}, +"nbformat": 4, +"nbformat_minor": 2 +} diff --git a/notebook/Examples_target_data.ipynb b/notebook/Examples_target_data.ipynb new file mode 100644 index 0000000..e7fa890 --- /dev/null +++ b/notebook/Examples_target_data.ipynb @@ -0,0 +1,340 @@ +{ + "cells": [ +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### `target` `data` Construct" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### Simple `target` `data` Construct" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " This example shows how the `target` `data` construct maps variables to a device data environment. The `target` `data` construct creates a new device data environment and maps the variables _v1_ , _v2_ , and _p_ to the new device data environment. The `target` construct enclosed in the `target` `data` region creates a new device data environment, which inherits the variables _v1_ , _v2_ , and _p_ from the enclosing device data environment. The variable _N_ is mapped into the new device data environment from the encountering task's data environment." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target_data.1.c" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The Fortran code passes a reference and specifies the extent of the arrays in the declaration. No length information is necessary in the map clause, as is required with C/C++ pointers." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target_data.1.f90" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### `target` `data` Region Enclosing Multiple `target` Regions" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following examples show how the `target` `data` construct maps variables to a device data environment of a `target` region. The `target` `data` construct creates a device data environment and encloses `target` regions, which have their own device data environments. The device data environment of the `target` `data` region is inherited by the device data environment of an enclosed `target` region. The `target` `data` construct is used to create variables that will persist throughout the `target` `data` region." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the following example the variables _v1_ and _v2_ are mapped at each `target` construct. Instead of mapping the variable _p_ twice, once at each `target` construct, _p_ is mapped once by the `target` `data` construct." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target_data.2.c" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The Fortran code uses reference and specifies the extent of the _p_ , _v1_ and _v2_ arrays. No length information is necessary in the `map` clause, as is required with C/C++ pointers. The arrays _v1_ and _v2_ are mapped at each `target` construct. Instead of mapping the array _p_ twice, once at each target construct, _p_ is mapped once by the `target` `data` construct." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target_data.2.f90" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the following example, the variable tmp defaults to `tofrom` map-type and is mapped at each `target` construct. The array _Q_ is mapped once at the enclosing `target` `data` region instead of at each `target` construct. " + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target_data.3.c" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the following example the arrays _v1_ and _v2_ are mapped at each `target` construct. Instead of mapping the array _Q_ twice at each `target` construct, _Q_ is mapped once by the `target` `data` construct. Note, the _tmp_ variable is implicitly remapped for each `target` region, mapping the value from the device to the host at the end of the first `target` region, and from the host to the device for the second `target` region." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target_data.3.f90" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### `target` `data` Construct with Orphaned Call" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following two examples show how the `target` `data` construct maps variables to a device data environment. The `target` `data` construct's device data environment encloses the `target` construct's device data environment in the function `vec_mult()` ." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " When the type of the variable appearing in an array section is pointer, the pointer variable and the storage location of the corresponding array section are mapped to the device data environment. The pointer variable is treated as if it had appeared in a `map` clause with a map-type of `alloc` . The array section's storage location is mapped according to the map-type in the `map` clause (the default map-type is `tofrom` )." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `target` construct's device data environment inherits the storage locations of the array sections _v1[0:N]_ , _v2[:n]_ , and _p0[0:N]_ from the enclosing target data construct's device data environment. Neither initialization nor assignment is performed for the array sections in the new device data environment." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The pointer variables _p1_ , _v3_ , and _v4_ are mapped into the target construct's device data environment with an implicit map-type of alloc and they are assigned the address of the storage location associated with their corresponding array sections. Note that the following pairs of array section storage locations are equivalent ( _p0[:N]_ , _p1[:N]_ ), ( _v1[:N]_ , _v3[:N]_ ), and ( _v2[:N]_ , _v4[:N]_ )." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target_data.4.c" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The Fortran code maps the pointers and storage in an identical manner (same extent, but uses indices from 1 to _N_ )." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `target` construct's device data environment inherits the storage locations of the arrays _v1_ , _v2_ and _p0_ from the enclosing `target` `data` constructs's device data environment. However, in Fortran the associated data of the pointer is known, and the shape is not required." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The pointer variables _p1_ , _v3_ , and _v4_ are mapped into the `target` construct's device data environment with an implicit map-type of `alloc` and they are assigned the address of the storage location associated with their corresponding array sections. Note that the following pair of array storage locations are equivalent ( _p0_ , _p1_ ), ( _v1_ , _v3_ ), and ( _v2_ , _v4_ )." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target_data.4.f90" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the following example, the variables _p1_ , _v3_ , and _v4_ are references to the pointer variables _p0_ , _v1_ and _v2_ respectively. The `target` construct's device data environment inherits the pointer variables _p0_ , _v1_ , and _v2_ from the enclosing `target` `data` construct's device data environment. Thus, _p1_ , _v3_ , and _v4_ are already present in the device data environment." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target_data.5.cpp" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the following example, the usual Fortran approach is used for dynamic memory. The _p0_ , _v1_ , and _v2_ arrays are allocated in the main program and passed as references from one routine to another. In `vec_mult` , _p1_ , _v3_ and _v4_ are references to the _p0_ , _v1_ , and _v2_ arrays, respectively. The `target` construct's device data environment inherits the arrays _p0_ , _v1_ , and _v2_ from the enclosing target data construct's device data environment. Thus, _p1_ , _v3_ , and _v4_ are already present in the device data environment." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target_data.5.f90" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### `target` `data` Construct with `if` Clause" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following two examples show how the `target` `data` construct maps variables to a device data environment." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the following example, the if clause on the `target` `data` construct indicates that if the variable _N_ is smaller than a given threshold, then the `target` `data` construct will not create a device data environment." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `target` constructs enclosed in the `target` `data` region must also use an `if` clause on the same condition, otherwise the pointer variable _p_ is implicitly mapped with a map-type of `tofrom` , but the storage location for the array section _p[0:N]_ will not be mapped in the device data environments of the `target` constructs." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target_data.6.c" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `if` clauses work the same way for the following Fortran code. The `target` constructs enclosed in the `target` `data` region should also use an `if` clause with the same condition, so that the `target` `data` region and the `target` region are either both created for the device, or are both ignored." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target_data.6.f90" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the following example, when the `if` clause conditional expression on the `target` construct evaluates to _false_ , the target region will execute on the host device. However, the `target` `data` construct created an enclosing device data environment that mapped _p[0:N]_ to a device data environment on the default device. At the end of the `target` `data` region the array section _p[0:N]_ will be assigned from the device data environment to the corresponding variable in the data environment of the task that encountered the `target` `data` construct, resulting in undefined values in _p[0:N]_ ." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target_data.7.c" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `if` clauses work the same way for the following Fortran code. When the `if` clause conditional expression on the `target` construct evaluates to _false_ , the `target` region will execute on the host device. However, the `target` `data` construct created an enclosing device data environment that mapped the _p_ array (and _v1_ and _v2_ ) to a device data environment on the default target device. At the end of the `target` `data` region the _p_ array will be assigned from the device data environment to the corresponding variable in the data environment of the task that encountered the `target` `data` construct, resulting in undefined values in _p_ ." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target_data.7.f90" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end---" + ] + } +], +"metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } +}, +"nbformat": 4, +"nbformat_minor": 2 +} diff --git a/notebook/Examples_target_unstructured_data.ipynb b/notebook/Examples_target_unstructured_data.ipynb new file mode 100644 index 0000000..698120b --- /dev/null +++ b/notebook/Examples_target_unstructured_data.ipynb @@ -0,0 +1,118 @@ +{ + "cells": [ +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"begin " + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### `target` `enter` `data` and `target` `exit` `data` Constructs" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +" ### Simple target enter data and target exit data Constructs" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The structured data construct ( `target` ~ `data` ) provides persistent data on a device for subsequent `target` constructs as shown in the `target` ~ `data` examples above. This is accomplished by creating a single `target` ~ `data` region containing `target` constructs." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The unstructured data constructs allow the creation and deletion of data on the device at any appropriate point within the host code, as shown below with the `target` ~ `enter` ~ `data` and `target` ~ `exit` ~ `data` constructs." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following C++ code creates/deletes a vector in a constructor/destructor of a class. The constructor creates a vector with `target` ~ `enter` ~ `data` and uses an `alloc` modifier in the `map` clause to avoid copying values to the device. The destructor deletes the data ( `target` ~ `exit` ~ `data` ) and uses the `delete` modifier in the `map` clause to avoid copying data back to the host. Note, the stand-alone `target` ~ `enter` ~ `data` occurs after the host vector is created, and the `target` ~ `exit` ~ `data` construct occurs before the host data is deleted." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target_unstructured_data.1.cpp" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following C code allocates and frees the data member of a Matrix structure. The `init_matrix` function allocates the memory used in the structure and uses the `target` ~ `enter` ~ `data` directive to map it to the target device. The `free_matrix` function removes the mapped array from the target device and then frees the memory on the host. Note, the stand-alone `target` ~ `enter` ~ `data` occurs after the host memory is allocated, and the `target` ~ `exit` ~ `data` construct occurs before the host data is freed." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target_unstructured_data.1.c" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following Fortran code allocates and deallocates a module array. The `initialize` subroutine allocates the module array and uses the `target` ~ `enter` ~ `data` directive to map it to the target device. The `finalize` subroutine removes the mapped array from the target device and then deallocates the array on the host. Note, the stand-alone `target` ~ `enter` ~ `data` occurs after the host memory is allocated, and the `target` ~ `exit` ~ `data` construct occurs before the host data is deallocated." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target_unstructured_data.1.f90" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"end" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end---" + ] + } +], +"metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } +}, +"nbformat": 4, +"nbformat_minor": 2 +} diff --git a/notebook/Examples_target_update.ipynb b/notebook/Examples_target_update.ipynb new file mode 100644 index 0000000..ca2a4af --- /dev/null +++ b/notebook/Examples_target_update.ipynb @@ -0,0 +1,152 @@ +{ + "cells": [ +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### `target` `update` Construct" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### Simple `target` `data` and `target` `update` Constructs" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows how the `target` `update` construct updates variables in a device data environment." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `target` `data` construct maps array sections _v1[:N]_ and _v2[:N]_ (arrays _v1_ and _v2_ in the Fortran code) into a device data environment." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The task executing on the host device encounters the first `target` region and waits for the completion of the region." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " After the execution of the first `target` region, the task executing on the host device then assigns new values to _v1[:N]_ and _v2[:N]_ ( _v1_ and _v2_ arrays in Fortran code) in the task's data environment by calling the function `init_again()` ." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `target` `update` construct assigns the new values of _v1_ and _v2_ from the task's data environment to the corresponding mapped array sections in the device data environment of the `target` `data` construct." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The task executing on the host device then encounters the second `target` region and waits for the completion of the region." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The second `target` region uses the updated values of _v1[:N]_ and _v2[:N]_ ." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target_update.1.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target_update.1.f90" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### `target` `update` Construct with `if` Clause" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows how the `target` `update` construct updates variables in a device data environment." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `target` `data` construct maps array sections _v1[:N]_ and _v2[:N]_ (arrays _v1_ and _v2_ in the Fortran code) into a device data environment. In between the two `target` regions, the task executing on the host device conditionally assigns new values to _v1_ and _v2_ in the task's data environment. The function `maybe_init_again()` returns _true_ if new data is written." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " When the conditional expression (the return value of `maybe_init_again()` ) in the `if` clause is _true_ , the `target` `update` construct assigns the new values of _v1_ and _v2_ from the task's data environment to the corresponding mapped array sections in the `target` `data` construct's device data environment." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target_update.2.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target_update.2.f90" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end---" + ] + } +], +"metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } +}, +"nbformat": 4, +"nbformat_minor": 2 +} diff --git a/notebook/Examples_task_dep.ipynb b/notebook/Examples_task_dep.ipynb new file mode 100644 index 0000000..efd40d8 --- /dev/null +++ b/notebook/Examples_task_dep.ipynb @@ -0,0 +1,220 @@ +{ + "cells": [ +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Task Dependences" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### Flow Dependence" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In this example we show a simple flow dependence expressed using the `depend` clause on the `task` construct." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_task_dep.1.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_task_dep.1.f90" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The program will always print ' x = 2 ' , because the `depend` clauses enforce the ordering of the tasks. If the `depend` clauses had been omitted, then the tasks could execute in any order and the program and the program would have a race condition." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### Anti-dependence" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In this example we show an anti-dependence expressed using the `depend` clause on the `task` construct." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_task_dep.2.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_task_dep.2.f90" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The program will always print ' x = 1 ' , because the `depend` clauses enforce the ordering of the tasks. If the `depend` clauses had been omitted, then the tasks could execute in any order and the program would have a race condition." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### Output Dependence" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In this example we show an output dependence expressed using the `depend` clause on the `task` construct." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_task_dep.3.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_task_dep.3.f90" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The program will always print ' x = 2 ' , because the `depend` clauses enforce the ordering of the tasks. If the `depend` clauses had been omitted, then the tasks could execute in any order and the program would have a race condition." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### Concurrent Execution with Dependences" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In this example we show potentially concurrent execution of tasks using multiple flow dependences expressed using the `depend` clause on the `task` construct." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_task_dep.4.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_task_dep.4.f90" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The last two tasks are dependent on the first task. However there is no dependence between the last two tasks, which may execute in any order (or concurrently if more than one thread is available). Thus, the possible outputs are ' x + 1 = 3. x + 2 = 4. ' and ' x + 2 = 4. x + 1 = 3. ' . If the `depend` clauses had been omitted, then all of the tasks could execute in any order and the program would have a race condition." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### Matrix multiplication" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " This example shows a task-based blocked matrix multiplication. Matrices are of NxN elements, and the multiplication is implemented using blocks of BSxBS elements." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_task_dep.5.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_task_dep.5.f90" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end---" + ] + } +], +"metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } +}, +"nbformat": 4, +"nbformat_minor": 2 +} diff --git a/notebook/Examples_task_priority.ipynb b/notebook/Examples_task_priority.ipynb new file mode 100644 index 0000000..36e4d73 --- /dev/null +++ b/notebook/Examples_task_priority.ipynb @@ -0,0 +1,73 @@ +{ + "cells": [ +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Task Priority" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +" #### Task Priority \n", +"" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In this example we compute arrays in a matrix through a _compute_array_ routine. Each task has a priority value equal to the value of the loop variable _i_ at the moment of its creation. A higher priority on a task means that a task is a candidate to run sooner." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The creation of tasks occurs in ascending order (according to the iteration space of the loop) but a hint, by means of the `priority` clause, is provided to reverse the execution order." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_task_priority.1.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_task_priority.1.f90" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end---" + ] + } +], +"metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } +}, +"nbformat": 4, +"nbformat_minor": 2 +} diff --git a/notebook/Examples_taskgroup.ipynb b/notebook/Examples_taskgroup.ipynb new file mode 100644 index 0000000..3f0b0ae --- /dev/null +++ b/notebook/Examples_taskgroup.ipynb @@ -0,0 +1,64 @@ +{ + "cells": [ +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### The `taskgroup` Construct" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In this example, tasks are grouped and synchronized using the `taskgroup` construct." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Initially, one task (the task executing the `start_background_work()` call) is created in the `parallel` region, and later a parallel tree traversal is started (the task executing the root of the recursive `compute_tree()` calls). While synchronizing tasks at the end of each tree traversal, using the `taskgroup` construct ensures that the formerly started background task does not participate in the synchronization, and is left free to execute in parallel. This is opposed to the behaviour of the `taskwait` construct, which would include the background tasks in the synchronization." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_taskgroup.1.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_taskgroup.1.f90" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end---" + ] + } +], +"metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } +}, +"nbformat": 4, +"nbformat_minor": 2 +} diff --git a/notebook/Examples_tasking.ipynb b/notebook/Examples_tasking.ipynb new file mode 100644 index 0000000..3b69f18 --- /dev/null +++ b/notebook/Examples_tasking.ipynb @@ -0,0 +1,417 @@ +{ + "cells": [ +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### The `task` and `taskwait` Constructs" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows how to traverse a tree-like structure using explicit tasks. Note that the `traverse` function should be called from within a parallel region for the different specified tasks to be executed in parallel. Also note that the tasks will be executed in no specified order because there are no synchronization directives. Thus, assuming that the traversal will be done in post order, as in the sequential code, is wrong." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_tasking.1.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_tasking.1.f90" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the next example, we force a postorder traversal of the tree by adding a `taskwait` directive. Now, we can safely assume that the left and right sons have been executed before we process the current node." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_tasking.2.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_tasking.2.f90" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example demonstrates how to use the `task` construct to process elements of a linked list in parallel. The thread executing the `single` region generates all of the explicit tasks, which are then executed by the threads in the current team. The pointer _p_ is `firstprivate` by default on the `task` construct so it is not necessary to specify it in a `firstprivate` clause." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_tasking.3.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_tasking.3.f90" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `fib()` function should be called from within a `parallel` region for the different specified tasks to be executed in parallel. Also, only one thread of the `parallel` region should call `fib()` unless multiple concurrent Fibonacci computations are desired. " + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_tasking.4.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_tasking.4.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Note: There are more efficient algorithms for computing Fibonacci numbers. This classic recursion algorithm is for illustrative purposes." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example demonstrates a way to generate a large number of tasks with one thread and execute them with the threads in the team. While generating these tasks, the implementation may reach its limit on unassigned tasks. If it does, the implementation is allowed to cause the thread executing the task generating loop to suspend its task at the task scheduling point in the `task` directive, and start executing unassigned tasks. Once the number of unassigned tasks is sufficiently low, the thread may resume execution of the task generating loop." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_tasking.5.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_tasking.5.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example is the same as the previous one, except that the tasks are generated in an untied task. While generating the tasks, the implementation may reach its limit on unassigned tasks. If it does, the implementation is allowed to cause the thread executing the task generating loop to suspend its task at the task scheduling point in the `task` directive, and start executing unassigned tasks. If that thread begins execution of a task that takes a long time to complete, the other threads may complete all the other tasks before it is finished." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In this case, since the loop is in an untied task, any other thread is eligible to resume the task generating loop. In the previous examples, the other threads would be forced to idle until the generating thread finishes its long task, since the task generating loop was in a tied task." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_tasking.6.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_tasking.6.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following two examples demonstrate how the scheduling rules illustrated in Section 2.11.3 of the OpenMP 4.0 specification affect the usage of `threadprivate` variables in tasks. A `threadprivate` variable can be modified by another task that is executed by the same thread. Thus, the value of a `threadprivate` variable cannot be assumed to be unchanged across a task scheduling point. In untied tasks, task scheduling points may be added in any place by the implementation." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " A task switch may occur at a task scheduling point. A single thread may execute both of the task regions that modify `tp` . The parts of these task regions in which `tp` is modified may be executed in any order so the resulting value of `var` can be either 1 or 2." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_tasking.7.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_tasking.7.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In this example, scheduling constraints prohibit a thread in the team from executing a new task that modifies `tp` while another such task region tied to the same thread is suspended. Therefore, the value written will persist across the task scheduling point." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_tasking.8.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_tasking.8.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following two examples demonstrate how the scheduling rules illustrated in Section 2.11.3 of the OpenMP 4.0 specification affect the usage of locks and critical sections in tasks. If a lock is held across a task scheduling point, no attempt should be made to acquire the same lock in any code that may be interleaved. Otherwise, a deadlock is possible." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the example below, suppose the thread executing task 1 defers task 2. When it encounters the task scheduling point at task 3, it could suspend task 1 and begin task 2 which will result in a deadlock when it tries to enter critical region 1." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_tasking.9.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_tasking.9.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the following example, `lock` is held across a task scheduling point. However, according to the scheduling restrictions, the executing thread can't begin executing one of the non-descendant tasks that also acquires `lock` before the task region is complete. Therefore, no deadlock is possible." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_tasking.10.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_tasking.10.f90" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following examples illustrate the use of the `mergeable` clause in the `task` construct. In this first example, the `task` construct has been annotated with the `mergeable` clause. The addition of this clause allows the implementation to reuse the data environment (including the ICVs) of the parent task for the task inside `foo` if the task is included or undeferred. Thus, the result of the execution may differ depending on whether the task is merged or not. Therefore the mergeable clause needs to be used with caution. In this example, the use of the mergeable clause is safe. As `x` is a shared variable the outcome does not depend on whether or not the task is merged (that is, the task will always increment the same variable and will always compute the same value for `x` )." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_tasking.11.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_tasking.11.f90" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " This second example shows an incorrect use of the `mergeable` clause. In this example, the created task will access different instances of the variable `x` if the task is not merged, as `x` is `firstprivate` , but it will access the same variable `x` if the task is merged. As a result, the behavior of the program is unspecified and it can print two different values for `x` depending on the decisions taken by the implementation." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_tasking.12.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_tasking.12.f90" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows the use of the `final` clause and the `omp_in_final` API call in a recursive binary search program. To reduce overhead, once a certain depth of recursion is reached the program uses the `final` clause to create only included tasks, which allow additional optimizations." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The use of the `omp_in_final` API call allows programmers to optimize their code by specifying which parts of the program are not necessary when a task can create only included tasks (that is, the code is inside a `final` task). In this example, the use of a different state variable is not necessary so once the program reaches the part of the computation that is finalized and copying from the parent state to the new state is eliminated. The allocation of `new_state` in the stack could also be avoided but it would make this example less clear. The `final` clause is most effective when used in conjunction with the `mergeable` clause since all tasks created in a `final` task region are included tasks that can be merged if the `mergeable` clause is present." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_tasking.13.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_tasking.13.f90" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example illustrates the difference between the `if` and the `final` clauses. The `if` clause has a local effect. In the first nest of tasks, the one that has the `if` clause will be undeferred but the task nested inside that task will not be affected by the `if` clause and will be created as usual. Alternatively, the `final` clause affects all `task` constructs in the `final` task region but not the `final` task itself. In the second nest of tasks, the nested tasks will be created as included tasks. Note also that the conditions for the `if` and `final` clauses are usually the opposite." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_tasking.14.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_tasking.14.f90" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end---" + ] + } +], +"metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } +}, +"nbformat": 4, +"nbformat_minor": 2 +} diff --git a/notebook/Examples_taskloop.ipynb b/notebook/Examples_taskloop.ipynb new file mode 100644 index 0000000..44c573e --- /dev/null +++ b/notebook/Examples_taskloop.ipynb @@ -0,0 +1,60 @@ +{ + "cells": [ +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### The `taskloop` Construct " + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example illustrates how to execute a long running task concurrently with tasks created with a `taskloop` directive for a loop having unbalanced amounts of work for its iterations. The `grainsize` clause specifies that each task is to execute at least 500 iterations of the loop. The `nogroup` clause removes the implicit taskgroup of the `taskloop` construct; the explicit `taskgroup` construct in the example ensures that the function is not exited before the long-running task and the loops have finished execution. cexample{taskloop}{1} " + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ffreeexample{taskloop}{1} " + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end---" + ] + } +], +"metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } +}, +"nbformat": 4, +"nbformat_minor": 2 +} diff --git a/notebook/Examples_taskyield.ipynb b/notebook/Examples_taskyield.ipynb new file mode 100644 index 0000000..3babc48 --- /dev/null +++ b/notebook/Examples_taskyield.ipynb @@ -0,0 +1,57 @@ +{ + "cells": [ +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### The `taskyield` Construct" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example illustrates the use of the `taskyield` directive. The tasks in the example compute something useful and then do some computation that must be done in a critical region. By using `taskyield` when a task cannot get access to the `critical` region the implementation can suspend the current task and schedule some other task that can do something useful. " + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_taskyield.1.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_taskyield.1.f90" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end---" + ] + } +], +"metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } +}, +"nbformat": 4, +"nbformat_minor": 2 +} diff --git a/notebook/Examples_teams.ipynb b/notebook/Examples_teams.ipynb new file mode 100644 index 0000000..750c223 --- /dev/null +++ b/notebook/Examples_teams.ipynb @@ -0,0 +1,308 @@ +{ + "cells": [ +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### `teams` Constructs" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "subsection{ `target` and `teams` Constructs with `omp_get_num_teams` " + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " and `omp_get_team_num` Routines}" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows how the `target` and `teams` constructs are used to create a league of thread teams that execute a region. The `teams` construct creates a league of at most two teams where the master thread of each team executes the `teams` region." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `omp_get_num_teams` routine returns the number of teams executing in a `teams` region. The `omp_get_team_num` routine returns the team number, which is an integer between 0 and one less than the value returned by `omp_get_num_teams` . The following example manually distributes a loop across two teams." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_teams.1.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_teams.1.f90" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### `target` , `teams` , and `distribute` Constructs" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows how the `target` , `teams` , and `distribute` constructs are used to execute a loop nest in a `target` region. The `teams` construct creates a league and the master thread of each team executes the `teams` region. The `distribute` construct schedules the subsequent loop iterations across the master threads of each team." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The number of teams in the league is less than or equal to the variable _num_blocks_ . Each team in the league has a number of threads less than or equal to the variable _block_threads_ . The iterations in the outer loop are distributed among the master threads of each team." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " When a team's master thread encounters the parallel loop construct before the inner loop, the other threads in its team are activated. The team executes the `parallel` region and then workshares the execution of the loop." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Each master thread executing the `teams` region has a private copy of the variable _sum_ that is created by the `reduction` clause on the `teams` construct. The master thread and all threads in its team have a private copy of the variable _sum_ that is created by the `reduction` clause on the parallel loop construct. The second private _sum_ is reduced into the master thread's private copy of _sum_ created by the `teams` construct. At the end of the `teams` region, each master thread's private copy of _sum_ is reduced into the final _sum_ that is implicitly mapped into the `target` region." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_teams.2.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_teams.2.f90" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### `target` `teams` , and Distribute Parallel Loop Constructs" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows how the `target` `teams` and distribute parallel loop constructs are used to execute a `target` region. The `target` `teams` construct creates a league of teams where the master thread of each team executes the `teams` region." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The distribute parallel loop construct schedules the loop iterations across the master threads of each team and then across the threads of each team." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_teams.3.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_teams.3.f90" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "subsection{ `target` `teams` and Distribute Parallel Loop " + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Constructs with Scheduling Clauses}" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows how the `target` `teams` and distribute parallel loop constructs are used to execute a `target` region. The `teams` construct creates a league of at most eight teams where the master thread of each team executes the `teams` region. The number of threads in each team is less than or equal to 16." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `distribute` parallel loop construct schedules the subsequent loop iterations across the master threads of each team and then across the threads of each team." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `dist_schedule` clause on the distribute parallel loop construct indicates that loop iterations are distributed to the master thread of each team in chunks of 1024 iterations." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `schedule` clause indicates that the 1024 iterations distributed to a master thread are then assigned to the threads in its associated team in chunks of 64 iterations." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_teams.4.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_teams.4.f90" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### `target` `teams` and `distribute` `simd` Constructs" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows how the `target` `teams` and `distribute` `simd` constructs are used to execute a loop in a `target` region. The `target` `teams` construct creates a league of teams where the master thread of each team executes the `teams` region." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `distribute` `simd` construct schedules the loop iterations across the master thread of each team and then uses SIMD parallelism to execute the iterations." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_teams.5.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_teams.5.f90" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### `target` `teams` and Distribute Parallel Loop SIMD Constructs" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows how the `target` `teams` and the distribute parallel loop SIMD constructs are used to execute a loop in a `target` `teams` region. The `target` `teams` construct creates a league of teams where the master thread of each team executes the `teams` region." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The distribute parallel loop SIMD construct schedules the loop iterations across the master thread of each team and then across the threads of each team where each thread uses SIMD parallelism." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_teams.6.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_teams.6.f90" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end---" + ] + } +], +"metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } +}, +"nbformat": 4, +"nbformat_minor": 2 +} diff --git a/notebook/Examples_threadprivate.ipynb b/notebook/Examples_threadprivate.ipynb new file mode 100644 index 0000000..ad88b35 --- /dev/null +++ b/notebook/Examples_threadprivate.ipynb @@ -0,0 +1,284 @@ +{ + "cells": [ +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### The `threadprivate` Directive" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following examples demonstrate how to use the `threadprivate` directive to give each thread a separate counter." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_threadprivate.1.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_threadprivate.1.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ccppspecificstart The following example uses `threadprivate` on a static variable:" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_threadprivate.2.c" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example demonstrates unspecified behavior for the initialization of a `threadprivate` variable. A `threadprivate` variable is initialized once at an unspecified point before its first reference. Because `a` is constructed using the value of `x` (which is modified by the statement `x++` ), the value of `a.val` at the start of the `parallel` region could be either 1 or 2. This problem is avoided for `b` , which uses an auxiliary `const` variable and a copy-constructor." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_cppnexamplethreadprivate3" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ccppspecificend" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following examples show non-conforming uses and correct uses of the `threadprivate` directive. " + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " fortranspecificstart The following example is non-conforming because the common block is not declared local to the subroutine that refers to it:" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_threadprivate.2.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example is also non-conforming because the common block is not declared local to the subroutine that refers to it:" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_threadprivate.3.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example is a correct rewrite of the previous example:" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_threadprivate.4.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following is an example of the use of `threadprivate` for local variables: \n", +" blue line floater at top of this page for 'Fortran, cont.' [t!] linewitharrows{-1}{dashed}{Fortran (cont.)}{8em} " + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_threadprivate.5.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The above program, if executed by two threads, will print one of the following two sets of output: " + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " `a = 11 12 13` `ptr = 4` `i = 15` " + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " `A is not allocated` `ptr = 4` `i = 5` " + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " or" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " `A is not allocated` `ptr = 4` `i = 15` " + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " `a = 1 2 3` `ptr = 4` `i = 5` " + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following is an example of the use of `threadprivate` for module variables: \n", +" blue line floater at top of this page for 'Fortran, cont.' [t!] linewitharrows{-1}{dashed}{Fortran (cont.)}{8em} " + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_threadprivate.6.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " fortranspecificend" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_cppspecificstart" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example illustrates initialization of `threadprivate` variables for class-type `T` . `t1` is default constructed, `t2` is constructed taking a constructor accepting one argument of integer type, `t3` is copy constructed with argument `f()` :" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_cppnexamplethreadprivate4" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example illustrates the use of `threadprivate` for static class members. The `threadprivate` directive for a static class member must be placed inside the class definition." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_cppnexamplethreadprivate5" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_cppspecificend" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end---" + ] + } +], +"metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } +}, +"nbformat": 4, +"nbformat_minor": 2 +} diff --git a/notebook/Examples_workshare.ipynb b/notebook/Examples_workshare.ipynb new file mode 100644 index 0000000..1324a16 --- /dev/null +++ b/notebook/Examples_workshare.ipynb @@ -0,0 +1,195 @@ +{ + "cells": [ +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### The `workshare` Construct" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " fortranspecificstart" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following are examples of the `workshare` construct. " + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the following example, `workshare` spreads work across the threads executing the `parallel` region, and there is a barrier after the last statement. Implementations must enforce Fortran execution rules inside of the `workshare` block." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_workshare.1.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the following example, the barrier at the end of the first `workshare` region is eliminated with a `nowait` clause. Threads doing `CC = DD` immediately begin work on `EE = FF` when they are done with `CC = DD` ." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_workshare.2.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +" blue line floater at top of this page for 'Fortran, cont.' [t!] linewitharrows{-1}{dashed}{Fortran (cont.)}{8em} " + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows the use of an `atomic` directive inside a `workshare` construct. The computation of `SUM(AA)` is workshared, but the update to `R` is atomic." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_workshare.3.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Fortran `WHERE` and `FORALL` statements are emph{compound statements}, made up of a emph{control} part and a emph{statement} part. When `workshare` is applied to one of these compound statements, both the control and the statement parts are workshared. The following example shows the use of a `WHERE` statement in a `workshare` construct." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Each task gets worked on in order by the threads:" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " `AA = BB` then `CC = DD` then `EE .ne. 0` then `FF = 1 / EE` then `GG = HH` " + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_workshare.4.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +" blue line floater at top of this page for 'Fortran, cont.' [t!] linewitharrows{-1}{dashed}{Fortran (cont.)}{8em} " + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the following example, an assignment to a shared scalar variable is performed by one thread in a `workshare` while all other threads in the team wait." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_workshare.5.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example contains an assignment to a private scalar variable, which is performed by one thread in a `workshare` while all other threads wait. It is non-conforming because the private scalar variable is undefined after the assignment statement. " + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_workshare.6.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Fortran execution rules must be enforced inside a `workshare` construct. In the following example, the same result is produced in the following program fragment regardless of whether the code is executed sequentially or inside an OpenMP program with multiple threads:" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_workshare.7.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " fortranspecificend" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end---" + ] + } +], +"metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } +}, +"nbformat": 4, +"nbformat_minor": 2 +} diff --git a/notebook/Examples_worksharing_critical.ipynb b/notebook/Examples_worksharing_critical.ipynb new file mode 100644 index 0000000..caecc1e --- /dev/null +++ b/notebook/Examples_worksharing_critical.ipynb @@ -0,0 +1,57 @@ +{ + "cells": [ +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Worksharing Constructs Inside a `critical` Construct" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example demonstrates using a worksharing construct inside a `critical` construct. This example is conforming because the worksharing `single` region is not closely nested inside the `critical` region. A single thread executes the one and only section in the `sections` region, and executes the `critical` region. The same thread encounters the nested `parallel` region, creates a new team of threads, and becomes the master of the new team. One of the threads in the new team enters the `single` region and increments `i` by `1` . At the end of this example `i` is equal to `2` ." + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_worksharing_critical.1.c" + ] + }, +{ + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_worksharing_critical.1.f" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end---" + ] + } +], +"metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } +}, +"nbformat": 4, +"nbformat_minor": 2 +} diff --git a/notebook/History.ipynb b/notebook/History.ipynb new file mode 100644 index 0000000..396097a --- /dev/null +++ b/notebook/History.ipynb @@ -0,0 +1,128 @@ +{ + "cells": [ +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ## Document Revision History" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Changes from 4.0.2 to 4.5.0" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* Reorganized into chapters of major topics \n", +"* Included file extensions in example labels to indicate source type \n", +"* Applied the explicit `map(tofrom)` for scalar variables in a number of examples to comply with the change of the default behavior for scalar variables from `map(tofrom)` to `firstprivate` in the 4.5 specification \n", +"* Added the following new examples: \n", +"* `linear` clause in loop constructs () \n", +"* task priority () \n", +"* `taskloop` construct () \n", +"* _directive-name_ modifier in multiple `if` clauses on a combined construct () \n", +"* unstructured data mapping () \n", +"* `link` clause for `declare` ~ `target` directive () \n", +"* asynchronous target execution with `nowait` clause () \n", +"* device memory routines and device pointers () \n", +"* doacross loop nest () \n", +"* locks with hints () \n", +"* C/C++ array reduction () \n", +"* C++ reference types in data sharing clauses () " + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Changes from 4.0.1 to 4.0.2" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* Names of examples were changed from numbers to mnemonics \n", +"* Added SIMD examples () \n", +"* Applied miscellaneous fixes in several source codes \n", +"* Added the revision history " + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Changes from 4.0 to 4.0.1" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Added the following new examples: \n", +"* the `proc_bind` clause () \n", +"* the `taskgroup` construct () " + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Changes from 3.1 to 4.0" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Beginning with OpenMP 4.0, examples were placed in a separate document from the specification document." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Version 4.0 added the following new examples: \n", +"* task dependences () \n", +"* `target` construct () \n", +"* `target` `data` construct () \n", +"* `target` `update` construct () \n", +"* `declare` `target` construct () \n", +"* `teams` constructs () \n", +"* asynchronous execution of a `target` region using tasks () \n", +"* array sections in device constructs () \n", +"* device runtime routines () \n", +"* Fortran ASSOCIATE construct () \n", +"* cancellation constructs () " + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end---" + ] + } +], +"metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } +}, +"nbformat": 4, +"nbformat_minor": 2 +} diff --git a/notebook/Introduction_Chapt.ipynb b/notebook/Introduction_Chapt.ipynb new file mode 100644 index 0000000..fc9b114 --- /dev/null +++ b/notebook/Introduction_Chapt.ipynb @@ -0,0 +1,139 @@ +{ + "cells": [ +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +" This is the introduction for the OpenMP Examples document. \n", +" This is an included file. See the master file (openmp-examples.tex) for more information. \n", +" \n", +" When editing this file: \n", +" \n", +" 1. To change formatting, appearance, or style, please edit openmp.sty. \n", +" \n", +" 2. Custom commands and macros are defined in openmp.sty. \n", +" \n", +" 3. Be kind to other editors -- keep a consistent style by copying-and-pasting to \n", +" create new content. \n", +" \n", +" 4. We use semantic markup, e.g. (see openmp.sty for a full list): \n", +" `` \n", +" for bold monospace keywords, code, operators, etc. \n", +" __ \n", +" for italic placeholder names, grammar, etc. \n", +" \n", +" 5. Other recommendations: \n", +" Use the convenience macros defined in openmp.sty for the minor headers \n", +" such as Comments, Syntax, etc. \n", +" \n", +" To keep items together on the same page, prefer the use of \n", +" .... Avoid parbox for text blocks as it interrupts line numbering. \n", +" When possible, avoid filbreak, , newpage, clearpage unless that's \n", +" what you mean. Use needspace{} cautiously for troublesome paragraphs. \n", +" \n", +" Avoid absolute lengths and measures in this file; use relative units when possible. \n", +" Vertical space can be relative to baselineskip or ex units. Horizontal space \n", +" can be relative to linewidth or em units. \n", +" \n", +" Prefer emph{} to italicize terminology, e.g.: \n", +" This is a emph{definition}, not a placeholder. \n", +" This is a _var-name_ . \n", +"" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "chapter*{Introduction}" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " addcontentsline{toc}{chapter}{protectnumberline{}Introduction} This collection of programming examples supplements the OpenMP API for Shared Memory Parallelization specifications, and is not part of the formal specifications. It assumes familiarity with the OpenMP specifications, and shares the typographical conventions used in that document." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " notestart noteheader – This first release of the OpenMP Examples reflects the OpenMP Version 4.5 specifications. Additional examples are being developed and will be published in future releases of this document. noteend" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The OpenMP API specification provides a model for parallel programming that is portable across shared memory architectures from different vendors. Compilers from numerous vendors support the OpenMP API." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The directives, library routines, and environment variables demonstrated in this document allow users to create and manage parallel programs while permitting portability. The directives extend the C, C++ and Fortran base languages with single program multiple data (SPMD) constructs, tasking constructs, device constructs, worksharing constructs, and synchronization constructs, and they provide support for sharing and privatizing data. The functionality to control the runtime environment is provided by library routines and environment variables. Compilers that support the OpenMP API often include a command line option to the compiler that activates and allows interpretation of all OpenMP directives." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The latest source codes for OpenMP Examples can be downloaded from the `sources` directory at https://github.com/OpenMP/Examples The codes for this OpenMP VER{} Examples document have the tag _vVER_ ." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +" https://github.com/OpenMP/Examples/tree/master/sources " + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Complete information about the OpenMP API and a list of the compilers that support the OpenMP API can be found at the OpenMP.org web site" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " `http://www.openmp.org` " + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +" This is the end of introduction.tex of the OpenMP Examples document." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end---" + ] + } +], +"metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } +}, +"nbformat": 4, +"nbformat_minor": 2 +} diff --git a/notebook/Title_Page.ipynb b/notebook/Title_Page.ipynb new file mode 100644 index 0000000..260ecab --- /dev/null +++ b/notebook/Title_Page.ipynb @@ -0,0 +1,217 @@ +{ + "cells": [ +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +" \n", +" Title page" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " hspace{-6em} includegraphics[width=0.4textwidth]{openmp-logo.png} " + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " {-0.75in}{0in} Huge textsf{OpenMPApplication ProgrammingInterface}" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +" An optional subtitle can go here: vspace{0.5in}textsf{Examples}vspace{-0.7in} normalsize" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " vspace{1.0in}" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " textbf{Version VER{} -- VERDATE} " + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " vspace{2.3in} \n", +"was 3.0" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Source codes for OpenMP VER{} Examples can be downloaded from https://github.com/OpenMP/Examples/tree/vVER {github}." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " {0pt}{1em}setlength{parskip}{0.25baselineskip}\n", +" Copyright © 1997-2016 OpenMP Architecture Review Board. Permission to copy without fee all or part of this material is granted, provided the OpenMP Architecture Review Board copyright notice and the title of this document appear. Notice is given that copying is by permission of OpenMP Architecture Review Board." + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +" Blank page" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " clearpage thispagestyle{empty} phantom{a} emph{This page intentionally left blank}" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"This working version enacted the following tickets: 180, 295, 299, 342, 381, \n", +"and a few other editorial changes. vfill" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end---" + ] + } +], +"metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } +}, +"nbformat": 4, +"nbformat_minor": 2 +} diff --git a/notebook/openmp-examples.ipynb b/notebook/openmp-examples.ipynb new file mode 100644 index 0000000..b7649f7 --- /dev/null +++ b/notebook/openmp-examples.ipynb @@ -0,0 +1,255 @@ +{ + "cells": [ +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +" Welcome to openmp-examples.tex. \n", +" This is the master LaTex file for the OpenMP Examples document. \n", +" \n", +" The files in this set include: \n", +" \n", +" openmp-examples.tex - this file, the master file \n", +" Makefile - makes the document \n", +" openmp.sty - the main style file \n", +" Title_Page.tex - the title page \n", +" openmplogo.png - the logo \n", +" Introduction_Chapt.tex - unnumbered introductory chapter \n", +" Examples_Chapt.tex - unnumbered chapter \n", +" Examples_Sects.tex - examples \n", +" sources/*.c, *.f - C/C++/Fortran example source files \n", +" \n", +" When editing this file: \n", +" \n", +" 1. To change formatting, appearance, or style, please edit openmp.sty. \n", +" \n", +" 2. Custom commands and macros are defined in openmp.sty. \n", +" \n", +" 3. Be kind to other editors -- keep a consistent style by copying-and-pasting to \n", +" create new content. \n", +" \n", +" 4. We use semantic markup, e.g. (see openmp.sty for a full list): \n", +" `` \n", +" for bold monospace keywords, code, operators, etc. \n", +" __ \n", +" for italic placeholder names, grammar, etc. \n", +" \n", +" 5. Other recommendations: \n", +" Use the convenience macros defined in openmp.sty for the minor headers \n", +" such as Comments, Syntax, etc. \n", +" \n", +" To keep items together on the same page, prefer the use of \n", +" .... Avoid parbox for text blocks as it interrupts line numbering. \n", +" When possible, avoid filbreak, , newpage, clearpage unless that's \n", +" what you mean. Use needspace{} cautiously for troublesome paragraphs. \n", +" \n", +" Avoid absolute lengths and measures in this file; use relative units when possible. \n", +" Vertical space can be relative to baselineskip or ex units. Horizontal space \n", +" can be relative to linewidth or em units. \n", +" \n", +" Prefer emph{} to italicize terminology, e.g.: \n", +" This is a emph{definition}, not a placeholder. \n", +" This is a _var-name_ . \n", +"" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +" The following says letter size, but the style sheet may change the size documentclass[10pt,letterpaper,twoside,makeidx,hidelinks]{scrreprt}" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +" Text to appear in the footer on even-numbered pages: newcommand{VER}{4.5.0} newcommand{VERDATE}{November 2016} newcommand{footerText}{OpenMP Examples Version VER{} - VERDATE}" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +" Unified style sheet for OpenMP documents: input{openmp.sty}" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " pagenumbering{roman} input{Title_Page}" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " setcounter{page}{0} setcounter{tocdepth}{2}" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " {1.3} tableofcontents " + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +" Uncomment the next line to enable line numbering on the main body text: linenumberspagewiselinenumbers" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " newpagepagenumbering{arabic}" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " input{Introduction_Chapt} input{Examples_Chapt}" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " setcounter{chapter}{0} \n", +" start chapter numbering here" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " input{Chap_parallel_execution} input{Examples_ploop} input{Examples_parallel} input{Examples_nthrs_nesting} input{Examples_nthrs_dynamic} input{Examples_fort_do} input{Examples_nowait} input{Examples_collapse} \n", +" linear Clause 475 input{Examples_linear_in_loop} input{Examples_psections} input{Examples_fpriv_sections} input{Examples_single} input{Examples_workshare} input{Examples_master} input{Examples_pra_iterator} input{Examples_set_dynamic_nthrs} input{Examples_get_nthrs}" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " input{Chap_affinity} input{Examples_affinity} input{Examples_affinity_query}" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " input{Chap_tasking} input{Examples_tasking} input{Examples_task_priority} input{Examples_task_dep} input{Examples_taskgroup} input{Examples_taskyield} input{Examples_taskloop}" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " input{Chap_devices} input{Examples_target} input{Examples_target_data} input{Examples_target_unstructured_data} input{Examples_target_update} input{Examples_declare_target} \n", +" Link clause 474 input{Examples_teams} input{Examples_async_target_depend} input{Examples_async_target_with_tasks} \n", +"Title change of 57.1 and 57.2 \n", +"New subsection input{Examples_async_target_nowait} input{Examples_async_target_nowait_depend} input{Examples_array_sections} \n", +" Structure Element in map 487 input{Examples_device} \n", +" MemoryRoutine and Device ptr 473" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " input{Chap_SIMD} input{Examples_SIMD} \n", +" Forward Depend 370 \n", +" simdlen 476 \n", +" simd linear modifier 480" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " input{Chap_synchronization} input{Examples_critical} input{Examples_worksharing_critical} input{Examples_barrier_regions} input{Examples_atomic} input{Examples_atomic_restrict} input{Examples_flush_nolist} input{Examples_ordered} \n", +" Doacross loop 405 input{Examples_doacross} input{Examples_locks} input{Examples_init_lock} input{Examples_init_lock_with_hint} input{Examples_lock_owner} input{Examples_simple_lock} input{Examples_nestable_lock} \n", +" \n", +" LOCK with Hints 478 \n", +" \n", +" Hint Clause xxxxxx (included after init_lock) \n", +" \n", +" Lock routines with hint " + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " input{Chap_data_environment} input{Examples_threadprivate} input{Examples_default_none} input{Examples_private} input{Examples_fort_loopvar} input{Examples_fort_sp_common} input{Examples_fort_sa_private} input{Examples_carrays_fpriv} input{Examples_lastprivate} input{Examples_reduction} \n", +" User UDR 287 \n", +" C array reduction 377 input{Examples_copyin} input{Examples_copyprivate} input{Examples_cpp_reference} \n", +" Fortran 2003 features 482 input{Examples_associate} \n", +"section--> subsection" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " input{Chap_memory_model} input{Examples_mem_model} input{Examples_fort_race}" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " input{Chap_program_control} input{Examples_cond_comp} input{Examples_icv} \n", +" If multi-ifs 471 input{Examples_standalone} input{Examples_cancellation} \n", +" New Section Nested Regions input{Examples_nested_loop} input{Examples_nesting_restrict}" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " setcounter{chapter}{0} \n", +" restart chapter numbering with 'letter A' renewcommand{thechapter}{Alph{chapter}}\n", +" appendix input{History}" + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + }, +{ + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end---" + ] + } +], +"metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } +}, +"nbformat": 4, +"nbformat_minor": 2 +} diff --git a/notebook/tex2notebook.py b/notebook/tex2notebook.py index 6b7515b..8242774 100644 --- a/notebook/tex2notebook.py +++ b/notebook/tex2notebook.py @@ -326,3 +326,7 @@ def replace_example(Str): f.write(E2) f.write(LanguageSet) + os.remove(testfile) + +os.remove('MyList.txt') + From f7eb9be1e2c9b5eee9170c23a239c3e9a43cf441 Mon Sep 17 00:00:00 2001 From: Kewei Yan Date: Tue, 8 Oct 2019 11:38:38 -0400 Subject: [PATCH 08/21] test2 --- notebook/Chap_SIMD.ipynb | 72 +- notebook/Chap_affinity.ipynb | 154 +-- notebook/Chap_data_environment.ipynb | 148 +-- notebook/Chap_devices.ipynb | 90 +- notebook/Chap_memory_model.ipynb | 92 +- notebook/Chap_parallel_execution.ipynb | 206 ++-- notebook/Chap_program_control.ipynb | 176 +-- notebook/Chap_synchronization.ipynb | 104 +- notebook/Chap_tasking.ipynb | 82 +- notebook/Examples_Chapt.ipynb | 42 +- notebook/Examples_SIMD.ipynb | 454 ++++---- notebook/Examples_affinity.ipynb | 1022 ++++++++--------- notebook/Examples_affinity_query.ipynb | 98 +- notebook/Examples_array_sections.ipynb | 182 +-- notebook/Examples_associate.ipynb | 112 +- notebook/Examples_async_target_depend.ipynb | 50 +- notebook/Examples_async_target_nowait.ipynb | 88 +- .../Examples_async_target_nowait_depend.ipynb | 92 +- .../Examples_async_target_with_tasks.ipynb | 156 +-- notebook/Examples_atomic.ipynb | 154 +-- notebook/Examples_atomic_restrict.ipynb | 130 +-- notebook/Examples_barrier_regions.ipynb | 78 +- notebook/Examples_cancellation.ipynb | 116 +- notebook/Examples_carrays_fpriv.ipynb | 156 +-- notebook/Examples_collapse.ipynb | 194 ++-- notebook/Examples_cond_comp.ipynb | 88 +- notebook/Examples_copyin.ipynb | 58 +- notebook/Examples_copyprivate.ipynb | 174 +-- notebook/Examples_cpp_reference.ipynb | 72 +- notebook/Examples_critical.ipynb | 96 +- notebook/Examples_declare_target.ipynb | 456 ++++---- notebook/Examples_default_none.ipynb | 78 +- notebook/Examples_device.ipynb | 228 ++-- notebook/Examples_doacross.ipynb | 182 +-- notebook/Examples_flush_nolist.ipynb | 58 +- notebook/Examples_fort_do.ipynb | 88 +- notebook/Examples_fort_loopvar.ipynb | 88 +- notebook/Examples_fort_race.ipynb | 64 +- notebook/Examples_fort_sa_private.ipynb | 132 +-- notebook/Examples_fort_sp_common.ipynb | 182 +-- notebook/Examples_fpriv_sections.ipynb | 58 +- notebook/Examples_get_nthrs.ipynb | 96 +- notebook/Examples_icv.ipynb | 138 +-- notebook/Examples_init_lock.ipynb | 58 +- notebook/Examples_init_lock_with_hint.ipynb | 60 +- notebook/Examples_lastprivate.ipynb | 58 +- notebook/Examples_linear_in_loop.ipynb | 58 +- notebook/Examples_lock_owner.ipynb | 68 +- notebook/Examples_locks.ipynb | 30 +- notebook/Examples_master.ipynb | 58 +- notebook/Examples_mem_model.ipynb | 144 +-- notebook/Examples_nestable_lock.ipynb | 58 +- notebook/Examples_nested_loop.ipynb | 96 +- notebook/Examples_nesting_restrict.ipynb | 320 +++--- notebook/Examples_nowait.ipynb | 106 +- notebook/Examples_nthrs_dynamic.ipynb | 116 +- notebook/Examples_nthrs_nesting.ipynb | 58 +- notebook/Examples_ordered.ipynb | 134 +-- notebook/Examples_parallel.ipynb | 58 +- notebook/Examples_ploop.ipynb | 58 +- notebook/Examples_pra_iterator.ipynb | 72 +- notebook/Examples_private.ipynb | 138 +-- notebook/Examples_psections.ipynb | 58 +- notebook/Examples_reduction.ipynb | 320 +++--- notebook/Examples_set_dynamic_nthrs.ipynb | 78 +- notebook/Examples_simple_lock.ipynb | 78 +- notebook/Examples_single.ipynb | 58 +- notebook/Examples_standalone.ipynb | 126 +- notebook/Examples_target.ipynb | 394 +++---- notebook/Examples_target_data.ipynb | 476 ++++---- .../Examples_target_unstructured_data.ipynb | 148 +-- notebook/Examples_target_update.ipynb | 196 ++-- notebook/Examples_task_dep.ipynb | 300 ++--- notebook/Examples_task_priority.ipynb | 80 +- notebook/Examples_taskgroup.ipynb | 68 +- notebook/Examples_tasking.ipynb | 698 +++++------ notebook/Examples_taskloop.ipynb | 60 +- notebook/Examples_taskyield.ipynb | 58 +- notebook/Examples_teams.ipynb | 428 +++---- notebook/Examples_threadprivate.ipynb | 400 +++---- notebook/Examples_workshare.ipynb | 262 ++--- notebook/Examples_worksharing_critical.ipynb | 58 +- notebook/History.ipynb | 118 +- notebook/Introduction_Chapt.ipynb | 126 +- notebook/Title_Page.ipynb | 152 +-- notebook/openmp-examples.ipynb | 256 ++--- notebook/tex2notebook.py | 28 +- 87 files changed, 6678 insertions(+), 6678 deletions(-) diff --git a/notebook/Chap_SIMD.ipynb b/notebook/Chap_SIMD.ipynb index 158dc56..f453edd 100644 --- a/notebook/Chap_SIMD.ipynb +++ b/notebook/Chap_SIMD.ipynb @@ -1,58 +1,58 @@ { "cells": [ -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ## SIMD" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ## SIMD " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Single instruction, multiple data (SIMD) is a form of parallel execution in which the same operation is performed on multiple data elements independently in hardware vector processing units (VPU), also called SIMD units. The addition of two vectors to form a third vector is a SIMD operation. Many processors have SIMD (vector) units that can perform simultaneously 2, 4, 8 or more executions of the same operation (by a single SIMD unit). " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Single instruction, multiple data (SIMD) is a form of parallel execution in which the same operation is performed on multiple data elements independently in hardware vector processing units (VPU), also called SIMD units. The addition of two vectors to form a third vector is a SIMD operation. Many processors have SIMD (vector) units that can perform simultaneously 2, 4, 8 or more executions of the same operation (by a single SIMD unit). " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Loops without loop-carried backward dependency (or with dependency preserved using ordered simd) are candidates for vectorization by the compiler for execution with SIMD units. In addition, with state-of-the-art vectorization technology and `declare simd` construct extensions for function vectorization in the OpenMP 4.5 specification, loops with function calls can be vectorized as well. The basic idea is that a scalar function call in a loop can be replaced by a vector version of the function, and the loop can be vectorized simultaneously by combining a loop vectorization ( `simd` directive on the loop) and a function vectorization ( `declare simd` directive on the function)." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Loops without loop-carried backward dependency (or with dependency preserved using ordered simd) are candidates for vectorization by the compiler for execution with SIMD units. In addition, with state-of-the-art vectorization technology and `declare simd` construct extensions for function vectorization in the OpenMP 4.5 specification, loops with function calls can be vectorized as well. The basic idea is that a scalar function call in a loop can be replaced by a vector version of the function, and the loop can be vectorized simultaneously by combining a loop vectorization ( `simd` directive on the loop) and a function vectorization ( `declare simd` directive on the function). " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " A `simd` construct states that SIMD operations be performed on the data within the loop. A number of clauses are available to provide data-sharing attributes ( `private` , `linear` , `reduction` and `lastprivate` ). Other clauses provide vector length preference/restrictions ( `simdlen` / `safelen` ), loop fusion ( `collapse` ), and data alignment ( `aligned` )." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " A `simd` construct states that SIMD operations be performed on the data within the loop. A number of clauses are available to provide data-sharing attributes ( `private` , `linear` , `reduction` and `lastprivate` ). Other clauses provide vector length preference/restrictions ( `simdlen` / `safelen` ), loop fusion ( `collapse` ), and data alignment ( `aligned` ). " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `declare simd` directive designates that a vector version of the function should also be constructed for execution within loops that contain the function and have a `simd` directive. Clauses provide argument specifications ( `linear` , `uniform` , and `aligned` ), a requested vector length ( `simdlen` ), and designate whether the function is always/never called conditionally in a loop ( `branch` / `inbranch` ). The latter is for optimizing peformance." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `declare simd` directive designates that a vector version of the function should also be constructed for execution within loops that contain the function and have a `simd` directive. Clauses provide argument specifications ( `linear` , `uniform` , and `aligned` ), a requested vector length ( `simdlen` ), and designate whether the function is always/never called conditionally in a loop ( `branch` / `inbranch` ). The latter is for optimizing peformance. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Also, the `simd` construct has been combined with the worksharing loop constructs ( `for simd` and `do simd` ) to enable simultaneous thread execution in different SIMD units. \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Also, the `simd` construct has been combined with the worksharing loop constructs ( `for simd` and `do simd` ) to enable simultaneous thread execution in different SIMD units. \n", "Hence, the `simd` construct can be \n", "used alone on a loop to direct vectorization (SIMD execution), or in \n", "combination with a parallel loop construct to include thread parallelism \n", "(a parallel loop sequentially followed by a `simd` construct, \n", "or a combined construct such as `parallel do simd` or \n", -" `parallel for simd` )." +" `parallel for simd` ). " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Chap_affinity.ipynb b/notebook/Chap_affinity.ipynb index 8a20a81..f965bf0 100644 --- a/notebook/Chap_affinity.ipynb +++ b/notebook/Chap_affinity.ipynb @@ -1,95 +1,95 @@ { "cells": [ -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ## OpenMP Affinity" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ## OpenMP Affinity " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " OpenMP Affinity consists of a `proc_bind` policy (thread affinity policy) and a specification of places ( ' location units ' or _processors_ that may be cores, hardware threads, sockets, etc.). OpenMP Affinity enables users to bind computations on specific places. The placement will hold for the duration of the parallel region. However, the runtime is free to migrate the OpenMP threads to different cores (hardware threads, sockets, etc.) prescribed within a given place, if two or more cores (hardware threads, sockets, etc.) have been assigned to a given place." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " OpenMP Affinity consists of a `proc_bind` policy (thread affinity policy) and a specification of places ( ' location units ' or _processors_ that may be cores, hardware threads, sockets, etc.). OpenMP Affinity enables users to bind computations on specific places. The placement will hold for the duration of the parallel region. However, the runtime is free to migrate the OpenMP threads to different cores (hardware threads, sockets, etc.) prescribed within a given place, if two or more cores (hardware threads, sockets, etc.) have been assigned to a given place. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Often the binding can be managed without resorting to explicitly setting places. Without the specification of places in the `OMP_PLACES` variable, the OpenMP runtime will distribute and bind threads using the entire range of processors for the OpenMP program, according to the `OMP_PROC_BIND` environment variable or the `proc_bind` clause. When places are specified, the OMP runtime binds threads to the places according to a default distribution policy, or those specified in the `OMP_PROC_BIND` environment variable or the `proc_bind` clause." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Often the binding can be managed without resorting to explicitly setting places. Without the specification of places in the `OMP_PLACES` variable, the OpenMP runtime will distribute and bind threads using the entire range of processors for the OpenMP program, according to the `OMP_PROC_BIND` environment variable or the `proc_bind` clause. When places are specified, the OMP runtime binds threads to the places according to a default distribution policy, or those specified in the `OMP_PROC_BIND` environment variable or the `proc_bind` clause. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the OpenMP Specifications document a processor refers to an execution unit that is enabled for an OpenMP thread to use. A processor is a core when there is no SMT (Simultaneous Multi-Threading) support or SMT is disabled. When SMT is enabled, a processor is a hardware thread (HW-thread). (This is the usual case; but actually, the execution unit is implementation defined.) Processor numbers are numbered sequentially from 0 to the number of cores less one (without SMT), or 0 to the number HW-threads less one (with SMT). OpenMP places use the processor number to designate binding locations (unless an ' abstract name ' is used.) " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the OpenMP Specifications document a processor refers to an execution unit that is enabled for an OpenMP thread to use. A processor is a core when there is no SMT (Simultaneous Multi-Threading) support or SMT is disabled. When SMT is enabled, a processor is a hardware thread (HW-thread). (This is the usual case; but actually, the execution unit is implementation defined.) Processor numbers are numbered sequentially from 0 to the number of cores less one (without SMT), or 0 to the number HW-threads less one (with SMT). OpenMP places use the processor number to designate binding locations (unless an ' abstract name ' is used.) " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The processors available to a process may be a subset of the system's processors. This restriction may be the result of a wrapper process controlling the execution (such as `numactl` on Linux systems), compiler options, library-specific environment variables, or default kernel settings. For instance, the execution of multiple MPI processes, launched on a single compute node, will each have a subset of processors as determined by the MPI launcher or set by MPI affinity environment variables for the MPI library. \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The processors available to a process may be a subset of the system's processors. This restriction may be the result of a wrapper process controlling the execution (such as `numactl` on Linux systems), compiler options, library-specific environment variables, or default kernel settings. For instance, the execution of multiple MPI processes, launched on a single compute node, will each have a subset of processors as determined by the MPI launcher or set by MPI affinity environment variables for the MPI library. \n", "Forked threads within an MPI process \n", "(for a hybrid execution of MPI and OpenMP code) inherit the valid \n", "processor set for execution from the parent process (the initial task region) \n", "when a parallel region forks threads. The binding policy set in \n", " `OMP_PROC_BIND` or the `proc_bind` clause will be applied to \n", -"the subset of processors available to _the particular_ MPI process." +"the subset of processors available to _the particular_ MPI process. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", "Also, setting an explicit list of processor numbers in the `OMP_PLACES` \n", "variable before an MPI launch (which involves more than one MPI process) will \n", "result in unspecified behavior (and doesn't make sense) because the set of \n", "processors in the places list must not contain processors outside the subset \n", "of processors for an MPI process. A separate `OMP_PLACES` variable must \n", "be set for each MPI process, and is usually accomplished by launching a script \n", -"which sets `OMP_PLACES` specifically for the MPI process. " +"which sets `OMP_PLACES` specifically for the MPI process. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Threads of a team are positioned onto places in a compact manner, a scattered distribution, or onto the master's place, by setting the `OMP_PROC_BIND` environment variable or the `proc_bind` clause to _close_ , _spread_ , or _master_ , respectively. When `OMP_PROC_BIND` is set to FALSE no binding is enforced; and when the value is TRUE, the binding is implementation defined to a set of places in the `OMP_PLACES` variable or to places defined by the implementation if the `OMP_PLACES` variable is not set." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Threads of a team are positioned onto places in a compact manner, a scattered distribution, or onto the master's place, by setting the `OMP_PROC_BIND` environment variable or the `proc_bind` clause to _close_ , _spread_ , or _master_ , respectively. When `OMP_PROC_BIND` is set to FALSE no binding is enforced; and when the value is TRUE, the binding is implementation defined to a set of places in the `OMP_PLACES` variable or to places defined by the implementation if the `OMP_PLACES` variable is not set. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `OMP_PLACES` variable can also be set to an abstract name ( _threads_ , _cores_ , _sockets_ ) to specify that a place is either a single hardware thread, a core, or a socket, respectively. This description of the `OMP_PLACES` is most useful when the number of threads is equal to the number of hardware thread, cores or sockets. It can also be used with a _close_ or _spread_ distribution policy when the equality doesn't hold." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `OMP_PLACES` variable can also be set to an abstract name ( _threads_ , _cores_ , _sockets_ ) to specify that a place is either a single hardware thread, a core, or a socket, respectively. This description of the `OMP_PLACES` is most useful when the number of threads is equal to the number of hardware thread, cores or sockets. It can also be used with a _close_ or _spread_ distribution policy when the equality doesn't hold. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -" We need an example of using sockets, cores and threads:" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +" We need an example of using sockets, cores and threads: " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -" case 1 cores:" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +" case 1 cores: " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", " Hyper-Threads on (2 hardware threads per core) \n", " 1 socket x 4 cores x 2 HW-threads \n", " \n", @@ -101,14 +101,14 @@ " thread # 0 * _ _ _ _ _ _ _ #mask for thread 0 \n", " thread # 1 _ _ * _ _ _ _ _ #mask for thread 1 \n", " thread # 2 _ _ _ _ * _ _ _ #mask for thread 2 \n", -" thread # 3 _ _ _ _ _ _ * _ #mask for thread 3" +" thread # 3 _ _ _ _ _ _ * _ #mask for thread 3 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", " case 2 threads: \n", " \n", " Hyper-Threads on (2 hardware threads per core) \n", @@ -122,14 +122,14 @@ " thread # 0 * * _ _ _ _ _ _ #mask for thread 0 \n", " thread # 1 _ _ * * _ _ _ _ #mask for thread 1 \n", " thread # 2 _ _ _ _ * * _ _ #mask for thread 2 \n", -" thread # 3 _ _ _ _ _ _ * * #mask for thread 3" +" thread # 3 _ _ _ _ _ _ * * #mask for thread 3 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", " case 3 sockets: \n", " \n", " No Hyper-Threads \n", @@ -142,14 +142,14 @@ " processor # 0,1,2,3 4,5,6,7 8,9,10,11 \n", " thread # 0 * * * * _ _ _ _ _ _ _ _ #mask for thread 0 \n", " thread # 0 _ _ _ _ * * * * _ _ _ _ #mask for thread 1 \n", -" thread # 0 _ _ _ _ _ _ _ _ * * * * #mask for thread 2" +" thread # 0 _ _ _ _ _ _ _ _ * * * * #mask for thread 2 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Chap_data_environment.ipynb b/notebook/Chap_data_environment.ipynb index a96a244..4d9cb4a 100644 --- a/notebook/Chap_data_environment.ipynb +++ b/notebook/Chap_data_environment.ipynb @@ -1,106 +1,106 @@ { "cells": [ -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ## Data Environment" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ## Data Environment " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The OpenMP _data environment_ contains data attributes of variables and objects. Many constructs (such as `parallel` , `simd` , `task` ) accept clauses to control _data-sharing_ attributes of referenced variables in the construct, where _data-sharing_ applies to whether the attribute of the variable is _shared_ , is _private_ storage, or has special operational characteristics (as found in the `firstprivate` , `lastprivate` , `linear` , or `reduction` clause)." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The OpenMP _data environment_ contains data attributes of variables and objects. Many constructs (such as `parallel` , `simd` , `task` ) accept clauses to control _data-sharing_ attributes of referenced variables in the construct, where _data-sharing_ applies to whether the attribute of the variable is _shared_ , is _private_ storage, or has special operational characteristics (as found in the `firstprivate` , `lastprivate` , `linear` , or `reduction` clause). " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The data environment for a device (distinguished as a _device data environment_ ) is controlled on the host by _data-mapping_ attributes, which determine the relationship of the data on the host, the _original_ data, and the data on the device, the _corresponding_ data." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The data environment for a device (distinguished as a _device data environment_ ) is controlled on the host by _data-mapping_ attributes, which determine the relationship of the data on the host, the _original_ data, and the data on the device, the _corresponding_ data. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " bigskip DATA-SHARING ATTRIBUTES" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " bigskip DATA-SHARING ATTRIBUTES " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Data-sharing attributes of variables can be classified as being _predetermined_ , _explicitly determined_ or _implicitly determined_ ." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Data-sharing attributes of variables can be classified as being _predetermined_ , _explicitly determined_ or _implicitly determined_ . " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Certain variables and objects have predetermined attributes. A commonly found case is the loop iteration variable in associated loops of a `for` or `do` construct. It has a private data-sharing attribute. Variables with predetermined data-sharing attributes can not be listed in a data-sharing clause; but there are some exceptions (mainly concerning loop iteration variables)." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Certain variables and objects have predetermined attributes. A commonly found case is the loop iteration variable in associated loops of a `for` or `do` construct. It has a private data-sharing attribute. Variables with predetermined data-sharing attributes can not be listed in a data-sharing clause; but there are some exceptions (mainly concerning loop iteration variables). " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Variables with explicitly determined data-sharing attributes are those that are referenced in a given construct and are listed in a data-sharing attribute clause on the construct. Some of the common data-sharing clauses are: `shared` , `private` , `firstprivate` , `lastprivate` , `linear` , and `reduction` . \n", -" Are these all of them?" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Variables with explicitly determined data-sharing attributes are those that are referenced in a given construct and are listed in a data-sharing attribute clause on the construct. Some of the common data-sharing clauses are: `shared` , `private` , `firstprivate` , `lastprivate` , `linear` , and `reduction` . \n", +" Are these all of them? " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Variables with implicitly determined data-sharing attributes are those that are referenced in a given construct, do not have predetermined data-sharing attributes, and are not listed in a data-sharing attribute clause of an enclosing construct. For a complete list of variables and objects with predetermined and implicitly determined attributes, please refer to the _Data-sharing Attribute Rules for Variables Referenced in a Construct_ subsection of the OpenMP Specifications document. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Variables with implicitly determined data-sharing attributes are those that are referenced in a given construct, do not have predetermined data-sharing attributes, and are not listed in a data-sharing attribute clause of an enclosing construct. For a complete list of variables and objects with predetermined and implicitly determined attributes, please refer to the _Data-sharing Attribute Rules for Variables Referenced in a Construct_ subsection of the OpenMP Specifications document. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " bigskip DATA-MAPPING ATTRIBUTES" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " bigskip DATA-MAPPING ATTRIBUTES " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `map` clause on a device construct explictly specifies how the list items in the clause are mapped from the encountering task's data environment (on the host) to the corresponding \n", -"* in the device data environment (on the device). The common _list items_ are arrays, array sections, scalars, pointers, and structure elements (members). " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `map` clause on a device construct explictly specifies how the list items in the clause are mapped from the encountering task's data environment (on the host) to the corresponding \n", +"* in the device data environment (on the device). The common _list items_ are arrays, array sections, scalars, pointers, and structure elements (members). " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Procedures and global variables have predetermined data mapping if they appear within the list or block of a `declare target` directive. Also, a C/C++ pointer is mapped as a zero-length array section, as is a C++ variable that is a reference to a pointer. \n", -" Waiting for response from Eric on this." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Procedures and global variables have predetermined data mapping if they appear within the list or block of a `declare target` directive. Also, a C/C++ pointer is mapped as a zero-length array section, as is a C++ variable that is a reference to a pointer. \n", +" Waiting for response from Eric on this. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Without explict mapping, non-scalar and non-pointer variables within the scope of the `target` construct are implicitly mapped with a _map-type_ of `tofrom` . Without explicit mapping, scalar variables within the scope of the `target` construct are not mapped, but have an implicit firstprivate data-sharing attribute. (That is, the value of the original variable is given to a private variable of the same name on the device.) This behavior can be changed with the `defaultmap` clause." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Without explict mapping, non-scalar and non-pointer variables within the scope of the `target` construct are implicitly mapped with a _map-type_ of `tofrom` . Without explicit mapping, scalar variables within the scope of the `target` construct are not mapped, but have an implicit firstprivate data-sharing attribute. (That is, the value of the original variable is given to a private variable of the same name on the device.) This behavior can be changed with the `defaultmap` clause. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `map` clause can appear on `target` , `target data` and `target enter/exit data` constructs. The operations of creation and removal of device storage as well as assignment of the original list \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `map` clause can appear on `target` , `target data` and `target enter/exit data` constructs. The operations of creation and removal of device storage as well as assignment of the original list \n", "* values to the corresponding list items may be complicated when the list \n", -"* appears on multiple constructs or when the host and device storage is shared. In these cases the item's reference count, the number of times it has been referenced (+1 on entry and -1 on exited) in nested (structured) map regions and/or accumulative (unstructured) mappings, determines the operation. Details of the `map` clause and reference count operation are specified in the _map Clause_ subsection of the OpenMP Specifications document." +"* appears on multiple constructs or when the host and device storage is shared. In these cases the item's reference count, the number of times it has been referenced (+1 on entry and -1 on exited) in nested (structured) map regions and/or accumulative (unstructured) mappings, determines the operation. Details of the `map` clause and reference count operation are specified in the _map Clause_ subsection of the OpenMP Specifications document. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Chap_devices.ipynb b/notebook/Chap_devices.ipynb index 266aa16..e0d8cdc 100644 --- a/notebook/Chap_devices.ipynb +++ b/notebook/Chap_devices.ipynb @@ -1,66 +1,66 @@ { "cells": [ -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ## Devices" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ## Devices " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `target` construct consists of a `target` directive and an execution region. The `target` region is executed on the default device or the device specified in the `device` clause. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `target` construct consists of a `target` directive and an execution region. The `target` region is executed on the default device or the device specified in the `device` clause. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In OpenMP version 4.0, by default, all variables within the lexical scope of the construct are copied _to_ and _from_ the device, unless the device is the host, or the data exists on the device from a previously executed data-type construct that has created space on the device and possibly copied host data to the device storage." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In OpenMP version 4.0, by default, all variables within the lexical scope of the construct are copied _to_ and _from_ the device, unless the device is the host, or the data exists on the device from a previously executed data-type construct that has created space on the device and possibly copied host data to the device storage. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The constructs that explicitly create storage, transfer data, and free storage on the device are catagorized as structured and unstructured. The `target` `data` construct is structured. It creates a data region around `target` constructs, and is convenient for providing persistent data throughout multiple `target` regions. The `target` `enter` `data` and `target` `exit` `data` constructs are unstructured, because they can occur anywhere and do not support a 'structure' (a region) for enclosing `target` constructs, as does the `target` `data` construct. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The constructs that explicitly create storage, transfer data, and free storage on the device are catagorized as structured and unstructured. The `target` `data` construct is structured. It creates a data region around `target` constructs, and is convenient for providing persistent data throughout multiple `target` regions. The `target` `enter` `data` and `target` `exit` `data` constructs are unstructured, because they can occur anywhere and do not support a 'structure' (a region) for enclosing `target` constructs, as does the `target` `data` construct. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `map` clause is used on `target` constructs and the data-type constructs to map host data. It specifies the device storage and data movement `to` and `from` the device, and controls on the storage duration." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `map` clause is used on `target` constructs and the data-type constructs to map host data. It specifies the device storage and data movement `to` and `from` the device, and controls on the storage duration. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " There is an important change in the OpenMP 4.5 specification that alters the data model for scalar variables and C/C++ pointer variables. The default behavior for scalar variables and C/C++ pointer variables in an 4.5 compliant code is `firstprivate` . Example codes that have been updated to reflect this new behavior are annotated with a description that describes changes required for correct execution. Often it is a simple matter of mapping the variable as `tofrom` to obtain the intended 4.0 behavior." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " There is an important change in the OpenMP 4.5 specification that alters the data model for scalar variables and C/C++ pointer variables. The default behavior for scalar variables and C/C++ pointer variables in an 4.5 compliant code is `firstprivate` . Example codes that have been updated to reflect this new behavior are annotated with a description that describes changes required for correct execution. Often it is a simple matter of mapping the variable as `tofrom` to obtain the intended 4.0 behavior. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In OpenMP version 4.5 the mechanism for target execution is specified as occuring through a _target task_ . When the `target` construct is encountered a new _target task_ is generated. The _target task_ completes after the `target` region has executed and all data transfers have finished." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In OpenMP version 4.5 the mechanism for target execution is specified as occuring through a _target task_ . When the `target` construct is encountered a new _target task_ is generated. The _target task_ completes after the `target` region has executed and all data transfers have finished. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " This new specification does not affect the execution of pre-4.5 code; it is a necessary element for asynchronous execution of the `target` region when using the new `nowait` clause introduced in OpenMP 4.5." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " This new specification does not affect the execution of pre-4.5 code; it is a necessary element for asynchronous execution of the `target` region when using the new `nowait` clause introduced in OpenMP 4.5. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Chap_memory_model.ipynb b/notebook/Chap_memory_model.ipynb index 2289b84..0dc5d90 100644 --- a/notebook/Chap_memory_model.ipynb +++ b/notebook/Chap_memory_model.ipynb @@ -1,52 +1,52 @@ { "cells": [ -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ## Memory Model" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ## Memory Model " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In this chapter, examples illustrate race conditions on access to variables with shared data-sharing attributes. A race condition can exist when two or more threads are involved in accessing a variable in which not all of the accesses are reads; that is, a WaR, RaW or WaW condition exists (R=read, a=after, W=write). A RaR does not produce a race condition. Ensuring thread execution order at the processor level is not enough to avoid race conditions, because the local storage at the processor level (registers, caches, etc.) must be synchronized so that a consistent view of the variable in the memory hierarchy can be seen by the threads accessing the variable." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In this chapter, examples illustrate race conditions on access to variables with shared data-sharing attributes. A race condition can exist when two or more threads are involved in accessing a variable in which not all of the accesses are reads; that is, a WaR, RaW or WaW condition exists (R=read, a=after, W=write). A RaR does not produce a race condition. Ensuring thread execution order at the processor level is not enough to avoid race conditions, because the local storage at the processor level (registers, caches, etc.) must be synchronized so that a consistent view of the variable in the memory hierarchy can be seen by the threads accessing the variable. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " OpenMP provides a shared-memory model which allows all threads access to _memory_ (shared data). Each thread also has exclusive access to _threadprivate memory_ (private data). A private variable referenced in an OpenMP directive's structured block is a new version of the original variable (with the same name) for each task (or SIMD lane) within the code block. A private variable is initially undefined (except for variables in `firstprivate` and `linear` clauses), and the original variable value is unaltered by assignments to the private variable, (except for `reduction` , `lastprivate` and `linear` clauses)." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " OpenMP provides a shared-memory model which allows all threads access to _memory_ (shared data). Each thread also has exclusive access to _threadprivate memory_ (private data). A private variable referenced in an OpenMP directive's structured block is a new version of the original variable (with the same name) for each task (or SIMD lane) within the code block. A private variable is initially undefined (except for variables in `firstprivate` and `linear` clauses), and the original variable value is unaltered by assignments to the private variable, (except for `reduction` , `lastprivate` and `linear` clauses). " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Private variables in an outer `parallel` region can be shared by implicit tasks of an inner `parallel` region (with a `share` clause on the inner `parallel` directive). Likewise, a private variable may be shared in the region of an explicit `task` (through a `shared` clause)." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Private variables in an outer `parallel` region can be shared by implicit tasks of an inner `parallel` region (with a `share` clause on the inner `parallel` directive). Likewise, a private variable may be shared in the region of an explicit `task` (through a `shared` clause). " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `flush` directive forces a consistent view of local variables of the thread executing the `flush` . When a list is supplied on the directive, only the items (variables) in the list are guaranteed to be flushed." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `flush` directive forces a consistent view of local variables of the thread executing the `flush` . When a list is supplied on the directive, only the items (variables) in the list are guaranteed to be flushed. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Implied flushes exist at prescribed locations of certain constructs. For the complete list of these locations and associated constructs, please refer to the _flush Construct_ section of the OpenMP Specifications document." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Implied flushes exist at prescribed locations of certain constructs. For the complete list of these locations and associated constructs, please refer to the _flush Construct_ section of the OpenMP Specifications document. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", " The following table lists construct in which implied flushes exist, and the \n", " location of their execution. \n", " \n", @@ -111,21 +111,21 @@ " ( `atomic` directive without a `seq_cst` clause), where the list \n", "* is the \n", " specific storage location accessed atomically (specified as the _x_ variable \n", -" in _atomic Construct_ subsection of the OpenMP Specifications document)." +" in _atomic Construct_ subsection of the OpenMP Specifications document). " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Examples 1-3 show the difficulty of synchronizing threads through `flush` and `atomic` directives." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Examples 1-3 show the difficulty of synchronizing threads through `flush` and `atomic` directives. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Chap_parallel_execution.ipynb b/notebook/Chap_parallel_execution.ipynb index 2252786..34b0ff6 100644 --- a/notebook/Chap_parallel_execution.ipynb +++ b/notebook/Chap_parallel_execution.ipynb @@ -1,150 +1,150 @@ { "cells": [ -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ## Parallel Execution" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ## Parallel Execution " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " A single thread, the _initial thread_ , begins sequential execution of an OpenMP enabled program, as if the whole program is in an implicit parallel region consisting of an implicit task executed by the _initial thread_ ." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " A single thread, the _initial thread_ , begins sequential execution of an OpenMP enabled program, as if the whole program is in an implicit parallel region consisting of an implicit task executed by the _initial thread_ . " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " A `parallel` construct encloses code, forming a parallel region. An _initial thread_ encountering a `parallel` region forks (creates) a team of threads at the beginning of the `parallel` region, and joins them (removes from execution) at the end of the region. The initial thread becomes the master thread of the team in a `parallel` region with a _thread_ number equal to zero, the other threads are numbered from 1 to number of threads minus 1. A team may be comprised of just a single thread." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " A `parallel` construct encloses code, forming a parallel region. An _initial thread_ encountering a `parallel` region forks (creates) a team of threads at the beginning of the `parallel` region, and joins them (removes from execution) at the end of the region. The initial thread becomes the master thread of the team in a `parallel` region with a _thread_ number equal to zero, the other threads are numbered from 1 to number of threads minus 1. A team may be comprised of just a single thread. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Each thread of a team is assigned an implicit task consisting of code within the parallel region. The task that creates a parallel region is suspended while the tasks of the team are executed. A thread is tied to its task; that is, only the thread assigned to the task can execute that task. After completion of the `parallel` region, the master thread resumes execution of the generating task. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Each thread of a team is assigned an implicit task consisting of code within the parallel region. The task that creates a parallel region is suspended while the tasks of the team are executed. A thread is tied to its task; that is, only the thread assigned to the task can execute that task. After completion of the `parallel` region, the master thread resumes execution of the generating task. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", "After the `parallel` region the master thread becomes the initial \n", -"thread again, and continues to execute the _sequential part_ . " +"thread again, and continues to execute the _sequential part_ . " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Any task within a `parallel` region is allowed to encounter another `parallel` region to form a nested `parallel` region. The parallelism of a nested `parallel` region (whether it forks additional threads, or is executed serially by the encountering task) can be controlled by the `OMP_NESTED` environment variable or the `omp_set_nested()` API routine with arguments indicating true or false." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Any task within a `parallel` region is allowed to encounter another `parallel` region to form a nested `parallel` region. The parallelism of a nested `parallel` region (whether it forks additional threads, or is executed serially by the encountering task) can be controlled by the `OMP_NESTED` environment variable or the `omp_set_nested()` API routine with arguments indicating true or false. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The number of threads of a `parallel` region can be set by the `OMP_NUM_THREADS` environment variable, the `omp_set_num_threads()` routine, or on the `parallel` directive with the `num_threads` clause. The routine overrides the environment variable, and the clause overrides all. Use the `OMP_DYNAMIC` or the `omp_set_dynamic()` function to specify that the OpenMP implementation dynamically adjust the number of threads for `parallel` regions. The default setting for dynamic adjustment is implementation defined. When dynamic adjustment is on and the number of threads is specified, the number of threads becomes an upper limit for the number of threads to be provided by the OpenMP runtime." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The number of threads of a `parallel` region can be set by the `OMP_NUM_THREADS` environment variable, the `omp_set_num_threads()` routine, or on the `parallel` directive with the `num_threads` clause. The routine overrides the environment variable, and the clause overrides all. Use the `OMP_DYNAMIC` or the `omp_set_dynamic()` function to specify that the OpenMP implementation dynamically adjust the number of threads for `parallel` regions. The default setting for dynamic adjustment is implementation defined. When dynamic adjustment is on and the number of threads is specified, the number of threads becomes an upper limit for the number of threads to be provided by the OpenMP runtime. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " WORKSHARING CONSTRUCTS" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " WORKSHARING CONSTRUCTS " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " A worksharing construct distributes the execution of the associated region among the members of the team that encounter it. There is an implied barrier at the end of the worksharing region (there is no barrier at the beginning). The worksharing constructs are:" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " A worksharing construct distributes the execution of the associated region among the members of the team that encounter it. There is an implied barrier at the end of the worksharing region (there is no barrier at the beginning). The worksharing constructs are: " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", "* loop constructs: { `for` and `do` } \n", "* `sections` \n", "* `single` \n", -"* `workshare` " +"* `workshare` " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `for` and `do` constructs (loop constructs) create a region consisting of a loop. A loop controlled by a loop construct is called an _associated_ loop. Nested loops can form a single region when the `collapse` clause (with an integer argument) designates the number of _associated_ loops to be executed in parallel, by forming a 'single iteration space' for the specified number of nested loops. The `ordered` clause can also control multiple associated loops." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `for` and `do` constructs (loop constructs) create a region consisting of a loop. A loop controlled by a loop construct is called an _associated_ loop. Nested loops can form a single region when the `collapse` clause (with an integer argument) designates the number of _associated_ loops to be executed in parallel, by forming a 'single iteration space' for the specified number of nested loops. The `ordered` clause can also control multiple associated loops. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " An associated loop must adhere to a 'canonical form' (specified in the _Canonical Loop Form_ of the OpenMP Specifications document) which allows the iteration count (of all associated loops) to be computed before the (outermost) loop is executed. \n", -"[58:27-29]. Most common loops comply with the canonical form, including C++ iterators." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " An associated loop must adhere to a 'canonical form' (specified in the _Canonical Loop Form_ of the OpenMP Specifications document) which allows the iteration count (of all associated loops) to be computed before the (outermost) loop is executed. \n", +"[58:27-29]. Most common loops comply with the canonical form, including C++ iterators. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " A `single` construct forms a region in which only one thread (any one of the team) executes the region. The other threads wait at the implied barrier at the end, unless the `nowait` clause is specified." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " A `single` construct forms a region in which only one thread (any one of the team) executes the region. The other threads wait at the implied barrier at the end, unless the `nowait` clause is specified. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `sections` construct forms a region that contains one or more structured blocks. Each block of a `sections` directive is constructed with a `section` construct, and executed once by one of the threads (any one) in the team. (If only one block is formed in the region, the `section` construct, which is used to separate blocks, is not required.) The other threads wait at the implied barrier at the end, unless the `nowait` clause is specified." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `sections` construct forms a region that contains one or more structured blocks. Each block of a `sections` directive is constructed with a `section` construct, and executed once by one of the threads (any one) in the team. (If only one block is formed in the region, the `section` construct, which is used to separate blocks, is not required.) The other threads wait at the implied barrier at the end, unless the `nowait` clause is specified. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `workshare` construct is a Fortran feature that consists of a region with a single structure block (section of code). Statements in the `workshare` region are divided into units of work, and executed (once) by threads of the team. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `workshare` construct is a Fortran feature that consists of a region with a single structure block (section of code). Statements in the `workshare` region are divided into units of work, and executed (once) by threads of the team. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " bigskip MASTER CONSTRUCT" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " bigskip MASTER CONSTRUCT " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `master` construct is not a worksharing construct. The master region is is executed only by the master thread. There is no implicit barrier (and flush) at the end of the `master` region; hence the other threads of the team continue execution beyond code statements beyond the `master` region." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `master` construct is not a worksharing construct. The master region is is executed only by the master thread. There is no implicit barrier (and flush) at the end of the `master` region; hence the other threads of the team continue execution beyond code statements beyond the `master` region. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Chap_program_control.ipynb b/notebook/Chap_program_control.ipynb index 84e65c8..4fadc55 100644 --- a/notebook/Chap_program_control.ipynb +++ b/notebook/Chap_program_control.ipynb @@ -1,136 +1,136 @@ { "cells": [ -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ## Program Control" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ## Program Control " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Some specific and elementary concepts of controlling program execution are illustrated in the examples of this chapter. Control can be directly managed with conditional control code (ifdef's with the `_OPENMP` macro, and the Fortran sentinel ( `!$` ) for conditionally compiling). The `if` clause on some constructs can direct the runtime to ignore or alter the behavior of the construct. Of course, the base-language `if` statements can be used to control the 'execution' of stand-alone directives (such as `flush` , `barrier` , `taskwait` , and `taskyield` ). However, the directives must appear in a block structure, and not as a substatement as shown in examples 1 and 2 of this chapter." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Some specific and elementary concepts of controlling program execution are illustrated in the examples of this chapter. Control can be directly managed with conditional control code (ifdef's with the `_OPENMP` macro, and the Fortran sentinel ( `!$` ) for conditionally compiling). The `if` clause on some constructs can direct the runtime to ignore or alter the behavior of the construct. Of course, the base-language `if` statements can be used to control the 'execution' of stand-alone directives (such as `flush` , `barrier` , `taskwait` , and `taskyield` ). However, the directives must appear in a block structure, and not as a substatement as shown in examples 1 and 2 of this chapter. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " bigskip CANCELLATION" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " bigskip CANCELLATION " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Cancellation (termination) of the normal sequence of execution for the threads in an OpenMP region can be accomplished with the `cancel` construct. The construct uses a _construct-type-clause_ to set the region-type to activate for the cancellation. That is, inclusion of one of the _construct-type-clause_ names `parallel` , `for` , `do` , `sections` or `taskgroup` on the directive line activates the corresponding region. The `cancel` construct is activated by the first encountering thread, and it continues execution at the end of the named region. The `cancel` construct is also a concellation point for any other thread of the team to also continue execution at the end of the named region. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Cancellation (termination) of the normal sequence of execution for the threads in an OpenMP region can be accomplished with the `cancel` construct. The construct uses a _construct-type-clause_ to set the region-type to activate for the cancellation. That is, inclusion of one of the _construct-type-clause_ names `parallel` , `for` , `do` , `sections` or `taskgroup` on the directive line activates the corresponding region. The `cancel` construct is activated by the first encountering thread, and it continues execution at the end of the named region. The `cancel` construct is also a concellation point for any other thread of the team to also continue execution at the end of the named region. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Also, once the specified region has been activated for cancellation any thread that encounnters a `cancellation point` construct with the same named region ( _construct-type-clause_ ), continues execution at the end of the region." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Also, once the specified region has been activated for cancellation any thread that encounnters a `cancellation point` construct with the same named region ( _construct-type-clause_ ), continues execution at the end of the region. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " For an activated `cancel taskgroup` construct, the tasks that belong to the taskgroup set of the innermost enclosing taskgroup region will be canceled. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " For an activated `cancel taskgroup` construct, the tasks that belong to the taskgroup set of the innermost enclosing taskgroup region will be canceled. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " A task that encounters the cancel taskgroup construct continues execution at the end of its task region. Any task of the taskgroup that has already begun execution will run to completion, unless it encounters a `cancellation point` ; tasks that have not begun execution 'may' be discarded as completed tasks." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " A task that encounters the cancel taskgroup construct continues execution at the end of its task region. Any task of the taskgroup that has already begun execution will run to completion, unless it encounters a `cancellation point` ; tasks that have not begun execution 'may' be discarded as completed tasks. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " bigskip CONTROL VARIABLES " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " bigskip CONTROL VARIABLES " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Internal control variables (ICV) are used by implementations to hold values which control the execution of OpenMP regions. Control (and hence the ICVs) may be set as implementation defaults, or set and adjusted through environment variables, clauses, and API functions. Many of the ICV control values are accessible through API function calls. Also, initial ICV values are reported by the runtime if the `OMP_DISPLAY_ENV` environment variable has been set to `TRUE` . " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Internal control variables (ICV) are used by implementations to hold values which control the execution of OpenMP regions. Control (and hence the ICVs) may be set as implementation defaults, or set and adjusted through environment variables, clauses, and API functions. Many of the ICV control values are accessible through API function calls. Also, initial ICV values are reported by the runtime if the `OMP_DISPLAY_ENV` environment variable has been set to `TRUE` . " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", "As an example, the _nthreads-var_ is the ICV that holds the number of threads \n", "to be used in a `parallel` region. It can be set with the `OMP_NUM_THREADS` environment variable, \n", "the `omp_set_num_threads()` API function, or the `num_threads` clause. The default _nthreads-var_ \n", "value is implementation defined. All of the ICVs are presented in the _Internal Control Variables_ section \n", "of the _Directives_ chapter of the OpenMP Specifications document. Within the same document section, override \n", "relationships and scoping information can be found for applying user specifications and understanding the \n", -"extent of the control." +"extent of the control. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " bigskip NESTED CONSTRUCTS" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " bigskip NESTED CONSTRUCTS " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Certain combinations of nested constructs are permitted, giving rise to a _combined_ construct consisting of two or more constructs. These can be used when the two (or several) constructs would be used immediately in succession (closely nested). A combined construct can use the clauses of the component constructs without restrictions. A _composite_ construct is a combined construct which has one or more clauses with (an often obviously) modified or restricted meaning, relative to when the constructs are uncombined. \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Certain combinations of nested constructs are permitted, giving rise to a _combined_ construct consisting of two or more constructs. These can be used when the two (or several) constructs would be used immediately in succession (closely nested). A combined construct can use the clauses of the component constructs without restrictions. A _composite_ construct is a combined construct which has one or more clauses with (an often obviously) modified or restricted meaning, relative to when the constructs are uncombined. \n", "\n", -"[appear separately (singly)." +"[appear separately (singly). " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", "The combined `parallel do` and `parallel for` constructs are formed by combining the `parallel` \n", "construct with one of the loops constructs `do` or `for` . The \n", " `parallel do SIMD` and `parallel for SIMD` constructs are composite constructs (composed from \n", "the parallel loop constructs and the `SIMD` construct), because the `collapse` clause must \n", -"explicitly address the ordering of loop chunking _and_ SIMD 'combined' execution." +"explicitly address the ordering of loop chunking _and_ SIMD 'combined' execution. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Certain nestings are forbidden, and often the reasoning is obvious. Worksharing constructs cannot be nested, and the `barrier` construct cannot be nested inside a worksharing construct, or a `critical` construct. Also, `target` constructs cannot be nested. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Certain nestings are forbidden, and often the reasoning is obvious. Worksharing constructs cannot be nested, and the `barrier` construct cannot be nested inside a worksharing construct, or a `critical` construct. Also, `target` constructs cannot be nested. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `parallel` construct can be nested, as well as the `task` construct. The parallel execution in the nested `parallel` construct(s) is control by the `OMP_NESTED` and `OMP_MAX_ACTIVE_LEVELS` environment variables, and the `omp_set_nested()` and `omp_set_max_active_levels()` functions." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `parallel` construct can be nested, as well as the `task` construct. The parallel execution in the nested `parallel` construct(s) is control by the `OMP_NESTED` and `OMP_MAX_ACTIVE_LEVELS` environment variables, and the `omp_set_nested()` and `omp_set_max_active_levels()` functions. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " More details on nesting can be found in the _Nesting of Regions_ of the _Directives_ chapter in the OpenMP Specifications document." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " More details on nesting can be found in the _Nesting of Regions_ of the _Directives_ chapter in the OpenMP Specifications document. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Chap_synchronization.ipynb b/notebook/Chap_synchronization.ipynb index d64fbf0..e3ea386 100644 --- a/notebook/Chap_synchronization.ipynb +++ b/notebook/Chap_synchronization.ipynb @@ -1,75 +1,75 @@ { "cells": [ -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ## Synchronization" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ## Synchronization " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `barrier` construct is a stand-alone directive that requires all threads of a team (within a contention group) to execute the barrier and complete execution of all tasks within the region, before continuing past the barrier." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `barrier` construct is a stand-alone directive that requires all threads of a team (within a contention group) to execute the barrier and complete execution of all tasks within the region, before continuing past the barrier. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `critical` construct is a directive that contains a structured block. The construct allows only a single thread at a time to execute the structured block (region). Multiple critical regions may exist in a parallel region, and may act cooperatively (only one thread at a time in all `critical` regions), or separately (only one thread at a time in each `critical` regions when a unique name is supplied on each `critical` construct). An optional (lock) `hint` clause may be specified on a named `critical` construct to provide the OpenMP runtime guidance in selection a locking mechanism." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `critical` construct is a directive that contains a structured block. The construct allows only a single thread at a time to execute the structured block (region). Multiple critical regions may exist in a parallel region, and may act cooperatively (only one thread at a time in all `critical` regions), or separately (only one thread at a time in each `critical` regions when a unique name is supplied on each `critical` construct). An optional (lock) `hint` clause may be specified on a named `critical` construct to provide the OpenMP runtime guidance in selection a locking mechanism. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " On a finer scale the `atomic` construct allows only a single thread at a time to have atomic access to a storage location involving a single read, write, update or capture statement, and a limited number of combinations when specifying the `capture` _atomic-clause_ clause. The _atomic-clause_ clause is required for some expression statements, but are not required for `update` statements. Please see the details in the _atomic Construct_ subsection of the _Directives_ chapter in the OpenMP Specifications document." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " On a finer scale the `atomic` construct allows only a single thread at a time to have atomic access to a storage location involving a single read, write, update or capture statement, and a limited number of combinations when specifying the `capture` _atomic-clause_ clause. The _atomic-clause_ clause is required for some expression statements, but are not required for `update` statements. Please see the details in the _atomic Construct_ subsection of the _Directives_ chapter in the OpenMP Specifications document. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -" The following three sentences were stolen from the spec. The `ordered` construct either specifies a structured block in a loop, simd, or loop SIMD region that will be executed in the order of the loop iterations. The ordered construct sequentializes and orders the execution of ordered regions while allowing code outside the region to run in parallel." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +" The following three sentences were stolen from the spec. The `ordered` construct either specifies a structured block in a loop, simd, or loop SIMD region that will be executed in the order of the loop iterations. The ordered construct sequentializes and orders the execution of ordered regions while allowing code outside the region to run in parallel. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Since OpenMP 4.5 the `ordered` construct can also be a stand-alone directive that specifies cross-iteration dependences in a doacross loop nest. The `depend` clause uses a `sink` _dependence-type_ , along with a iteration vector argument (vec) to indicate the iteration that satisfies the dependence. The `depend` clause with a `source` _dependence-type_ specifies dependence satisfaction." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Since OpenMP 4.5 the `ordered` construct can also be a stand-alone directive that specifies cross-iteration dependences in a doacross loop nest. The `depend` clause uses a `sink` _dependence-type_ , along with a iteration vector argument (vec) to indicate the iteration that satisfies the dependence. The `depend` clause with a `source` _dependence-type_ specifies dependence satisfaction. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `flush` directive is a stand-alone construct that forces a thread's temporal local storage (view) of a variable to memory where a consistent view of the variable storage can be accesses. When the construct is used without a variable list, all the locally thread-visible data as defined by the base language are flushed. A construct with a list applies the flush operation only to the items in the list. The `flush` construct also effectively insures that no memory (load or store) operation for the variable set (list items, or default set) may be reordered across the `flush` directive. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `flush` directive is a stand-alone construct that forces a thread's temporal local storage (view) of a variable to memory where a consistent view of the variable storage can be accesses. When the construct is used without a variable list, all the locally thread-visible data as defined by the base language are flushed. A construct with a list applies the flush operation only to the items in the list. The `flush` construct also effectively insures that no memory (load or store) operation for the variable set (list items, or default set) may be reordered across the `flush` directive. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " General-purpose routines provide mutual exclusion semantics through locks, represented by lock variables. The semantics allows a task to _set_ , and hence _own_ a lock, until it is _unset_ by the task that set it. A _nestable_ lock can be set multiple times by a task, and is used when in code requires nested control of locks. A _simple lock_ can only be set once by the owning task. There are specific calls for the two types of locks, and the variable of a specific lock type cannot be used by the other lock type. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " General-purpose routines provide mutual exclusion semantics through locks, represented by lock variables. The semantics allows a task to _set_ , and hence _own_ a lock, until it is _unset_ by the task that set it. A _nestable_ lock can be set multiple times by a task, and is used when in code requires nested control of locks. A _simple lock_ can only be set once by the owning task. There are specific calls for the two types of locks, and the variable of a specific lock type cannot be used by the other lock type. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Any explicit task will observe the synchronization prescribed in a `barrier` construct and an implied barrier. Also, additional synchronizations are available for tasks. All children of a task will wait at a `taskwait` (for their siblings to complete). A `taskgroup` construct creates a region in which the current task is suspended at the end of the region until all sibling tasks, and their descendants, have completed. Scheduling constraints on task execution can be prescribed by the `depend` clause to enforce dependence on previously generated tasks. More details on controlling task executions can be found in the _Tasking_ Chapter in the OpenMP Specifications document. \n", -"(DO REF. RIGHT.)" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Any explicit task will observe the synchronization prescribed in a `barrier` construct and an implied barrier. Also, additional synchronizations are available for tasks. All children of a task will wait at a `taskwait` (for their siblings to complete). A `taskgroup` construct creates a region in which the current task is suspended at the end of the region until all sibling tasks, and their descendants, have completed. Scheduling constraints on task execution can be prescribed by the `depend` clause to enforce dependence on previously generated tasks. More details on controlling task executions can be found in the _Tasking_ Chapter in the OpenMP Specifications document. \n", +"(DO REF. RIGHT.) " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Chap_tasking.ipynb b/notebook/Chap_tasking.ipynb index 40e9ca2..a4514cd 100644 --- a/notebook/Chap_tasking.ipynb +++ b/notebook/Chap_tasking.ipynb @@ -1,60 +1,60 @@ { "cells": [ -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ## Tasking" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ## Tasking " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Tasking constructs provide units of work to a thread for execution. Worksharing constructs do this, too (e.g. `for` , `do` , `sections` , and `singles` constructs); but the work units are tightly controlled by an iteration limit and limited scheduling, or a limited number of `sections` or `single` regions. Worksharing was designed with ' data parallel ' computing in mind. Tasking was designed for ' task parallel ' computing and often involves non-locality or irregularity in memory access." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Tasking constructs provide units of work to a thread for execution. Worksharing constructs do this, too (e.g. `for` , `do` , `sections` , and `singles` constructs); but the work units are tightly controlled by an iteration limit and limited scheduling, or a limited number of `sections` or `single` regions. Worksharing was designed with ' data parallel ' computing in mind. Tasking was designed for ' task parallel ' computing and often involves non-locality or irregularity in memory access. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `task` construct can be used to execute work chunks: in a while loop; while traversing nodes in a list; at nodes in a tree graph; or in a normal loop (with a `taskloop` construct). Unlike the statically scheduled loop iterations of worksharing, a task is often enqueued, and then dequeued for execution by any of the threads of the team within a parallel region. The generation of tasks can be from a single generating thread (creating sibling tasks), or from multiple generators in a recursive graph tree traversals. \n", -"(creating a parent-descendents hierarchy of tasks, see example 4 and 7 below). A `taskloop` construct bundles iterations of an associated loop into tasks, and provides similar controls found in the `task` construct." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `task` construct can be used to execute work chunks: in a while loop; while traversing nodes in a list; at nodes in a tree graph; or in a normal loop (with a `taskloop` construct). Unlike the statically scheduled loop iterations of worksharing, a task is often enqueued, and then dequeued for execution by any of the threads of the team within a parallel region. The generation of tasks can be from a single generating thread (creating sibling tasks), or from multiple generators in a recursive graph tree traversals. \n", +"(creating a parent-descendents hierarchy of tasks, see example 4 and 7 below). A `taskloop` construct bundles iterations of an associated loop into tasks, and provides similar controls found in the `task` construct. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Sibling tasks are synchronized by the `taskwait` construct, and tasks and their descendent tasks can be synchronized by containing them in a `taskgroup` region. Ordered execution is accomplished by specifying dependences with a `depend` clause. Also, priorities can be specified as hints to the scheduler through a `priority` clause." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Sibling tasks are synchronized by the `taskwait` construct, and tasks and their descendent tasks can be synchronized by containing them in a `taskgroup` region. Ordered execution is accomplished by specifying dependences with a `depend` clause. Also, priorities can be specified as hints to the scheduler through a `priority` clause. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Various clauses can be used to manage and optimize task generation, as well as reduce the overhead of execution and to relinquish control of threads for work balance and forward progress. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Various clauses can be used to manage and optimize task generation, as well as reduce the overhead of execution and to relinquish control of threads for work balance and forward progress. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Once a thread starts executing a task, it is the designated thread for executing the task to completion, even though it may leave the execution at a scheduling point and return later. The thread is tied to the task. Scheduling points can be introduced with the `taskyield` construct. With an `untied` clause any other thread is allowed to continue the task. An `if` clause with a _true_ expression allows the generating thread to immediately execute the task as an undeferred task. By including the data environment of the generating task into the generated task with the `mergeable` and `final` clauses, task generation overhead can be reduced." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Once a thread starts executing a task, it is the designated thread for executing the task to completion, even though it may leave the execution at a scheduling point and return later. The thread is tied to the task. Scheduling points can be introduced with the `taskyield` construct. With an `untied` clause any other thread is allowed to continue the task. An `if` clause with a _true_ expression allows the generating thread to immediately execute the task as an undeferred task. By including the data environment of the generating task into the generated task with the `mergeable` and `final` clauses, task generation overhead can be reduced. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " A complete list of the tasking constructs and details of their clauses can be found in the _Tasking Constructs_ chapter of the OpenMP Specifications, in the _OpenMP Application Programming Interface_ section." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " A complete list of the tasking constructs and details of their clauses can be found in the _Tasking Constructs_ chapter of the OpenMP Specifications, in the _OpenMP Application Programming Interface_ section. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_Chapt.ipynb b/notebook/Examples_Chapt.ipynb index 3575d43..0036111 100644 --- a/notebook/Examples_Chapt.ipynb +++ b/notebook/Examples_Chapt.ipynb @@ -1,35 +1,35 @@ { "cells": [ -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "chapter*{Examples}" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "chapter*{Examples} " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " addcontentsline{toc}{chapter}{protectnumberline{}Examples} The following are examples of the OpenMP API directives, constructs, and routines. ccppspecificstart A statement following a directive is compound only when necessary, and a non-compound statement is indented with respect to a directive preceding it. ccppspecificend" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " addcontentsline{toc}{chapter}{protectnumberline{}Examples} The following are examples of the OpenMP API directives, constructs, and routines. ccppspecificstart A statement following a directive is compound only when necessary, and a non-compound statement is indented with respect to a directive preceding it. ccppspecificend " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Each example is labeled as _ename.seqno.ext_ , where _ename_ is the example name, _seqno_ is the sequence number in a section, and _ext_ is the source file extension to indicate the code type and source form. _ext_ is one of the following: \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Each example is labeled as _ename.seqno.ext_ , where _ename_ is the example name, _seqno_ is the sequence number in a section, and _ext_ is the source file extension to indicate the code type and source form. _ext_ is one of the following: \n", "* _c_ -- C code, \n", "* _cpp_ -- C++ code, \n", "* _f_ -- Fortran code in fixed form, and \n", -"* _f90_ -- Fortran code in free form. " +"* _f90_ -- Fortran code in free form. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_SIMD.ipynb b/notebook/Examples_SIMD.ipynb index cf3a0bf..cdb52d4 100644 --- a/notebook/Examples_SIMD.ipynb +++ b/notebook/Examples_SIMD.ipynb @@ -1,273 +1,273 @@ { "cells": [ -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -" ### `simd` and `declare` `simd` Constructs" - ] - }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example illustrates the basic use of the `simd` construct to assure the compiler that the loop can be vectorized." - ] - }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_SIMD.1.c" - ] - }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_SIMD.1.f90" - ] - }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " When a function can be inlined within a loop the compiler has an opportunity to vectorize the loop. By guaranteeing SIMD behavior of a function's operations, characterizing the arguments of the function and privatizing temporary variables of the loop, the compiler can often create faster, vector code for the loop. In the examples below the `declare` `simd` construct is used on the _add1_ and _add2_ functions to enable creation of their corresponding SIMD function versions for execution within the associated SIMD loop. The functions characterize two different approaches of accessing data within the function: by a single variable and as an element in a data array, respectively. The _add3_ C function uses dereferencing." - ] - }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `declare` `simd` constructs also illustrate the use of `uniform` and `linear` clauses. The `uniform(fact)` clause indicates that the variable _fact_ is invariant across the SIMD lanes. In the _add2_ function _a_ and _b_ are included in the `unform` list because the C pointer and the Fortran array references are constant. The _i_ index used in the _add2_ function is included in a `linear` clause with a constant-linear-step of 1, to guarantee a unity increment of the associated loop. In the `declare` `simd` construct for the _add3_ C function the `linear(a,b:1)` clause instructs the compiler to generate unit-stride loads across the SIMD lanes; otherwise, costly emph{gather} instructions would be generated for the unknown sequence of access of the pointer dereferences." - ] - }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the `simd` constructs for the loops the `private(tmp)` clause is necessary to assure that the each vector operation has its own _tmp_ variable." - ] - }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_SIMD.2.c" - ] - }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_SIMD.2.f90" - ] - }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " A thread that encounters a SIMD construct executes a vectorized code of the iterations. Similar to the concerns of a worksharing loop a loop vectorized with a SIMD construct must assure that temporary and reduction variables are privatized and declared as reductions with clauses. The example below illustrates the use of `private` and `reduction` clauses in a SIMD construct." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +" ### `simd` and `declare` `simd` Constructs " ] - }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_SIMD.3.c" + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example illustrates the basic use of the `simd` construct to assure the compiler that the loop can be vectorized. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_SIMD.3.f90" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_SIMD.1.c " ] - }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " A `safelen(N)` clause in a `simd` construct assures the compiler that there are no loop-carried dependencies for vectors of size _N_ or below. If the `safelen` clause is not specified, then the default safelen value is the number of loop iterations. The `safelen(16)` clause in the example below guarantees that the vector code is safe for vectors up to and including size 16. In the loop, _m_ can be 16 or greater, for correct code execution. If the value of _m_ is less than 16, the behavior is undefined." + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_SIMD.1.f90 " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " ] - }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_SIMD.4.c" + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " When a function can be inlined within a loop the compiler has an opportunity to vectorize the loop. By guaranteeing SIMD behavior of a function's operations, characterizing the arguments of the function and privatizing temporary variables of the loop, the compiler can often create faster, vector code for the loop. In the examples below the `declare` `simd` construct is used on the _add1_ and _add2_ functions to enable creation of their corresponding SIMD function versions for execution within the associated SIMD loop. The functions characterize two different approaches of accessing data within the function: by a single variable and as an element in a data array, respectively. The _add3_ C function uses dereferencing. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_SIMD.4.f90" - ] + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `declare` `simd` constructs also illustrate the use of `uniform` and `linear` clauses. The `uniform(fact)` clause indicates that the variable _fact_ is invariant across the SIMD lanes. In the _add2_ function _a_ and _b_ are included in the `unform` list because the C pointer and the Fortran array references are constant. The _i_ index used in the _add2_ function is included in a `linear` clause with a constant-linear-step of 1, to guarantee a unity increment of the associated loop. In the `declare` `simd` construct for the _add3_ C function the `linear(a,b:1)` clause instructs the compiler to generate unit-stride loads across the SIMD lanes; otherwise, costly emph{gather} instructions would be generated for the unknown sequence of access of the pointer dereferences. " + ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following SIMD construct instructs the compiler to collapse the _i_ and _j_ loops into a single SIMD loop in which SIMD chunks are executed by threads of the team. Within the workshared loop chunks of a thread, the SIMD chunks are executed in the lanes of the vector units." - ] + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the `simd` constructs for the loops the `private(tmp)` clause is necessary to assure that the each vector operation has its own _tmp_ variable. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_SIMD.2.c " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_SIMD.2.f90 " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " A thread that encounters a SIMD construct executes a vectorized code of the iterations. Similar to the concerns of a worksharing loop a loop vectorized with a SIMD construct must assure that temporary and reduction variables are privatized and declared as reductions with clauses. The example below illustrates the use of `private` and `reduction` clauses in a SIMD construct. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_SIMD.3.c " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_SIMD.3.f90 " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " A `safelen(N)` clause in a `simd` construct assures the compiler that there are no loop-carried dependencies for vectors of size _N_ or below. If the `safelen` clause is not specified, then the default safelen value is the number of loop iterations. The `safelen(16)` clause in the example below guarantees that the vector code is safe for vectors up to and including size 16. In the loop, _m_ can be 16 or greater, for correct code execution. If the value of _m_ is less than 16, the behavior is undefined. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_SIMD.4.c " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_SIMD.4.f90 " + ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_SIMD.5.c" - ] + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following SIMD construct instructs the compiler to collapse the _i_ and _j_ loops into a single SIMD loop in which SIMD chunks are executed by threads of the team. Within the workshared loop chunks of a thread, the SIMD chunks are executed in the lanes of the vector units. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_SIMD.5.c " + ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_SIMD.5.f90" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_SIMD.5.f90 " ] - }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", "\n", "\n", -" section ### `inbranch` and `notinbranch` Clauses" +" section ### `inbranch` and `notinbranch` Clauses " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following examples illustrate the use of the `declare` `simd` construct with the `inbranch` and `notinbranch` clauses. The `notinbranch` clause informs the compiler that the function _foo_ is never called conditionally in the SIMD loop of the function _myaddint_ . On the other hand, the `inbranch` clause for the function goo indicates that the function is always called conditionally in the SIMD loop inside the function _myaddfloat_ ." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following examples illustrate the use of the `declare` `simd` construct with the `inbranch` and `notinbranch` clauses. The `notinbranch` clause informs the compiler that the function _foo_ is never called conditionally in the SIMD loop of the function _myaddint_ . On the other hand, the `inbranch` clause for the function goo indicates that the function is always called conditionally in the SIMD loop inside the function _myaddfloat_ . " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_SIMD.6.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_SIMD.6.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_SIMD.6.f90" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_SIMD.6.f90 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the code below, the function _fib()_ is called in the main program and also recursively called in the function _fib()_ within an `if` condition. The compiler creates a masked vector version and a non-masked vector version for the function _fib()_ while retaining the original scalar version of the _fib()_ function." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the code below, the function _fib()_ is called in the main program and also recursively called in the function _fib()_ within an `if` condition. The compiler creates a masked vector version and a non-masked vector version for the function _fib()_ while retaining the original scalar version of the _fib()_ function. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_SIMD.7.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_SIMD.7.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_SIMD.7.f90" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_SIMD.7.f90 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", "\n", "\n", -" section ### Loop-Carried Lexical Forward Dependence" +" section ### Loop-Carried Lexical Forward Dependence " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example tests the restriction on an SIMD loop with the loop-carried lexical forward-dependence. This dependence must be preserved for the correct execution of SIMD loops." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example tests the restriction on an SIMD loop with the loop-carried lexical forward-dependence. This dependence must be preserved for the correct execution of SIMD loops. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " A loop can be vectorized even though the iterations are not completely independent when it has loop-carried dependences that are forward lexical dependences, indicated in the code below by the read of _A[j+1]_ and the write to _A[j]_ in C/C++ code (or _A(j+1)_ and _A(j)_ in Fortran). That is, the read of _A[j+1]_ (or _A(j+1)_ in Fortran) before the write to _A[j]_ (or _A(j)_ in Fortran) ordering must be preserved for each iteration in _j_ for valid SIMD code generation." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " A loop can be vectorized even though the iterations are not completely independent when it has loop-carried dependences that are forward lexical dependences, indicated in the code below by the read of _A[j+1]_ and the write to _A[j]_ in C/C++ code (or _A(j+1)_ and _A(j)_ in Fortran). That is, the read of _A[j+1]_ (or _A(j+1)_ in Fortran) before the write to _A[j]_ (or _A(j)_ in Fortran) ordering must be preserved for each iteration in _j_ for valid SIMD code generation. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " This test assures that the compiler preserves the loop carried lexical forward-dependence for generating a correct SIMD code." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " This test assures that the compiler preserves the loop carried lexical forward-dependence for generating a correct SIMD code. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_SIMD.8.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_SIMD.8.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_SIMD.8.f90" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_SIMD.8.f90 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_affinity.ipynb b/notebook/Examples_affinity.ipynb index 97e96d0..7f51393 100644 --- a/notebook/Examples_affinity.ipynb +++ b/notebook/Examples_affinity.ipynb @@ -1,690 +1,690 @@ { "cells": [ -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### The `proc_bind` Clause" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### The `proc_bind` Clause " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following examples demonstrate how to use the `proc_bind` clause to control the thread binding for a team of threads in a `parallel` region. The machine architecture is depicted in the figure below. It consists of two sockets, each equipped with a quad-core processor and configured to execute two hardware threads simultaneously on each core. These examples assume a contiguous core numbering starting from 0, such that the hardware threads 0,1 form the first physical core." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following examples demonstrate how to use the `proc_bind` clause to control the thread binding for a team of threads in a `parallel` region. The machine architecture is depicted in the figure below. It consists of two sockets, each equipped with a quad-core processor and configured to execute two hardware threads simultaneously on each core. These examples assume a contiguous core numbering starting from 0, such that the hardware threads 0,1 form the first physical core. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " {figs/proc_bind_fig.pdf}} \n", -" fi" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " {figs/proc_bind_fig.pdf}} \n", +" fi " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following equivalent place list declarations consist of eight places (which we designate as p0 to p7):" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following equivalent place list declarations consist of eight places (which we designate as p0 to p7): " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " `OMP_PLACES= ' {0,1},{2,3},{4,5},{6,7},{8,9},{10,11},{12,13},{14,15} ' ` " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " `OMP_PLACES= ' {0,1},{2,3},{4,5},{6,7},{8,9},{10,11},{12,13},{14,15} ' ` " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " or" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " or " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " `OMP_PLACES= ' {0:2}:8:2 ' ` " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " `OMP_PLACES= ' {0:2}:8:2 ' ` " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### Spread Affinity Policy" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### Spread Affinity Policy " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows the result of the `spread` affinity policy on the partition list when the number of threads is less than or equal to the number of places in the parent's place partition, for the machine architecture depicted above. Note that the threads are bound to the first place of each subpartition." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows the result of the `spread` affinity policy on the partition list when the number of threads is less than or equal to the number of places in the parent's place partition, for the machine architecture depicted above. Note that the threads are bound to the first place of each subpartition. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_affinity.1.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_affinity.1.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_affinity.1.f" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_affinity.1.f " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " It is unspecified on which place the master thread is initially started. If the master thread is initially started on p0, the following placement of threads will be applied in the parallel region:" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " It is unspecified on which place the master thread is initially started. If the master thread is initially started on p0, the following placement of threads will be applied in the parallel region: " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* thread 0 executes on p0 with the place partition p0,p1" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* thread 0 executes on p0 with the place partition p0,p1 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* thread 1 executes on p2 with the place partition p2,p3" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* thread 1 executes on p2 with the place partition p2,p3 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* thread 2 executes on p4 with the place partition p4,p5" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* thread 2 executes on p4 with the place partition p4,p5 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* thread 3 executes on p6 with the place partition p6,p7 " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* thread 3 executes on p6 with the place partition p6,p7 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " If the master thread would initially be started on p2, the placement of threads and distribution of the place partition would be as follows:" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " If the master thread would initially be started on p2, the placement of threads and distribution of the place partition would be as follows: " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* thread 0 executes on p2 with the place partition p2,p3" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* thread 0 executes on p2 with the place partition p2,p3 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* thread 1 executes on p4 with the place partition p4,p5" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* thread 1 executes on p4 with the place partition p4,p5 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* thread 2 executes on p6 with the place partition p6,p7" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* thread 2 executes on p6 with the place partition p6,p7 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* thread 3 executes on p0 with the place partition p0,p1 " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* thread 3 executes on p0 with the place partition p0,p1 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example illustrates the `spread` thread affinity policy when the number of threads is greater than the number of places in the parent's place partition." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example illustrates the `spread` thread affinity policy when the number of threads is greater than the number of places in the parent's place partition. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Let _T_ be the number of threads in the team, and _P_ be the number of places in the parent's place partition. The first _T/P_ threads of the team (including the master thread) execute on the parent's place. The next _T/P_ threads execute on the next place in the place partition, and so on, with wrap around. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Let _T_ be the number of threads in the team, and _P_ be the number of places in the parent's place partition. The first _T/P_ threads of the team (including the master thread) execute on the parent's place. The next _T/P_ threads execute on the next place in the place partition, and so on, with wrap around. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_affinity.2.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_affinity.2.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_affinity.2.f90" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_affinity.2.f90 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " It is unspecified on which place the master thread is initially started. If the master thread is initially started on p0, the following placement of threads will be applied in the parallel region:" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " It is unspecified on which place the master thread is initially started. If the master thread is initially started on p0, the following placement of threads will be applied in the parallel region: " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* threads 0,1 execute on p0 with the place partition p0" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* threads 0,1 execute on p0 with the place partition p0 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* threads 2,3 execute on p1 with the place partition p1" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* threads 2,3 execute on p1 with the place partition p1 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* threads 4,5 execute on p2 with the place partition p2" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* threads 4,5 execute on p2 with the place partition p2 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* threads 6,7 execute on p3 with the place partition p3" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* threads 6,7 execute on p3 with the place partition p3 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* threads 8,9 execute on p4 with the place partition p4" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* threads 8,9 execute on p4 with the place partition p4 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* threads 10,11 execute on p5 with the place partition p5" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* threads 10,11 execute on p5 with the place partition p5 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* threads 12,13 execute on p6 with the place partition p6" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* threads 12,13 execute on p6 with the place partition p6 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* threads 14,15 execute on p7 with the place partition p7 " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* threads 14,15 execute on p7 with the place partition p7 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " If the master thread would initially be started on p2, the placement of threads and distribution of the place partition would be as follows:" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " If the master thread would initially be started on p2, the placement of threads and distribution of the place partition would be as follows: " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* threads 0,1 execute on p2 with the place partition p2" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* threads 0,1 execute on p2 with the place partition p2 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* threads 2,3 execute on p3 with the place partition p3" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* threads 2,3 execute on p3 with the place partition p3 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* threads 4,5 execute on p4 with the place partition p4" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* threads 4,5 execute on p4 with the place partition p4 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* threads 6,7 execute on p5 with the place partition p5" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* threads 6,7 execute on p5 with the place partition p5 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* threads 8,9 execute on p6 with the place partition p6" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* threads 8,9 execute on p6 with the place partition p6 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* threads 10,11 execute on p7 with the place partition p7" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* threads 10,11 execute on p7 with the place partition p7 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* threads 12,13 execute on p0 with the place partition p0" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* threads 12,13 execute on p0 with the place partition p0 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* threads 14,15 execute on p1 with the place partition p1 " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* threads 14,15 execute on p1 with the place partition p1 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### Close Affinity Policy" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### Close Affinity Policy " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows the result of the `close` affinity policy on the partition list when the number of threads is less than or equal to the number of places in parent's place partition, for the machine architecture depicted above. The place partition is not changed by the `close` policy." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows the result of the `close` affinity policy on the partition list when the number of threads is less than or equal to the number of places in parent's place partition, for the machine architecture depicted above. The place partition is not changed by the `close` policy. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_affinity.3.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_affinity.3.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_affinity.3.f" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_affinity.3.f " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " It is unspecified on which place the master thread is initially started. If the master thread is initially started on p0, the following placement of threads will be applied in the `parallel` region:" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " It is unspecified on which place the master thread is initially started. If the master thread is initially started on p0, the following placement of threads will be applied in the `parallel` region: " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* thread 0 executes on p0 with the place partition p0-p7" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* thread 0 executes on p0 with the place partition p0-p7 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* thread 1 executes on p1 with the place partition p0-p7" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* thread 1 executes on p1 with the place partition p0-p7 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* thread 2 executes on p2 with the place partition p0-p7" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* thread 2 executes on p2 with the place partition p0-p7 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* thread 3 executes on p3 with the place partition p0-p7 " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* thread 3 executes on p3 with the place partition p0-p7 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " If the master thread would initially be started on p2, the placement of threads and distribution of the place partition would be as follows:" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " If the master thread would initially be started on p2, the placement of threads and distribution of the place partition would be as follows: " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* thread 0 executes on p2 with the place partition p0-p7" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* thread 0 executes on p2 with the place partition p0-p7 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* thread 1 executes on p3 with the place partition p0-p7" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* thread 1 executes on p3 with the place partition p0-p7 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* thread 2 executes on p4 with the place partition p0-p7" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* thread 2 executes on p4 with the place partition p0-p7 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* thread 3 executes on p5 with the place partition p0-p7 " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* thread 3 executes on p5 with the place partition p0-p7 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example illustrates the `close` thread affinity policy when the number of threads is greater than the number of places in the parent's place partition." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example illustrates the `close` thread affinity policy when the number of threads is greater than the number of places in the parent's place partition. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Let _T_ be the number of threads in the team, and _P_ be the number of places in the parent's place partition. The first _T/P_ threads of the team (including the master thread) execute on the parent's place. The next _T/P_ threads execute on the next place in the place partition, and so on, with wrap around. The place partition is not changed by the `close` policy." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Let _T_ be the number of threads in the team, and _P_ be the number of places in the parent's place partition. The first _T/P_ threads of the team (including the master thread) execute on the parent's place. The next _T/P_ threads execute on the next place in the place partition, and so on, with wrap around. The place partition is not changed by the `close` policy. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_affinity.4.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_affinity.4.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_affinity.4.f90" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_affinity.4.f90 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " It is unspecified on which place the master thread is initially started. If the master thread is initially running on p0, the following placement of threads will be applied in the parallel region:" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " It is unspecified on which place the master thread is initially started. If the master thread is initially running on p0, the following placement of threads will be applied in the parallel region: " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* threads 0,1 execute on p0 with the place partition p0-p7" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* threads 0,1 execute on p0 with the place partition p0-p7 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* threads 2,3 execute on p1 with the place partition p0-p7" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* threads 2,3 execute on p1 with the place partition p0-p7 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* threads 4,5 execute on p2 with the place partition p0-p7" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* threads 4,5 execute on p2 with the place partition p0-p7 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* threads 6,7 execute on p3 with the place partition p0-p7" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* threads 6,7 execute on p3 with the place partition p0-p7 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* threads 8,9 execute on p4 with the place partition p0-p7" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* threads 8,9 execute on p4 with the place partition p0-p7 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* threads 10,11 execute on p5 with the place partition p0-p7" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* threads 10,11 execute on p5 with the place partition p0-p7 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* threads 12,13 execute on p6 with the place partition p0-p7" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* threads 12,13 execute on p6 with the place partition p0-p7 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* threads 14,15 execute on p7 with the place partition p0-p7 " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* threads 14,15 execute on p7 with the place partition p0-p7 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " If the master thread would initially be started on p2, the placement of threads and distribution of the place partition would be as follows:" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " If the master thread would initially be started on p2, the placement of threads and distribution of the place partition would be as follows: " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* threads 0,1 execute on p2 with the place partition p0-p7" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* threads 0,1 execute on p2 with the place partition p0-p7 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* threads 2,3 execute on p3 with the place partition p0-p7" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* threads 2,3 execute on p3 with the place partition p0-p7 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* threads 4,5 execute on p4 with the place partition p0-p7" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* threads 4,5 execute on p4 with the place partition p0-p7 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* threads 6,7 execute on p5 with the place partition p0-p7" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* threads 6,7 execute on p5 with the place partition p0-p7 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* threads 8,9 execute on p6 with the place partition p0-p7" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* threads 8,9 execute on p6 with the place partition p0-p7 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* threads 10,11 execute on p7 with the place partition p0-p7" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* threads 10,11 execute on p7 with the place partition p0-p7 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* threads 12,13 execute on p0 with the place partition p0-p7" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* threads 12,13 execute on p0 with the place partition p0-p7 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* threads 14,15 execute on p1 with the place partition p0-p7 " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* threads 14,15 execute on p1 with the place partition p0-p7 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### Master Affinity Policy" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### Master Affinity Policy " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows the result of the `master` affinity policy on the partition list for the machine architecture depicted above. The place partition is not changed by the master policy." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows the result of the `master` affinity policy on the partition list for the machine architecture depicted above. The place partition is not changed by the master policy. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_affinity.5.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_affinity.5.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_affinity.5.f" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_affinity.5.f " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " It is unspecified on which place the master thread is initially started. If the master thread is initially running on p0, the following placement of threads will be applied in the parallel region:" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " It is unspecified on which place the master thread is initially started. If the master thread is initially running on p0, the following placement of threads will be applied in the parallel region: " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* threads 0-3 execute on p0 with the place partition p0-p7 " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* threads 0-3 execute on p0 with the place partition p0-p7 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " If the master thread would initially be started on p2, the placement of threads and distribution of the place partition would be as follows:" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " If the master thread would initially be started on p2, the placement of threads and distribution of the place partition would be as follows: " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* threads 0-3 execute on p2 with the place partition p0-p7 " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* threads 0-3 execute on p2 with the place partition p0-p7 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_affinity_query.ipynb b/notebook/Examples_affinity_query.ipynb index 1b70cec..1f27f7c 100644 --- a/notebook/Examples_affinity_query.ipynb +++ b/notebook/Examples_affinity_query.ipynb @@ -1,70 +1,70 @@ { "cells": [ -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Affinity Query Functions" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Affinity Query Functions " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the example below a team of threads is generated on each socket of the system, using nested parallelism. Several query functions are used to gather information to support the creation of the teams and to obtain socket and thread numbers." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the example below a team of threads is generated on each socket of the system, using nested parallelism. Several query functions are used to gather information to support the creation of the teams and to obtain socket and thread numbers. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " For proper execution of the code, the user must create a place partition, such that each place is a listing of the core numbers for a socket. For example, in a 2 socket system with 8 cores in each socket, and sequential numbering in the socket for the core numbers, the `OMP_PLACES` variable would be set to '{0:8},{8:8}', using the place syntax { _lower_bound_ : _length_ : _stride_ }, and the default stride of 1." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " For proper execution of the code, the user must create a place partition, such that each place is a listing of the core numbers for a socket. For example, in a 2 socket system with 8 cores in each socket, and sequential numbering in the socket for the core numbers, the `OMP_PLACES` variable would be set to '{0:8},{8:8}', using the place syntax { _lower_bound_ : _length_ : _stride_ }, and the default stride of 1. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The code determines the number of sockets ( _n_sockets_ ) using the `omp_get_num_places()` query function. In this example each place is constructed with a list of each socket's core numbers, hence the number of places is equal to the number of sockets. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The code determines the number of sockets ( _n_sockets_ ) using the `omp_get_num_places()` query function. In this example each place is constructed with a list of each socket's core numbers, hence the number of places is equal to the number of sockets. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The outer parallel region forms a team of threads, and each thread executes on a socket (place) because the `proc_bind` clause uses `spread` in the outer `parallel` construct. Next, in the _socket_init_ function, an inner parallel region creates a team of threads equal to the number of elements (core numbers) from the place of the parent thread. Because the outer `parallel` construct uses a `spread` affinity policy, each of its threads inherits a subpartition of the original partition. Hence, the `omp_get_place_num_procs` query function returns the number of elements (here procs = cores) in the subpartition of the thread. After each parent thread creates its nested parallel region on the section, the socket number and thread number are reported." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The outer parallel region forms a team of threads, and each thread executes on a socket (place) because the `proc_bind` clause uses `spread` in the outer `parallel` construct. Next, in the _socket_init_ function, an inner parallel region creates a team of threads equal to the number of elements (core numbers) from the place of the parent thread. Because the outer `parallel` construct uses a `spread` affinity policy, each of its threads inherits a subpartition of the original partition. Hence, the `omp_get_place_num_procs` query function returns the number of elements (here procs = cores) in the subpartition of the thread. After each parent thread creates its nested parallel region on the section, the socket number and thread number are reported. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Note: Portable tools like hwloc (Portable HardWare LOCality package), which support many common operating systems, can be used to determine the configuration of a system. On some systems there are utilities, files or user guides that provide configuration information. For instance, the socket number and proc_id's for a socket can be found in the /proc/cpuinfo text file on Linux systems." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Note: Portable tools like hwloc (Portable HardWare LOCality package), which support many common operating systems, can be used to determine the configuration of a system. On some systems there are utilities, files or user guides that provide configuration information. For instance, the socket number and proc_id's for a socket can be found in the /proc/cpuinfo text file on Linux systems. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_affinity.6.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_affinity.6.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_affinity.6.f90" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_affinity.6.f90 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_array_sections.ipynb b/notebook/Examples_array_sections.ipynb index dee493a..0441780 100644 --- a/notebook/Examples_array_sections.ipynb +++ b/notebook/Examples_array_sections.ipynb @@ -1,124 +1,124 @@ { "cells": [ -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Array Sections in Device Constructs" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Array Sections in Device Constructs " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following examples show the usage of array sections in `map` clauses on `target` and `target` `data` constructs." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following examples show the usage of array sections in `map` clauses on `target` and `target` `data` constructs. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " This example shows the invalid usage of two seperate sections of the same array inside of a `target` construct." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " This example shows the invalid usage of two seperate sections of the same array inside of a `target` construct. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_array_sections.1.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_array_sections.1.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_array_sections.1.f90" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_array_sections.1.f90 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " This example shows the invalid usage of two separate sections of the same array inside of a `target` construct." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " This example shows the invalid usage of two separate sections of the same array inside of a `target` construct. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_array_sections.2.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_array_sections.2.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_array_sections.2.f90" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_array_sections.2.f90 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " This example shows the valid usage of two separate sections of the same array inside of a `target` construct." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " This example shows the valid usage of two separate sections of the same array inside of a `target` construct. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_array_sections.3.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_array_sections.3.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_array_sections.3.f90" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_array_sections.3.f90 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " This example shows the valid usage of a wholly contained array section of an already mapped array section inside of a `target` construct." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " This example shows the valid usage of a wholly contained array section of an already mapped array section inside of a `target` construct. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_array_sections.4.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_array_sections.4.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_array_sections.4.f90" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_array_sections.4.f90 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_associate.ipynb b/notebook/Examples_associate.ipynb index 91aada5..0eef380 100644 --- a/notebook/Examples_associate.ipynb +++ b/notebook/Examples_associate.ipynb @@ -1,79 +1,79 @@ { "cells": [ -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Fortran `ASSOCIATE` Construct" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Fortran `ASSOCIATE` Construct " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " fortranspecificstart" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " fortranspecificstart " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following is an invalid example of specifying an associate name on a data-sharing attribute clause. The constraint in the Data Sharing Attribute Rules section in the OpenMP 4.0 API Specifications states that an associate name preserves the association with the selector established at the `ASSOCIATE` statement. The associate name _b_ is associated with the shared variable _a_ . With the predetermined data-sharing attribute rule, the associate name _b_ is not allowed to be specified on the `private` clause." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following is an invalid example of specifying an associate name on a data-sharing attribute clause. The constraint in the Data Sharing Attribute Rules section in the OpenMP 4.0 API Specifications states that an associate name preserves the association with the selector established at the `ASSOCIATE` statement. The associate name _b_ is associated with the shared variable _a_ . With the predetermined data-sharing attribute rule, the associate name _b_ is not allowed to be specified on the `private` clause. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_associate.1.f" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_associate.1.f " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In next example, within the `parallel` construct, the association name _thread_id_ is associated with the private copy of _i_ . The print statement should output the unique thread number." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In next example, within the `parallel` construct, the association name _thread_id_ is associated with the private copy of _i_ . The print statement should output the unique thread number. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_associate.2.f" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_associate.2.f " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example illustrates the effect of specifying a selector name on a data-sharing attribute clause. The associate name _u_ is associated with _v_ and the variable _v_ is specified on the `private` clause of the `parallel` construct. The construct association is established prior to the `parallel` region. The association between _u_ and the original _v_ is retained (see the Data Sharing Attribute Rules section in the OpenMP 4.0 API Specifications). Inside the `parallel` region, _v_ has the value of -1 and _u_ has the value of the original _v_ ." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example illustrates the effect of specifying a selector name on a data-sharing attribute clause. The associate name _u_ is associated with _v_ and the variable _v_ is specified on the `private` clause of the `parallel` construct. The construct association is established prior to the `parallel` region. The association between _u_ and the original _v_ is retained (see the Data Sharing Attribute Rules section in the OpenMP 4.0 API Specifications). Inside the `parallel` region, _v_ has the value of -1 and _u_ has the value of the original _v_ . " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_ffreenexampleassociate3" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_ffreenexampleassociate3 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " fortranspecificend" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " fortranspecificend " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_async_target_depend.ipynb b/notebook/Examples_async_target_depend.ipynb index 1561876..5366519 100644 --- a/notebook/Examples_async_target_depend.ipynb +++ b/notebook/Examples_async_target_depend.ipynb @@ -1,38 +1,38 @@ { "cells": [ -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Asynchronous `target` Execution and Dependences" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Asynchronous `target` Execution and Dependences " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Asynchronous execution of a `target` region can be accomplished by creating an explicit task around the `target` region. Examples with explicit tasks are shown at the beginning of this section. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Asynchronous execution of a `target` region can be accomplished by creating an explicit task around the `target` region. Examples with explicit tasks are shown at the beginning of this section. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " As of OpenMP 4.5 and beyond the `nowait` clause can be used on the `target` directive for asynchronous execution. Examples with `nowait` clauses follow the explicit `task` examples." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " As of OpenMP 4.5 and beyond the `nowait` clause can be used on the `target` directive for asynchronous execution. Examples with `nowait` clauses follow the explicit `task` examples. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " This section also shows the use of `depend` clauses to order executions through dependences." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " This section also shows the use of `depend` clauses to order executions through dependences. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_async_target_nowait.ipynb b/notebook/Examples_async_target_nowait.ipynb index 9380ed9..63f25e4 100644 --- a/notebook/Examples_async_target_nowait.ipynb +++ b/notebook/Examples_async_target_nowait.ipynb @@ -1,63 +1,63 @@ { "cells": [ -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### `nowait` Clause on `target` Construct" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### `nowait` Clause on `target` Construct " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows how to execute code asynchronously on a device without an explicit task. The `nowait` clause on a `target` construct allows the thread of the _target task_ to perform other work while waiting for the `target` region execution to complete. Hence, the the `target` region can execute asynchronously on the device (without requiring a host thread to idle while waiting for the _target task_ execution to complete)." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows how to execute code asynchronously on a device without an explicit task. The `nowait` clause on a `target` construct allows the thread of the _target task_ to perform other work while waiting for the `target` region execution to complete. Hence, the the `target` region can execute asynchronously on the device (without requiring a host thread to idle while waiting for the _target task_ execution to complete). " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In this example the product of two vectors (arrays), _v1_ and _v2_ , is formed. One half of the operations is performed on the device, and the last half on the host, concurrently." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In this example the product of two vectors (arrays), _v1_ and _v2_ , is formed. One half of the operations is performed on the device, and the last half on the host, concurrently. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " After a team of threads is formed the master thread generates the _target task_ while the other threads can continue on, without a barrier, to the execution of the host portion of the vector product. The completion of the _target task_ (asynchronous target execution) is guaranteed by the synchronization in the implicit barrier at the end of the host vector-product worksharing loop region. See the `barrier` glossary entry in the OpenMP specification for details." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " After a team of threads is formed the master thread generates the _target task_ while the other threads can continue on, without a barrier, to the execution of the host portion of the vector product. The completion of the _target task_ (asynchronous target execution) is guaranteed by the synchronization in the implicit barrier at the end of the host vector-product worksharing loop region. See the `barrier` glossary entry in the OpenMP specification for details. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The host loop scheduling is `dynamic` , to balance the host thread executions, since one thread is being used for offload generation. In the situation where little time is spent by the _target task_ in setting up and tearing down the the target execution, `static` scheduling may be desired. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The host loop scheduling is `dynamic` , to balance the host thread executions, since one thread is being used for offload generation. In the situation where little time is spent by the _target task_ in setting up and tearing down the the target execution, `static` scheduling may be desired. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_async_target.3.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_async_target.3.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_async_target.3.f90" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_async_target.3.f90 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_async_target_nowait_depend.ipynb b/notebook/Examples_async_target_nowait_depend.ipynb index c1dc205..80f8cd5 100644 --- a/notebook/Examples_async_target_nowait_depend.ipynb +++ b/notebook/Examples_async_target_nowait_depend.ipynb @@ -1,65 +1,65 @@ { "cells": [ -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"begin #### Asynchronous `target` with `nowait` and `depend` Clauses" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"begin #### Asynchronous `target` with `nowait` and `depend` Clauses " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " More details on dependences can be found in , Task Dependences. In this example, there are three flow dependences. In the first two dependences the target task does not execute until the preceding explicit tasks have finished. These dependences are produced by arrays _v1_ and _v2_ with the `out` dependence type in the first two tasks, and the `in` dependence type in the target task. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " More details on dependences can be found in , Task Dependences. In this example, there are three flow dependences. In the first two dependences the target task does not execute until the preceding explicit tasks have finished. These dependences are produced by arrays _v1_ and _v2_ with the `out` dependence type in the first two tasks, and the `in` dependence type in the target task. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The last dependence is produced by array _p_ with the `out` dependence type in the target task, and the `in` dependence type in the last task. The last task does not execute until the target task finishes. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The last dependence is produced by array _p_ with the `out` dependence type in the target task, and the `in` dependence type in the last task. The last task does not execute until the target task finishes. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `nowait` clause on the `target` construct creates a deferrable _target task_ , allowing the encountering task to continue execution without waiting for the completion of the _target task_ ." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `nowait` clause on the `target` construct creates a deferrable _target task_ , allowing the encountering task to continue execution without waiting for the completion of the _target task_ . " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_async_target.4.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_async_target.4.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_async_target.4.f90" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_async_target.4.f90 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"end" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"end " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_async_target_with_tasks.ipynb b/notebook/Examples_async_target_with_tasks.ipynb index 44b665c..dd568a9 100644 --- a/notebook/Examples_async_target_with_tasks.ipynb +++ b/notebook/Examples_async_target_with_tasks.ipynb @@ -1,109 +1,109 @@ { "cells": [ -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### Asynchronous `target` with Tasks" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### Asynchronous `target` with Tasks " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows how the `task` and `target` constructs are used to execute multiple `target` regions asynchronously. The task that encounters the `task` construct generates an explicit task that contains a `target` region. The thread executing the explicit task encounters a task scheduling point while waiting for the execution of the `target` region to complete, allowing the thread to switch back to the execution of the encountering task or one of the previously generated explicit tasks." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows how the `task` and `target` constructs are used to execute multiple `target` regions asynchronously. The task that encounters the `task` construct generates an explicit task that contains a `target` region. The thread executing the explicit task encounters a task scheduling point while waiting for the execution of the `target` region to complete, allowing the thread to switch back to the execution of the encountering task or one of the previously generated explicit tasks. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_async_target.1.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_async_target.1.c " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The Fortran version has an interface block that contains the `declare` `target` . An identical statement exists in the function declaration (not shown here)." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The Fortran version has an interface block that contains the `declare` `target` . An identical statement exists in the function declaration (not shown here). " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_async_target.1.f90" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_async_target.1.f90 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows how the `task` and `target` constructs are used to execute multiple `target` regions asynchronously. The task dependence ensures that the storage is allocated and initialized on the device before it is accessed." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows how the `task` and `target` constructs are used to execute multiple `target` regions asynchronously. The task dependence ensures that the storage is allocated and initialized on the device before it is accessed. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_async_target.2.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_async_target.2.c " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The Fortran example below is similar to the C version above. Instead of pointers, though, it uses the convenience of Fortran allocatable arrays on the device. In order to preserve the arrays allocated on the device across multiple `target` regions, a `target` ~ `data` region is used in this case." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The Fortran example below is similar to the C version above. Instead of pointers, though, it uses the convenience of Fortran allocatable arrays on the device. In order to preserve the arrays allocated on the device across multiple `target` regions, a `target` ~ `data` region is used in this case. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " If there is no shape specified for an allocatable array in a `map` clause, only the array descriptor (also called a dope vector) is mapped. That is, device space is created for the descriptor, and it is initially populated with host values. In this case, the _v1_ and _v2_ arrays will be in a non-associated state on the device. When space for _v1_ and _v2_ is allocated on the device in the first `target` region the addresses to the space will be included in their descriptors." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " If there is no shape specified for an allocatable array in a `map` clause, only the array descriptor (also called a dope vector) is mapped. That is, device space is created for the descriptor, and it is initially populated with host values. In this case, the _v1_ and _v2_ arrays will be in a non-associated state on the device. When space for _v1_ and _v2_ is allocated on the device in the first `target` region the addresses to the space will be included in their descriptors. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " At the end of the first `target` region, the arrays _v1_ and _v2_ are preserved on the device for access in the second `target` region. At the end of the second `target` region, the data in array _p_ is copied back, the arrays _v1_ and _v2_ are not." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " At the end of the first `target` region, the arrays _v1_ and _v2_ are preserved on the device for access in the second `target` region. At the end of the second `target` region, the data in array _p_ is copied back, the arrays _v1_ and _v2_ are not. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " A `depend` clause is used in the `task` directive to provide a wait at the beginning of the second `target` region, to insure that there is no race condition with _v1_ and _v2_ in the two tasks. It would be noncompliant to use _v1_ and/or _v2_ in lieu of _N_ in the `depend` clauses, because the use of non-allocated allocatable arrays as list items in a `depend` clause would lead to unspecified behavior. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " A `depend` clause is used in the `task` directive to provide a wait at the beginning of the second `target` region, to insure that there is no race condition with _v1_ and _v2_ in the two tasks. It would be noncompliant to use _v1_ and/or _v2_ in lieu of _N_ in the `depend` clauses, because the use of non-allocated allocatable arrays as list items in a `depend` clause would lead to unspecified behavior. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " noteheader{--} This example is not strictly compliant with the OpenMP 4.5 specification since the allocation status of allocatable arrays _v1_ and _v2_ is changed inside the `target` region, which is not allowed. (See the restrictions for the `map` clause in the _Data-mapping Attribute Rules and Clauses_ section of the specification.) However, the intention is to relax the restrictions on mapping of allocatable variables in the next release of the specification so that the example will be compliant." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " noteheader{--} This example is not strictly compliant with the OpenMP 4.5 specification since the allocation status of allocatable arrays _v1_ and _v2_ is changed inside the `target` region, which is not allowed. (See the restrictions for the `map` clause in the _Data-mapping Attribute Rules and Clauses_ section of the specification.) However, the intention is to relax the restrictions on mapping of allocatable variables in the next release of the specification so that the example will be compliant. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_async_target.2.f90" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_async_target.2.f90 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_atomic.ipynb b/notebook/Examples_atomic.ipynb index 7d9311d..8899d92 100644 --- a/notebook/Examples_atomic.ipynb +++ b/notebook/Examples_atomic.ipynb @@ -1,106 +1,106 @@ { "cells": [ -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### The `atomic` Construct" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### The `atomic` Construct " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example avoids race conditions (simultaneous updates of an element of _x_ by multiple threads) by using the `atomic` construct ." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example avoids race conditions (simultaneous updates of an element of _x_ by multiple threads) by using the `atomic` construct . " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The advantage of using the `atomic` construct in this example is that it allows updates of two different elements of _x_ to occur in parallel. If a `critical` construct were used instead, then all updates to elements of _x_ would be executed serially (though not in any guaranteed order)." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The advantage of using the `atomic` construct in this example is that it allows updates of two different elements of _x_ to occur in parallel. If a `critical` construct were used instead, then all updates to elements of _x_ would be executed serially (though not in any guaranteed order). " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Note that the `atomic` directive applies only to the statement immediately following it. As a result, elements of _y_ are not updated atomically in this example." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Note that the `atomic` directive applies only to the statement immediately following it. As a result, elements of _y_ are not updated atomically in this example. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_atomic.1.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_atomic.1.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_atomic.1.f" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_atomic.1.f " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example illustrates the `read` and `write` clauses for the `atomic` directive. These clauses ensure that the given variable is read or written, respectively, as a whole. Otherwise, some other thread might read or write part of the variable while the current thread was reading or writing another part of the variable. Note that most hardware provides atomic reads and writes for some set of properly aligned variables of specific sizes, but not necessarily for all the variable types supported by the OpenMP API." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example illustrates the `read` and `write` clauses for the `atomic` directive. These clauses ensure that the given variable is read or written, respectively, as a whole. Otherwise, some other thread might read or write part of the variable while the current thread was reading or writing another part of the variable. Note that most hardware provides atomic reads and writes for some set of properly aligned variables of specific sizes, but not necessarily for all the variable types supported by the OpenMP API. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_atomic.2.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_atomic.2.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_atomic.2.f" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_atomic.2.f " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example illustrates the `capture` clause for the `atomic` directive. In this case the value of a variable is captured, and then the variable is incremented. These operations occur atomically. This particular example could be implemented using the fetch-and-add instruction available on many kinds of hardware. The example also shows a way to implement a spin lock using the `capture` and `read` clauses." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example illustrates the `capture` clause for the `atomic` directive. In this case the value of a variable is captured, and then the variable is incremented. These operations occur atomically. This particular example could be implemented using the fetch-and-add instruction available on many kinds of hardware. The example also shows a way to implement a spin lock using the `capture` and `read` clauses. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_atomic.3.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_atomic.3.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_atomic.3.f" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_atomic.3.f " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_atomic_restrict.ipynb b/notebook/Examples_atomic_restrict.ipynb index 2e9f100..b0b2323 100644 --- a/notebook/Examples_atomic_restrict.ipynb +++ b/notebook/Examples_atomic_restrict.ipynb @@ -1,90 +1,90 @@ { "cells": [ -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Restrictions on the `atomic` Construct" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Restrictions on the `atomic` Construct " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following non-conforming examples illustrate the restrictions on the `atomic` construct. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following non-conforming examples illustrate the restrictions on the `atomic` construct. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_atomic_restrict.1.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_atomic_restrict.1.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_atomic_restrict.1.f" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_atomic_restrict.1.f " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_atomic_restrict.2.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_atomic_restrict.2.c " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " fortranspecificstart The following example is non-conforming because `I` and `R` reference the same location but have different types." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " fortranspecificstart The following example is non-conforming because `I` and `R` reference the same location but have different types. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_atomic_restrict.2.f" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_atomic_restrict.2.f " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Although the following example might work on some implementations, this is also non-conforming:" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Although the following example might work on some implementations, this is also non-conforming: " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_atomic_restrict.3.f" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_atomic_restrict.3.f " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " fortranspecificend" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " fortranspecificend " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_barrier_regions.ipynb b/notebook/Examples_barrier_regions.ipynb index f0979f3..53441bc 100644 --- a/notebook/Examples_barrier_regions.ipynb +++ b/notebook/Examples_barrier_regions.ipynb @@ -1,56 +1,56 @@ { "cells": [ -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Binding of `barrier` Regions" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Binding of `barrier` Regions " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The binding rules call for a `barrier` region to bind to the closest enclosing `parallel` region. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The binding rules call for a `barrier` region to bind to the closest enclosing `parallel` region. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the following example, the call from the main program to _sub2_ is conforming because the `barrier` region (in _sub3_ ) binds to the `parallel` region in _sub2_ . The call from the main program to _sub1_ is conforming because the `barrier` region binds to the `parallel` region in subroutine _sub2_ ." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the following example, the call from the main program to _sub2_ is conforming because the `barrier` region (in _sub3_ ) binds to the `parallel` region in _sub2_ . The call from the main program to _sub1_ is conforming because the `barrier` region binds to the `parallel` region in subroutine _sub2_ . " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The call from the main program to _sub3_ is conforming because the `barrier` region binds to the implicit inactive `parallel` region enclosing the sequential part. Also note that the `barrier` region in _sub3_ when called from _sub2_ only synchronizes the team of threads in the enclosing `parallel` region and not all the threads created in _sub1_ ." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The call from the main program to _sub3_ is conforming because the `barrier` region binds to the implicit inactive `parallel` region enclosing the sequential part. Also note that the `barrier` region in _sub3_ when called from _sub2_ only synchronizes the team of threads in the enclosing `parallel` region and not all the threads created in _sub1_ . " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_barrier_regions.1.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_barrier_regions.1.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_barrier_regions.1.f" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_barrier_regions.1.f " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_cancellation.ipynb b/notebook/Examples_cancellation.ipynb index 48fce7d..1488b55 100644 --- a/notebook/Examples_cancellation.ipynb +++ b/notebook/Examples_cancellation.ipynb @@ -1,81 +1,81 @@ { "cells": [ -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Cancellation Constructs" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Cancellation Constructs " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows how the `cancel` directive can be used to terminate an OpenMP region. Although the `cancel` construct terminates the OpenMP worksharing region, programmers must still track the exception through the pointer ex and issue a cancellation for the `parallel` region if an exception has been raised. The master thread checks the exception pointer to make sure that the exception is properly handled in the sequential part. If cancellation of the `parallel` region has been requested, some threads might have executed `phase_1()` . However, it is guaranteed that none of the threads executed `phase_2()` ." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows how the `cancel` directive can be used to terminate an OpenMP region. Although the `cancel` construct terminates the OpenMP worksharing region, programmers must still track the exception through the pointer ex and issue a cancellation for the `parallel` region if an exception has been raised. The master thread checks the exception pointer to make sure that the exception is properly handled in the sequential part. If cancellation of the `parallel` region has been requested, some threads might have executed `phase_1()` . However, it is guaranteed that none of the threads executed `phase_2()` . " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_cancellation.1.cpp" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_cancellation.1.cpp " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example illustrates the use of the `cancel` construct in error handling. If there is an error condition from the `allocate` statement, the cancellation is activated. The encountering thread sets the shared variable `err` and other threads of the binding thread set proceed to the end of the worksharing construct after the cancellation has been activated. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example illustrates the use of the `cancel` construct in error handling. If there is an error condition from the `allocate` statement, the cancellation is activated. The encountering thread sets the shared variable `err` and other threads of the binding thread set proceed to the end of the worksharing construct after the cancellation has been activated. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_cancellation.1.f90" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_cancellation.1.f90 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows how to cancel a parallel search on a binary tree as soon as the search value has been detected. The code creates a task to descend into the child nodes of the current tree node. If the search value has been found, the code remembers the tree node with the found value through an `atomic` write to the result variable and then cancels execution of all search tasks. The function `search_tree_parallel` groups all search tasks into a single task group to control the effect of the `cancel taskgroup` directive. The _level_ argument is used to create undeferred tasks after the first ten levels of the tree." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows how to cancel a parallel search on a binary tree as soon as the search value has been detected. The code creates a task to descend into the child nodes of the current tree node. If the search value has been found, the code remembers the tree node with the found value through an `atomic` write to the result variable and then cancels execution of all search tasks. The function `search_tree_parallel` groups all search tasks into a single task group to control the effect of the `cancel taskgroup` directive. The _level_ argument is used to create undeferred tasks after the first ten levels of the tree. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_cancellation.2.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_cancellation.2.c " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following is the equivalent parallel search example in Fortran." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following is the equivalent parallel search example in Fortran. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_cancellation.2.f90" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_cancellation.2.f90 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_carrays_fpriv.ipynb b/notebook/Examples_carrays_fpriv.ipynb index f2687fa..d4835fb 100644 --- a/notebook/Examples_carrays_fpriv.ipynb +++ b/notebook/Examples_carrays_fpriv.ipynb @@ -1,109 +1,109 @@ { "cells": [ -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### C/C++ Arrays in a `firstprivate` Clause" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### C/C++ Arrays in a `firstprivate` Clause " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ccppspecificstart" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ccppspecificstart " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example illustrates the size and value of list items of array or pointer type in a `firstprivate` clause . The size of new list items is based on the type of the corresponding original list item, as determined by the base language." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example illustrates the size and value of list items of array or pointer type in a `firstprivate` clause . The size of new list items is based on the type of the corresponding original list item, as determined by the base language. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In this example:" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In this example: " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* The type of `A` is array of two arrays of two ints." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* The type of `A` is array of two arrays of two ints. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* The type of `B` is adjusted to pointer to array of `n` ints, because it is a function parameter." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* The type of `B` is adjusted to pointer to array of `n` ints, because it is a function parameter. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* The type of `C` is adjusted to pointer to int, because it is a function parameter." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* The type of `C` is adjusted to pointer to int, because it is a function parameter. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* The type of `D` is array of two arrays of two ints." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* The type of `D` is array of two arrays of two ints. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* The type of `E` is array of `n` arrays of `n` ints. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"* The type of `E` is array of `n` arrays of `n` ints. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Note that `B` and `E` involve variable length array types." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Note that `B` and `E` involve variable length array types. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The new items of array type are initialized as if each integer element of the original array is assigned to the corresponding element of the new array. Those of pointer type are initialized as if by assignment from the original \n", -"* to the new item." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The new items of array type are initialized as if each integer element of the original array is assigned to the corresponding element of the new array. Those of pointer type are initialized as if by assignment from the original \n", +"* to the new item. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_carrays_fpriv.1.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_carrays_fpriv.1.c " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ccppspecificend" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ccppspecificend " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_collapse.ipynb b/notebook/Examples_collapse.ipynb index 7d2dce0..d119dc4 100644 --- a/notebook/Examples_collapse.ipynb +++ b/notebook/Examples_collapse.ipynb @@ -1,134 +1,134 @@ { "cells": [ -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### The `collapse` Clause" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### The `collapse` Clause " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the following example, the `k` and `j` loops are associated with the loop construct. So the iterations of the `k` and `j` loops are collapsed into one loop with a larger iteration space, and that loop is then divided among the threads in the current team. Since the `i` loop is not associated with the loop construct, it is not collapsed, and the `i` loop is executed sequentially in its entirety in every iteration of the collapsed `k` and `j` loop. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the following example, the `k` and `j` loops are associated with the loop construct. So the iterations of the `k` and `j` loops are collapsed into one loop with a larger iteration space, and that loop is then divided among the threads in the current team. Since the `i` loop is not associated with the loop construct, it is not collapsed, and the `i` loop is executed sequentially in its entirety in every iteration of the collapsed `k` and `j` loop. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The variable `j` can be omitted from the `private` clause when the `collapse` clause is used since it is implicitly private. However, if the `collapse` clause is omitted then `j` will be shared if it is omitted from the `private` clause. In either case, `k` is implicitly private and could be omitted from the `private` clause." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The variable `j` can be omitted from the `private` clause when the `collapse` clause is used since it is implicitly private. However, if the `collapse` clause is omitted then `j` will be shared if it is omitted from the `private` clause. In either case, `k` is implicitly private and could be omitted from the `private` clause. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_collapse.1.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_collapse.1.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_collapse.1.f" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_collapse.1.f " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the next example, the `k` and `j` loops are associated with the loop construct. So the iterations of the `k` and `j` loops are collapsed into one loop with a larger iteration space, and that loop is then divided among the threads in the current team." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the next example, the `k` and `j` loops are associated with the loop construct. So the iterations of the `k` and `j` loops are collapsed into one loop with a larger iteration space, and that loop is then divided among the threads in the current team. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The sequential execution of the iterations in the `k` and `j` loops determines the order of the iterations in the collapsed iteration space. This implies that in the sequentially last iteration of the collapsed iteration space, `k` will have the value `2` and `j` will have the value `3` . Since `klast` and `jlast` are `lastprivate` , their values are assigned by the sequentially last iteration of the collapsed `k` and `j` loop. This example prints: `2 3` ." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The sequential execution of the iterations in the `k` and `j` loops determines the order of the iterations in the collapsed iteration space. This implies that in the sequentially last iteration of the collapsed iteration space, `k` will have the value `2` and `j` will have the value `3` . Since `klast` and `jlast` are `lastprivate` , their values are assigned by the sequentially last iteration of the collapsed `k` and `j` loop. This example prints: `2 3` . " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_collapse.2.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_collapse.2.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_collapse.2.f" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_collapse.2.f " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The next example illustrates the interaction of the `collapse` and `ordered` clauses." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The next example illustrates the interaction of the `collapse` and `ordered` clauses. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the example, the loop construct has both a `collapse` clause and an `ordered` clause. The `collapse` clause causes the iterations of the `k` and `j` loops to be collapsed into one loop with a larger iteration space, and that loop is divided among the threads in the current team. An `ordered` clause is added to the loop construct, because an ordered region binds to the loop region arising from the loop construct." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the example, the loop construct has both a `collapse` clause and an `ordered` clause. The `collapse` clause causes the iterations of the `k` and `j` loops to be collapsed into one loop with a larger iteration space, and that loop is divided among the threads in the current team. An `ordered` clause is added to the loop construct, because an ordered region binds to the loop region arising from the loop construct. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " According to Section 2.12.8 of the OpenMP 4.0 specification, a thread must not execute more than one ordered region that binds to the same loop region. So the `collapse` clause is required for the example to be conforming. With the `collapse` clause, the iterations of the `k` and `j` loops are collapsed into one loop, and therefore only one ordered region will bind to the collapsed `k` and `j` loop. Without the `collapse` clause, there would be two ordered regions that bind to each iteration of the `k` loop (one arising from the first iteration of the `j` loop, and the other arising from the second iteration of the `j` loop)." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " According to Section 2.12.8 of the OpenMP 4.0 specification, a thread must not execute more than one ordered region that binds to the same loop region. So the `collapse` clause is required for the example to be conforming. With the `collapse` clause, the iterations of the `k` and `j` loops are collapsed into one loop, and therefore only one ordered region will bind to the collapsed `k` and `j` loop. Without the `collapse` clause, there would be two ordered regions that bind to each iteration of the `k` loop (one arising from the first iteration of the `j` loop, and the other arising from the second iteration of the `j` loop). " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The code prints" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The code prints " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " `0 1 1` `0 1 2` `0 2 1` `1 2 2` `1 3 1` `1 3 2` " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " `0 1 1` `0 1 2` `0 2 1` `1 2 2` `1 3 1` `1 3 2` " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_collapse.3.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_collapse.3.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_collapse.3.f" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_collapse.3.f " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_cond_comp.ipynb b/notebook/Examples_cond_comp.ipynb index 864f9fb..fcd809b 100644 --- a/notebook/Examples_cond_comp.ipynb +++ b/notebook/Examples_cond_comp.ipynb @@ -1,63 +1,63 @@ { "cells": [ -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Conditional Compilation" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Conditional Compilation " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ccppspecificstart The following example illustrates the use of conditional compilation using the OpenMP macro `_OPENMP` . With OpenMP compilation, the `_OPENMP` macro becomes defined." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ccppspecificstart The following example illustrates the use of conditional compilation using the OpenMP macro `_OPENMP` . With OpenMP compilation, the `_OPENMP` macro becomes defined. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_cond_comp.1.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_cond_comp.1.c " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ccppspecificend" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ccppspecificend " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " fortranspecificstart The following example illustrates the use of the conditional compilation sentinel. With OpenMP compilation, the conditional compilation sentinel `!$` is recognized and treated as two spaces. In fixed form source, statements guarded by the sentinel must start after column 6." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " fortranspecificstart The following example illustrates the use of the conditional compilation sentinel. With OpenMP compilation, the conditional compilation sentinel `!$` is recognized and treated as two spaces. In fixed form source, statements guarded by the sentinel must start after column 6. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_cond_comp.1.f" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_cond_comp.1.f " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " fortranspecificend" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " fortranspecificend " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_copyin.ipynb b/notebook/Examples_copyin.ipynb index 7ce6dfb..c7c13e0 100644 --- a/notebook/Examples_copyin.ipynb +++ b/notebook/Examples_copyin.ipynb @@ -1,42 +1,42 @@ { "cells": [ -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### The `copyin` Clause" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### The `copyin` Clause " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `copyin` clause is used to initialize threadprivate data upon entry to a `parallel` region. The value of the threadprivate variable in the master thread is copied to the threadprivate variable of each other team member." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `copyin` clause is used to initialize threadprivate data upon entry to a `parallel` region. The value of the threadprivate variable in the master thread is copied to the threadprivate variable of each other team member. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_copyin.1.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_copyin.1.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_copyin.1.f" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_copyin.1.f " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_copyprivate.ipynb b/notebook/Examples_copyprivate.ipynb index e887184..23479c0 100644 --- a/notebook/Examples_copyprivate.ipynb +++ b/notebook/Examples_copyprivate.ipynb @@ -1,120 +1,120 @@ { "cells": [ -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### The `copyprivate` Clause" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### The `copyprivate` Clause " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `copyprivate` clause can be used to broadcast values acquired by a single thread directly to all instances of the private variables in the other threads. In this example, if the routine is called from the sequential part, its behavior is not affected by the presence of the directives. If it is called from a `parallel` region, then the actual arguments with which `a` and `b` are associated must be private. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `copyprivate` clause can be used to broadcast values acquired by a single thread directly to all instances of the private variables in the other threads. In this example, if the routine is called from the sequential part, its behavior is not affected by the presence of the directives. If it is called from a `parallel` region, then the actual arguments with which `a` and `b` are associated must be private. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The thread that executes the structured block associated with the `single` construct broadcasts the values of the private variables `a` , `b` , `x` , and `y` from its implicit task's data environment to the data environments of the other implicit tasks in the thread team. The broadcast completes before any of the threads have left the barrier at the end of the construct." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The thread that executes the structured block associated with the `single` construct broadcasts the values of the private variables `a` , `b` , `x` , and `y` from its implicit task's data environment to the data environments of the other implicit tasks in the thread team. The broadcast completes before any of the threads have left the barrier at the end of the construct. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_copyprivate.1.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_copyprivate.1.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_copyprivate.1.f" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_copyprivate.1.f " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In this example, assume that the input must be performed by the master thread. Since the `master` construct does not support the `copyprivate` clause, it cannot broadcast the input value that is read. However, `copyprivate` is used to broadcast an address where the input value is stored." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In this example, assume that the input must be performed by the master thread. Since the `master` construct does not support the `copyprivate` clause, it cannot broadcast the input value that is read. However, `copyprivate` is used to broadcast an address where the input value is stored. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_copyprivate.2.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_copyprivate.2.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_copyprivate.2.f" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_copyprivate.2.f " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Suppose that the number of lock variables required within a `parallel` region cannot easily be determined prior to entering it. The `copyprivate` clause can be used to provide access to shared lock variables that are allocated within that `parallel` region." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Suppose that the number of lock variables required within a `parallel` region cannot easily be determined prior to entering it. The `copyprivate` clause can be used to provide access to shared lock variables that are allocated within that `parallel` region. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_copyprivate.3.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_copyprivate.3.c " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " fortranspecificstartfnexample{copyprivate}{3}" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " fortranspecificstartfnexample{copyprivate}{3} " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Note that the effect of the `copyprivate` clause on a variable with the `allocatable` attribute is different than on a variable with the `pointer` attribute. The value of `A` is copied (as if by intrinsic assignment) and the pointer `B` is copied (as if by pointer assignment) to the corresponding list items in the other implicit tasks belonging to the `parallel` region. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Note that the effect of the `copyprivate` clause on a variable with the `allocatable` attribute is different than on a variable with the `pointer` attribute. The value of `A` is copied (as if by intrinsic assignment) and the pointer `B` is copied (as if by pointer assignment) to the corresponding list items in the other implicit tasks belonging to the `parallel` region. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_copyprivate.4.f" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_copyprivate.4.f " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " fortranspecificend" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " fortranspecificend " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_cpp_reference.ipynb b/notebook/Examples_cpp_reference.ipynb index dfffba8..9ceeb4a 100644 --- a/notebook/Examples_cpp_reference.ipynb +++ b/notebook/Examples_cpp_reference.ipynb @@ -1,51 +1,51 @@ { "cells": [ -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### C++ Reference in Data-Sharing Clauses" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### C++ Reference in Data-Sharing Clauses " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_cppspecificstart" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_cppspecificstart " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " C++ reference types are allowed in data-sharing attribute clauses as of OpenMP 4.5, except for the `threadprivate` , `copyin` and `copyprivate` clauses. (See the Data-Sharing Attribute Clauses Section of the 4.5 OpenMP specification.) When a variable with C++ reference type is privatized, the object the reference refers to is privatized in addition to the reference itself. The following example shows the use of reference types in data-sharing clauses in the usual way. Additionally it shows how the data-sharing of formal arguments with a C++ reference type on an orphaned task generating construct is determined implicitly. (See the Data-sharing Attribute Rules for Variables Referenced in a Construct Section of the 4.5 OpenMP specification.)" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " C++ reference types are allowed in data-sharing attribute clauses as of OpenMP 4.5, except for the `threadprivate` , `copyin` and `copyprivate` clauses. (See the Data-Sharing Attribute Clauses Section of the 4.5 OpenMP specification.) When a variable with C++ reference type is privatized, the object the reference refers to is privatized in addition to the reference itself. The following example shows the use of reference types in data-sharing clauses in the usual way. Additionally it shows how the data-sharing of formal arguments with a C++ reference type on an orphaned task generating construct is determined implicitly. (See the Data-sharing Attribute Rules for Variables Referenced in a Construct Section of the 4.5 OpenMP specification.) " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_cppnexamplecpp_reference1" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_cppnexamplecpp_reference1 " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_cppspecificend" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_cppspecificend " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_critical.ipynb b/notebook/Examples_critical.ipynb index 9b3cb3f..e4774cf 100644 --- a/notebook/Examples_critical.ipynb +++ b/notebook/Examples_critical.ipynb @@ -1,67 +1,67 @@ { "cells": [ -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### The `critical` Construct" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### The `critical` Construct " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example includes several `critical` constructs. The example illustrates a queuing model in which a task is dequeued and worked on. To guard against multiple threads dequeuing the same task, the dequeuing operation must be in a `critical` region. Because the two queues in this example are independent, they are protected by `critical` constructs with different names, _xaxis_ and _yaxis_ ." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example includes several `critical` constructs. The example illustrates a queuing model in which a task is dequeued and worked on. To guard against multiple threads dequeuing the same task, the dequeuing operation must be in a `critical` region. Because the two queues in this example are independent, they are protected by `critical` constructs with different names, _xaxis_ and _yaxis_ . " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_critical.1.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_critical.1.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_critical.1.f" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_critical.1.f " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example extends the previous example by adding the `hint` clause to the `critical` constructs." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example extends the previous example by adding the `hint` clause to the `critical` constructs. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_critical.2.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_critical.2.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_critical.2.f" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_critical.2.f " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_declare_target.ipynb b/notebook/Examples_declare_target.ipynb index 99625a4..ac21458 100644 --- a/notebook/Examples_declare_target.ipynb +++ b/notebook/Examples_declare_target.ipynb @@ -1,311 +1,311 @@ { "cells": [ -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### `declare` `target` Construct" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### `declare` `target` Construct " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### `declare` `target` and `end` `declare` `target` for a Function" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### `declare` `target` and `end` `declare` `target` for a Function " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows how the `declare` `target` directive is used to indicate that the corresponding call inside a `target` region is to a `fib` function that can execute on the default target device." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows how the `declare` `target` directive is used to indicate that the corresponding call inside a `target` region is to a `fib` function that can execute on the default target device. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " A version of the function is also available on the host device. When the `if` clause conditional expression on the `target` construct evaluates to _false_ , the `target` region (thus `fib` ) will execute on the host device." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " A version of the function is also available on the host device. When the `if` clause conditional expression on the `target` construct evaluates to _false_ , the `target` region (thus `fib` ) will execute on the host device. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " For C/C++ codes the declaration of the function `fib` appears between the `declare` `target` and `end` `declare` `target` directives." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " For C/C++ codes the declaration of the function `fib` appears between the `declare` `target` and `end` `declare` `target` directives. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_declare_target.1.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_declare_target.1.c " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The Fortran `fib` subroutine contains a `declare` `target` declaration to indicate to the compiler to create an device executable version of the procedure. The subroutine name has not been included on the `declare` `target` directive and is, therefore, implicitly assumed." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The Fortran `fib` subroutine contains a `declare` `target` declaration to indicate to the compiler to create an device executable version of the procedure. The subroutine name has not been included on the `declare` `target` directive and is, therefore, implicitly assumed. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The program uses the `module_fib` module, which presents an explicit interface to the compiler with the `declare` `target` declarations for processing the `fib` call." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The program uses the `module_fib` module, which presents an explicit interface to the compiler with the `declare` `target` declarations for processing the `fib` call. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_declare_target.1.f90" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_declare_target.1.f90 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The next Fortran example shows the use of an external subroutine. Without an explicit interface (through module use or an interface block) the `declare` `target` declarations within a external subroutine are unknown to the main program unit; therefore, a `declare` `target` must be provided within the program scope for the compiler to determine that a target binary should be available." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The next Fortran example shows the use of an external subroutine. Without an explicit interface (through module use or an interface block) the `declare` `target` declarations within a external subroutine are unknown to the main program unit; therefore, a `declare` `target` must be provided within the program scope for the compiler to determine that a target binary should be available. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_declare_target.2.f90" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_declare_target.2.f90 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### `declare` `target` Construct for Class Type" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### `declare` `target` Construct for Class Type " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_cppspecificstart" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_cppspecificstart " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows how the `declare` `target` and `end` `declare` `target` directives are used to enclose the declaration of a variable _varY_ with a class type `typeY` . The member function `typeY::foo()` cannot be accessed on a target device because its declaration did not appear between `declare` `target` and `end` `declare` `target` directives." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows how the `declare` `target` and `end` `declare` `target` directives are used to enclose the declaration of a variable _varY_ with a class type `typeY` . The member function `typeY::foo()` cannot be accessed on a target device because its declaration did not appear between `declare` `target` and `end` `declare` `target` directives. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_cppnexampledeclare_target2" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_cppnexampledeclare_target2 " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_cppspecificend" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_cppspecificend " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### `declare` `target` and `end` `declare` `target` for Variables" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### `declare` `target` and `end` `declare` `target` for Variables " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following examples show how the `declare` `target` and `end` `declare` `target` directives are used to indicate that global variables are mapped to the implicit device data environment of each target device." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following examples show how the `declare` `target` and `end` `declare` `target` directives are used to indicate that global variables are mapped to the implicit device data environment of each target device. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the following example, the declarations of the variables _p_ , _v1_ , and _v2_ appear between `declare` `target` and `end` `declare` `target` directives indicating that the variables are mapped to the implicit device data environment of each target device. The `target` `update` directive is then used to manage the consistency of the variables _p_ , _v1_ , and _v2_ between the data environment of the encountering host device task and the implicit device data environment of the default target device." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the following example, the declarations of the variables _p_ , _v1_ , and _v2_ appear between `declare` `target` and `end` `declare` `target` directives indicating that the variables are mapped to the implicit device data environment of each target device. The `target` `update` directive is then used to manage the consistency of the variables _p_ , _v1_ , and _v2_ between the data environment of the encountering host device task and the implicit device data environment of the default target device. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_declare_target.3.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_declare_target.3.c " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The Fortran version of the above C code uses a different syntax. Fortran modules use a list syntax on the `declare` `target` directive to declare mapped variables." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The Fortran version of the above C code uses a different syntax. Fortran modules use a list syntax on the `declare` `target` directive to declare mapped variables. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_declare_target.3.f90" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_declare_target.3.f90 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example also indicates that the function `Pfun()` is available on the target device, as well as the variable _Q_ , which is mapped to the implicit device data environment of each target device. The `target` `update` directive is then used to manage the consistency of the variable _Q_ between the data environment of the encountering host device task and the implicit device data environment of the default target device." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example also indicates that the function `Pfun()` is available on the target device, as well as the variable _Q_ , which is mapped to the implicit device data environment of each target device. The `target` `update` directive is then used to manage the consistency of the variable _Q_ between the data environment of the encountering host device task and the implicit device data environment of the default target device. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the following example, the function and variable declarations appear between the `declare` `target` and `end` `declare` `target` directives." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the following example, the function and variable declarations appear between the `declare` `target` and `end` `declare` `target` directives. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_declare_target.4.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_declare_target.4.c " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The Fortran version of the above C code uses a different syntax. In Fortran modules a list syntax on the `declare` `target` directive is used to declare mapped variables and procedures. The _N_ and _Q_ variables are declared as a comma separated list. When the `declare` `target` directive is used to declare just the procedure, the procedure name need not be listed -- it is implicitly assumed, as illustrated in the `Pfun()` function." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The Fortran version of the above C code uses a different syntax. In Fortran modules a list syntax on the `declare` `target` directive is used to declare mapped variables and procedures. The _N_ and _Q_ variables are declared as a comma separated list. When the `declare` `target` directive is used to declare just the procedure, the procedure name need not be listed -- it is implicitly assumed, as illustrated in the `Pfun()` function. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_declare_target.4.f90" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_declare_target.4.f90 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### `declare` `target` and `end` `declare` `target` with `declare` `simd` " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### `declare` `target` and `end` `declare` `target` with `declare` `simd` " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows how the `declare` `target` and `end` `declare` `target` directives are used to indicate that a function is available on a target device. The `declare` `simd` directive indicates that there is a SIMD version of the function `P()` that is available on the target device as well as one that is available on the host device." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows how the `declare` `target` and `end` `declare` `target` directives are used to indicate that a function is available on a target device. The `declare` `simd` directive indicates that there is a SIMD version of the function `P()` that is available on the target device as well as one that is available on the host device. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_declare_target.5.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_declare_target.5.c " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The Fortran version of the above C code uses a different syntax. Fortran modules use a list syntax of the `declare` `target` declaration for the mapping. Here the _N_ and _Q_ variables are declared in the list form as a comma separated list. The function declaration does not use a list and implicitly assumes the function name. In this Fortran example row and column indices are reversed relative to the C/C++ example, as is usual for codes optimized for memory access." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The Fortran version of the above C code uses a different syntax. Fortran modules use a list syntax of the `declare` `target` declaration for the mapping. Here the _N_ and _Q_ variables are declared in the list form as a comma separated list. The function declaration does not use a list and implicitly assumes the function name. In this Fortran example row and column indices are reversed relative to the C/C++ example, as is usual for codes optimized for memory access. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_declare_target.5.f90" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_declare_target.5.f90 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### `declare` ~ `target` Directive with `link` Clause" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### `declare` ~ `target` Directive with `link` Clause " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the OpenMP 4.5 standard the `declare` ~ `target` directive was extended to allow static data to be mapped, emph{when needed}, through a `link` clause." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the OpenMP 4.5 standard the `declare` ~ `target` directive was extended to allow static data to be mapped, emph{when needed}, through a `link` clause. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Data storage for items listed in the `link` clause becomes available on the device when it is mapped implicitly or explicitly in a `map` clause, and it persists for the scope of the mapping (as specified by a `target` construct, a `target` ~ `data` construct, or `target` ~ `enter/exit` ~ `data` constructs)." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Data storage for items listed in the `link` clause becomes available on the device when it is mapped implicitly or explicitly in a `map` clause, and it persists for the scope of the mapping (as specified by a `target` construct, a `target` ~ `data` construct, or `target` ~ `enter/exit` ~ `data` constructs). " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Tip: When all the global data items will not fit on a device and are not needed simultaneously, use the `link` clause and map the data only when it is needed." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Tip: When all the global data items will not fit on a device and are not needed simultaneously, use the `link` clause and map the data only when it is needed. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following C and Fortran examples show two sets of data (single precision and double precision) that are global on the host for the entire execution on the host; but are only used globally on the device for part of the program execution. The single precision data are allocated and persist only for the first `target` region. Similarly, the double precision data are in scope on the device only for the second `target` region." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following C and Fortran examples show two sets of data (single precision and double precision) that are global on the host for the entire execution on the host; but are only used globally on the device for part of the program execution. The single precision data are allocated and persist only for the first `target` region. Similarly, the double precision data are in scope on the device only for the second `target` region. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_declare_target.6.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_declare_target.6.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_declare_target.6.f90" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_declare_target.6.f90 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_default_none.ipynb b/notebook/Examples_default_none.ipynb index e4dd1c0..50044f0 100644 --- a/notebook/Examples_default_none.ipynb +++ b/notebook/Examples_default_none.ipynb @@ -1,56 +1,56 @@ { "cells": [ -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### The `default(none)` Clause" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### The `default(none)` Clause " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example distinguishes the variables that are affected by the `default(none)` clause from those that are not. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example distinguishes the variables that are affected by the `default(none)` clause from those that are not. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ccppspecificstart Beginning with OpenMP 4.0, variables with `const` -qualified type and no mutable member are no longer predetermined shared. Thus, these variables (variable _c_ in the example) need to be explicitly listed in data-sharing attribute clauses when the `default(none)` clause is specified." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ccppspecificstart Beginning with OpenMP 4.0, variables with `const` -qualified type and no mutable member are no longer predetermined shared. Thus, these variables (variable _c_ in the example) need to be explicitly listed in data-sharing attribute clauses when the `default(none)` clause is specified. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_default_none.1.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_default_none.1.c " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ccppspecificend" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ccppspecificend " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_default_none.1.f" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_default_none.1.f " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_device.ipynb b/notebook/Examples_device.ipynb index c7e7123..cb48d50 100644 --- a/notebook/Examples_device.ipynb +++ b/notebook/Examples_device.ipynb @@ -1,157 +1,157 @@ { "cells": [ -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Device Routines" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Device Routines " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### `omp_is_initial_device` Routine" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### `omp_is_initial_device` Routine " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows how the `omp_is_initial_device` runtime library routine can be used to query if a code is executing on the initial host device or on a target device. The example then sets the number of threads in the `parallel` region based on where the code is executing." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows how the `omp_is_initial_device` runtime library routine can be used to query if a code is executing on the initial host device or on a target device. The example then sets the number of threads in the `parallel` region based on where the code is executing. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_device.1.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_device.1.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_device.1.f90" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_device.1.f90 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### `omp_get_num_devices` Routine" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### `omp_get_num_devices` Routine " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows how the `omp_get_num_devices` runtime library routine can be used to determine the number of devices." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows how the `omp_get_num_devices` runtime library routine can be used to determine the number of devices. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_device.2.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_device.2.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_device.2.f90" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_device.2.f90 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "subsection{ `omp_set_default_device` and " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "subsection{ `omp_set_default_device` and " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " `omp_get_default_device` Routines}" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " `omp_get_default_device` Routines} " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows how the `omp_set_default_device` and `omp_get_default_device` runtime library routines can be used to set the default device and determine the default device respectively." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows how the `omp_set_default_device` and `omp_get_default_device` runtime library routines can be used to set the default device and determine the default device respectively. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_device.3.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_device.3.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_device.3.f90" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_device.3.f90 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### Target Memory and Device Pointers Routines" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### Target Memory and Device Pointers Routines " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows how to create space on a device, transfer data to and from that space, and free the space, using API calls. The API calls directly execute allocation, copy and free operations on the device, without invoking any mapping through a `target` directive. The `omp_target_alloc` routine allocates space and returns a device pointer for referencing the space in the `omp_target_memcpy` API routine on the host. The `omp_target_free` routine frees the space on the device." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows how to create space on a device, transfer data to and from that space, and free the space, using API calls. The API calls directly execute allocation, copy and free operations on the device, without invoking any mapping through a `target` directive. The `omp_target_alloc` routine allocates space and returns a device pointer for referencing the space in the `omp_target_memcpy` API routine on the host. The `omp_target_free` routine frees the space on the device. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The example also illustrates how to access that space in a `target` region by exposing the device pointer in an `is_device_ptr` clause." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The example also illustrates how to access that space in a `target` region by exposing the device pointer in an `is_device_ptr` clause. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The example creates an array of cosine values on the default device, to be used on the host device. The function fails if a default device is not available." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The example creates an array of cosine values on the default device, to be used on the host device. The function fails if a default device is not available. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_device.4.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_device.4.c " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_doacross.ipynb b/notebook/Examples_doacross.ipynb index f21e198..aeff986 100644 --- a/notebook/Examples_doacross.ipynb +++ b/notebook/Examples_doacross.ipynb @@ -1,124 +1,124 @@ { "cells": [ -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Doacross Loop Nest" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Doacross Loop Nest " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " An `ordered` clause can be used on a loop construct with an integer parameter argument to define the number of associated loops within a _doacross loop nest_ where cross-iteration dependences exist. A `depend` clause on an `ordered` construct within an ordered loop describes the dependences of the _doacross_ loops. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " An `ordered` clause can be used on a loop construct with an integer parameter argument to define the number of associated loops within a _doacross loop nest_ where cross-iteration dependences exist. A `depend` clause on an `ordered` construct within an ordered loop describes the dependences of the _doacross_ loops. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the code below, the `depend(sink:i-1)` clause defines an _i-1_ to _i_ cross-iteration dependence that specifies a wait point for the completion of computation from iteration _i-1_ before proceeding to the subsequent statements. The `depend(source)` clause indicates the completion of computation from the current iteration ( _i_ ) to satisfy the cross-iteration dependence that arises from the iteration. For this example the same sequential ordering could have been achieved with an `ordered` clause without a parameter, on the loop directive, and a single `ordered` directive without the `depend` clause specified for the statement executing the _bar_ function." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the code below, the `depend(sink:i-1)` clause defines an _i-1_ to _i_ cross-iteration dependence that specifies a wait point for the completion of computation from iteration _i-1_ before proceeding to the subsequent statements. The `depend(source)` clause indicates the completion of computation from the current iteration ( _i_ ) to satisfy the cross-iteration dependence that arises from the iteration. For this example the same sequential ordering could have been achieved with an `ordered` clause without a parameter, on the loop directive, and a single `ordered` directive without the `depend` clause specified for the statement executing the _bar_ function. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_doacross.1.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_doacross.1.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_doacross.1.f90" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_doacross.1.f90 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following code is similar to the previous example but with _doacross loop nest_ extended to two nested loops, _i_ and _j_ , as specified by the `ordered(2)` clause on the loop directive. In the C/C++ code, the _i_ and _j_ loops are the first and second associated loops, respectively, whereas in the Fortran code, the _j_ and _i_ loops are the first and second associated loops, respectively. The `depend(sink:i-1,j)` and `depend(sink:i,j-1)` clauses in the C/C++ code define cross-iteration dependences in two dimensions from iterations ( _i-1, j_ ) and ( _i, j-1_ ) to iteration ( _i, j_ ). Likewise, the `depend(sink:j-1,i)` and `depend(sink:j,i-1)` clauses in the Fortran code define cross-iteration dependences from iterations ( _j-1, i_ ) and ( _j, i-1_ ) to iteration ( _j, i_ )." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following code is similar to the previous example but with _doacross loop nest_ extended to two nested loops, _i_ and _j_ , as specified by the `ordered(2)` clause on the loop directive. In the C/C++ code, the _i_ and _j_ loops are the first and second associated loops, respectively, whereas in the Fortran code, the _j_ and _i_ loops are the first and second associated loops, respectively. The `depend(sink:i-1,j)` and `depend(sink:i,j-1)` clauses in the C/C++ code define cross-iteration dependences in two dimensions from iterations ( _i-1, j_ ) and ( _i, j-1_ ) to iteration ( _i, j_ ). Likewise, the `depend(sink:j-1,i)` and `depend(sink:j,i-1)` clauses in the Fortran code define cross-iteration dependences from iterations ( _j-1, i_ ) and ( _j, i-1_ ) to iteration ( _j, i_ ). " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_doacross.2.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_doacross.2.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_doacross.2.f90" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_doacross.2.f90 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows the incorrect use of the `ordered` directive with a `depend` clause. There are two issues with the code. The first issue is a missing `ordered` ~ `depend(source)` directive, which could cause a deadlock. The second issue is the `depend(sink:i+1,j)` and `depend(sink:i,j+1)` clauses define dependences on lexicographically later source iterations ( _i+1, j_ ) and ( _i, j+1_ ), which could cause a deadlock as well since they may not start to execute until the current iteration completes." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows the incorrect use of the `ordered` directive with a `depend` clause. There are two issues with the code. The first issue is a missing `ordered` ~ `depend(source)` directive, which could cause a deadlock. The second issue is the `depend(sink:i+1,j)` and `depend(sink:i,j+1)` clauses define dependences on lexicographically later source iterations ( _i+1, j_ ) and ( _i, j+1_ ), which could cause a deadlock as well since they may not start to execute until the current iteration completes. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_doacross.3.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_doacross.3.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_doacross.3.f90" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_doacross.3.f90 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example illustrates the use of the `collapse` clause for a _doacross loop nest_ . The _i_ and _j_ loops are the associated loops for the collapsed loop as well as for the _doacross loop nest_ . The example also shows a compliant usage of the dependence source directive placed before the corresponding sink directive. Checking the completion of computation from previous iterations at the sink point can occur after the source statement." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example illustrates the use of the `collapse` clause for a _doacross loop nest_ . The _i_ and _j_ loops are the associated loops for the collapsed loop as well as for the _doacross loop nest_ . The example also shows a compliant usage of the dependence source directive placed before the corresponding sink directive. Checking the completion of computation from previous iterations at the sink point can occur after the source statement. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_doacross.4.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_doacross.4.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_doacross.4.f90" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_doacross.4.f90 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_flush_nolist.ipynb b/notebook/Examples_flush_nolist.ipynb index bb6132a..20af185 100644 --- a/notebook/Examples_flush_nolist.ipynb +++ b/notebook/Examples_flush_nolist.ipynb @@ -1,42 +1,42 @@ { "cells": [ -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### The `flush` Construct without a List" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### The `flush` Construct without a List " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example distinguishes the shared variables affected by a `flush` construct with no list from the shared objects that are not affected:" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example distinguishes the shared variables affected by a `flush` construct with no list from the shared objects that are not affected: " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_flush_nolist.1.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_flush_nolist.1.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_flush_nolist.1.f" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_flush_nolist.1.f " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_fort_do.ipynb b/notebook/Examples_fort_do.ipynb index 7369207..a69af2b 100644 --- a/notebook/Examples_fort_do.ipynb +++ b/notebook/Examples_fort_do.ipynb @@ -1,63 +1,63 @@ { "cells": [ -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Fortran Restrictions on the `do` Construct" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Fortran Restrictions on the `do` Construct " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " fortranspecificstart" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " fortranspecificstart " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " If an `end do` directive follows a _do-construct_ in which several `DO` statements share a `DO` termination statement, then a `do` directive can only be specified for the outermost of these `DO` statements. The following example contains correct usages of loop constructs:" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " If an `end do` directive follows a _do-construct_ in which several `DO` statements share a `DO` termination statement, then a `do` directive can only be specified for the outermost of these `DO` statements. The following example contains correct usages of loop constructs: " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_fort_do.1.f" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_fort_do.1.f " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example is non-conforming because the matching `do` directive for the `end do` does not precede the outermost loop:" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example is non-conforming because the matching `do` directive for the `end do` does not precede the outermost loop: " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_fort_do.2.f" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_fort_do.2.f " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " fortranspecificend" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " fortranspecificend " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_fort_loopvar.ipynb b/notebook/Examples_fort_loopvar.ipynb index c6822a8..90b4061 100644 --- a/notebook/Examples_fort_loopvar.ipynb +++ b/notebook/Examples_fort_loopvar.ipynb @@ -1,63 +1,63 @@ { "cells": [ -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Fortran Private Loop Iteration Variables" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Fortran Private Loop Iteration Variables " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " fortranspecificstart" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " fortranspecificstart " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In general loop iteration variables will be private, when used in the _do-loop_ of a `do` and `parallel do` construct or in sequential loops in a `parallel` construct (see Section 2.7.1 and Section 2.14.1 of the OpenMP 4.0 specification). In the following example of a sequential loop in a `parallel` construct the loop iteration variable _I_ will be private." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In general loop iteration variables will be private, when used in the _do-loop_ of a `do` and `parallel do` construct or in sequential loops in a `parallel` construct (see Section 2.7.1 and Section 2.14.1 of the OpenMP 4.0 specification). In the following example of a sequential loop in a `parallel` construct the loop iteration variable _I_ will be private. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_ffreenexamplefort_loopvar1" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_ffreenexamplefort_loopvar1 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In exceptional cases, loop iteration variables can be made shared, as in the following example:" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In exceptional cases, loop iteration variables can be made shared, as in the following example: " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_ffreenexamplefort_loopvar2" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_ffreenexamplefort_loopvar2 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Note however that the use of shared loop iteration variables can easily lead to race conditions. fortranspecificend" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Note however that the use of shared loop iteration variables can easily lead to race conditions. fortranspecificend " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_fort_race.ipynb b/notebook/Examples_fort_race.ipynb index 1fa34d3..a38e763 100644 --- a/notebook/Examples_fort_race.ipynb +++ b/notebook/Examples_fort_race.ipynb @@ -1,47 +1,47 @@ { "cells": [ -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Race Conditions Caused by Implied Copies of Shared Variables in Fortran" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Race Conditions Caused by Implied Copies of Shared Variables in Fortran " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " fortranspecificstart" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " fortranspecificstart " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example contains a race condition, because the shared variable, which is an array section, is passed as an actual argument to a routine that has an assumed-size array as its dummy argument. The subroutine call passing an array section argument may cause the compiler to copy the argument into a temporary location prior to the call and copy from the temporary location into the original variable when the subroutine returns. This copying would cause races in the `parallel` region." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example contains a race condition, because the shared variable, which is an array section, is passed as an actual argument to a routine that has an assumed-size array as its dummy argument. The subroutine call passing an array section argument may cause the compiler to copy the argument into a temporary location prior to the call and copy from the temporary location into the original variable when the subroutine returns. This copying would cause races in the `parallel` region. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_ffreenexamplefort_race1" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_ffreenexamplefort_race1 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " fortranspecificend" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " fortranspecificend " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_fort_sa_private.ipynb b/notebook/Examples_fort_sa_private.ipynb index 590ac9b..7c7955b 100644 --- a/notebook/Examples_fort_sa_private.ipynb +++ b/notebook/Examples_fort_sa_private.ipynb @@ -1,91 +1,91 @@ { "cells": [ -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Fortran Restrictions on Storage Association with the `private` Clause" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Fortran Restrictions on Storage Association with the `private` Clause " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " fortranspecificstart" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " fortranspecificstart " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following non-conforming examples illustrate the implications of the `private` clause rules with regard to storage association. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following non-conforming examples illustrate the implications of the `private` clause rules with regard to storage association. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_fort_sa_private.1.f" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_fort_sa_private.1.f " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_fort_sa_private.2.f" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_fort_sa_private.2.f " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_fort_sa_private.3.f" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_fort_sa_private.3.f " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -" blue line floater at top of this page for 'Fortran, cont.' [t!] linewitharrows{-1}{dashed}{Fortran (cont.)}{8em} " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +" blue line floater at top of this page for 'Fortran, cont.' [t!] linewitharrows{-1}{dashed}{Fortran (cont.)}{8em} " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_fort_sa_private.4.f" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_fort_sa_private.4.f " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_fort_sa_private.5.f" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_fort_sa_private.5.f " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " fortranspecificend" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " fortranspecificend " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_fort_sp_common.ipynb b/notebook/Examples_fort_sp_common.ipynb index fdd2d55..800445f 100644 --- a/notebook/Examples_fort_sp_common.ipynb +++ b/notebook/Examples_fort_sp_common.ipynb @@ -1,126 +1,126 @@ { "cells": [ -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Fortran Restrictions on `shared` and `private` Clauses with Common Blocks" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Fortran Restrictions on `shared` and `private` Clauses with Common Blocks " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " fortranspecificstart" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " fortranspecificstart " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " When a named common block is specified in a `private` , `firstprivate` , or `lastprivate` clause of a construct, none of its members may be declared in another data-sharing attribute clause on that construct. The following examples illustrate this point. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " When a named common block is specified in a `private` , `firstprivate` , or `lastprivate` clause of a construct, none of its members may be declared in another data-sharing attribute clause on that construct. The following examples illustrate this point. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example is conforming:" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example is conforming: " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_fort_sp_common.1.f" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_fort_sp_common.1.f " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example is also conforming:" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example is also conforming: " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_fort_sp_common.2.f" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_fort_sp_common.2.f " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -" blue line floater at top of this page for 'Fortran, cont.' [t!] linewitharrows{-1}{dashed}{Fortran (cont.)}{8em} " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +" blue line floater at top of this page for 'Fortran, cont.' [t!] linewitharrows{-1}{dashed}{Fortran (cont.)}{8em} " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example is conforming:" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example is conforming: " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_fort_sp_common.3.f" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_fort_sp_common.3.f " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example is non-conforming because `x` is a constituent element of `c` :" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example is non-conforming because `x` is a constituent element of `c` : " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_fort_sp_common.4.f" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_fort_sp_common.4.f " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example is non-conforming because a common block may not be declared both shared and private:" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example is non-conforming because a common block may not be declared both shared and private: " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_fort_sp_common.5.f" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_fort_sp_common.5.f " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " fortranspecificend" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " fortranspecificend " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_fpriv_sections.ipynb b/notebook/Examples_fpriv_sections.ipynb index 76d29de..3654615 100644 --- a/notebook/Examples_fpriv_sections.ipynb +++ b/notebook/Examples_fpriv_sections.ipynb @@ -1,42 +1,42 @@ { "cells": [ -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### The `firstprivate` Clause and the `sections` Construct" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### The `firstprivate` Clause and the `sections` Construct " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the following example of the `sections` construct the `firstprivate` clause is used to initialize the private copy of `section_count` of each thread. The problem is that the `section` constructs modify `section_count` , which breaks the independence of the `section` constructs. When different threads execute each section, both sections will print the value 1. When the same thread executes the two sections, one section will print the value 1 and the other will print the value 2. Since the order of execution of the two sections in this case is unspecified, it is unspecified which section prints which value. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the following example of the `sections` construct the `firstprivate` clause is used to initialize the private copy of `section_count` of each thread. The problem is that the `section` constructs modify `section_count` , which breaks the independence of the `section` constructs. When different threads execute each section, both sections will print the value 1. When the same thread executes the two sections, one section will print the value 1 and the other will print the value 2. Since the order of execution of the two sections in this case is unspecified, it is unspecified which section prints which value. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_fpriv_sections.1.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_fpriv_sections.1.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_fpriv_sections.1.f90" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_fpriv_sections.1.f90 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_get_nthrs.ipynb b/notebook/Examples_get_nthrs.ipynb index 73561e5..656169b 100644 --- a/notebook/Examples_get_nthrs.ipynb +++ b/notebook/Examples_get_nthrs.ipynb @@ -1,67 +1,67 @@ { "cells": [ -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### The `omp_get_num_threads` Routine" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### The `omp_get_num_threads` Routine " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the following example, the `omp_get_num_threads` call returns 1 in the sequential part of the code, so `np` will always be equal to 1. To determine the number of threads that will be deployed for the `parallel` region, the call should be inside the `parallel` region." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the following example, the `omp_get_num_threads` call returns 1 in the sequential part of the code, so `np` will always be equal to 1. To determine the number of threads that will be deployed for the `parallel` region, the call should be inside the `parallel` region. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_get_nthrs.1.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_get_nthrs.1.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_get_nthrs.1.f" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_get_nthrs.1.f " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows how to rewrite this program without including a query for the number of threads:" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows how to rewrite this program without including a query for the number of threads: " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_get_nthrs.2.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_get_nthrs.2.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_get_nthrs.2.f" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_get_nthrs.2.f " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_icv.ipynb b/notebook/Examples_icv.ipynb index 7027659..b2fb417 100644 --- a/notebook/Examples_icv.ipynb +++ b/notebook/Examples_icv.ipynb @@ -1,98 +1,98 @@ { "cells": [ -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Internal Control Variables (ICVs)" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Internal Control Variables (ICVs) " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " According to Section 2.3 of the OpenMP 4.0 specification, an OpenMP implementation must act as if there are ICVs that control the behavior of the program. This example illustrates two ICVs, _nthreads-var_ and _max-active-levels-var_ . The _nthreads-var_ ICV controls the number of threads requested for encountered parallel regions; there is one copy of this ICV per task. The _max-active-levels-var_ ICV controls the maximum number of nested active parallel regions; there is one copy of this ICV for the whole program." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " According to Section 2.3 of the OpenMP 4.0 specification, an OpenMP implementation must act as if there are ICVs that control the behavior of the program. This example illustrates two ICVs, _nthreads-var_ and _max-active-levels-var_ . The _nthreads-var_ ICV controls the number of threads requested for encountered parallel regions; there is one copy of this ICV per task. The _max-active-levels-var_ ICV controls the maximum number of nested active parallel regions; there is one copy of this ICV for the whole program. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the following example, the _nest-var_ , _max-active-levels-var_ , _dyn-var_ , and _nthreads-var_ ICVs are modified through calls to the runtime library routines `omp_set_nested` , `omp_set_max_active_levels` , ` omp_set_dynamic` , and `omp_set_num_threads` respectively. These ICVs affect the operation of `parallel` regions. Each implicit task generated by a `parallel` region has its own copy of the _nest-var, dyn-var_ , and _nthreads-var_ ICVs." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the following example, the _nest-var_ , _max-active-levels-var_ , _dyn-var_ , and _nthreads-var_ ICVs are modified through calls to the runtime library routines `omp_set_nested` , `omp_set_max_active_levels` , ` omp_set_dynamic` , and `omp_set_num_threads` respectively. These ICVs affect the operation of `parallel` regions. Each implicit task generated by a `parallel` region has its own copy of the _nest-var, dyn-var_ , and _nthreads-var_ ICVs. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the following example, the new value of _nthreads-var_ applies only to the implicit tasks that execute the call to `omp_set_num_threads` . There is one copy of the _max-active-levels-var_ ICV for the whole program and its value is the same for all tasks. This example assumes that nested parallelism is supported." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the following example, the new value of _nthreads-var_ applies only to the implicit tasks that execute the call to `omp_set_num_threads` . There is one copy of the _max-active-levels-var_ ICV for the whole program and its value is the same for all tasks. This example assumes that nested parallelism is supported. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The outer `parallel` region creates a team of two threads; each of the threads will execute one of the two implicit tasks generated by the outer `parallel` region." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The outer `parallel` region creates a team of two threads; each of the threads will execute one of the two implicit tasks generated by the outer `parallel` region. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Each implicit task generated by the outer `parallel` region calls `omp_set_num_threads(3)` , assigning the value 3 to its respective copy of _nthreads-var_ . Then each implicit task encounters an inner `parallel` region that creates a team of three threads; each of the threads will execute one of the three implicit tasks generated by that inner `parallel` region." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Each implicit task generated by the outer `parallel` region calls `omp_set_num_threads(3)` , assigning the value 3 to its respective copy of _nthreads-var_ . Then each implicit task encounters an inner `parallel` region that creates a team of three threads; each of the threads will execute one of the three implicit tasks generated by that inner `parallel` region. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Since the outer `parallel` region is executed by 2 threads, and the inner by 3, there will be a total of 6 implicit tasks generated by the two inner `parallel` regions." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Since the outer `parallel` region is executed by 2 threads, and the inner by 3, there will be a total of 6 implicit tasks generated by the two inner `parallel` regions. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Each implicit task generated by an inner `parallel` region will execute the call to `omp_set_num_threads(4)` , assigning the value 4 to its respective copy of _nthreads-var_ ." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Each implicit task generated by an inner `parallel` region will execute the call to `omp_set_num_threads(4)` , assigning the value 4 to its respective copy of _nthreads-var_ . " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The print statement in the outer `parallel` region is executed by only one of the threads in the team. So it will be executed only once." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The print statement in the outer `parallel` region is executed by only one of the threads in the team. So it will be executed only once. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The print statement in an inner `parallel` region is also executed by only one of the threads in the team. Since we have a total of two inner `parallel` regions, the print statement will be executed twice -- once per inner `parallel` region." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The print statement in an inner `parallel` region is also executed by only one of the threads in the team. Since we have a total of two inner `parallel` regions, the print statement will be executed twice -- once per inner `parallel` region. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_icv.1.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_icv.1.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_icv.1.f" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_icv.1.f " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_init_lock.ipynb b/notebook/Examples_init_lock.ipynb index 4b5fca7..2a57c07 100644 --- a/notebook/Examples_init_lock.ipynb +++ b/notebook/Examples_init_lock.ipynb @@ -1,42 +1,42 @@ { "cells": [ -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### The `omp_init_lock` Routine" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### The `omp_init_lock` Routine " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example demonstrates how to initialize an array of locks in a `parallel` region by using `omp_init_lock` ." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example demonstrates how to initialize an array of locks in a `parallel` region by using `omp_init_lock` . " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_init_lock.1.cpp" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_init_lock.1.cpp " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_init_lock.1.f" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_init_lock.1.f " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_init_lock_with_hint.ipynb b/notebook/Examples_init_lock_with_hint.ipynb index e0a1c75..64614f0 100644 --- a/notebook/Examples_init_lock_with_hint.ipynb +++ b/notebook/Examples_init_lock_with_hint.ipynb @@ -1,43 +1,43 @@ { "cells": [ -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -" #### The `omp_init_lock_with_hint` Routine" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +" #### The `omp_init_lock_with_hint` Routine " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example demonstrates how to initialize an array of locks in a `parallel` region by using `omp_init_lock_with_hint` . Note, hints are combined with an `|` or `+` operator in C/C++ and a `+` operator in Fortran." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example demonstrates how to initialize an array of locks in a `parallel` region by using `omp_init_lock_with_hint` . Note, hints are combined with an `|` or `+` operator in C/C++ and a `+` operator in Fortran. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_init_lock_with_hint.1.cpp" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_init_lock_with_hint.1.cpp " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_init_lock_with_hint.1.f" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_init_lock_with_hint.1.f " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_lastprivate.ipynb b/notebook/Examples_lastprivate.ipynb index ef4da87..4910ae0 100644 --- a/notebook/Examples_lastprivate.ipynb +++ b/notebook/Examples_lastprivate.ipynb @@ -1,42 +1,42 @@ { "cells": [ -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### The `lastprivate` Clause" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### The `lastprivate` Clause " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Correct execution sometimes depends on the value that the last iteration of a loop assigns to a variable. Such programs must list all such variables in a `lastprivate` clause so that the values of the variables are the same as when the loop is executed sequentially." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Correct execution sometimes depends on the value that the last iteration of a loop assigns to a variable. Such programs must list all such variables in a `lastprivate` clause so that the values of the variables are the same as when the loop is executed sequentially. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_lastprivate.1.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_lastprivate.1.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_lastprivate.1.f" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_lastprivate.1.f " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_linear_in_loop.ipynb b/notebook/Examples_linear_in_loop.ipynb index 3b365d6..2f28ef9 100644 --- a/notebook/Examples_linear_in_loop.ipynb +++ b/notebook/Examples_linear_in_loop.ipynb @@ -1,42 +1,42 @@ { "cells": [ -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### `linear` Clause in Loop Constructs" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### `linear` Clause in Loop Constructs " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows the use of the `linear` clause in a loop construct to allow the proper parallelization of a loop that contains an induction variable ( _j_ ). At the end of the execution of the loop construct, the original variable _j_ is updated with the value _N/2_ from the last iteration of the loop." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows the use of the `linear` clause in a loop construct to allow the proper parallelization of a loop that contains an induction variable ( _j_ ). At the end of the execution of the loop construct, the original variable _j_ is updated with the value _N/2_ from the last iteration of the loop. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_linear_in_loop.1.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_linear_in_loop.1.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_linear_in_loop.1.f90" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_linear_in_loop.1.f90 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_lock_owner.ipynb b/notebook/Examples_lock_owner.ipynb index b87883e..4f00112 100644 --- a/notebook/Examples_lock_owner.ipynb +++ b/notebook/Examples_lock_owner.ipynb @@ -1,49 +1,49 @@ { "cells": [ -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### Ownership of Locks" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### Ownership of Locks " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Ownership of locks has changed since OpenMP 2.5. In OpenMP 2.5, locks are owned by threads; so a lock released by the `omp_unset_lock` routine must be owned by the same thread executing the routine. Beginning with OpenMP 3.0, locks are owned by task regions; so a lock released by the `omp_unset_lock` routine in a task region must be owned by the same task region." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Ownership of locks has changed since OpenMP 2.5. In OpenMP 2.5, locks are owned by threads; so a lock released by the `omp_unset_lock` routine must be owned by the same thread executing the routine. Beginning with OpenMP 3.0, locks are owned by task regions; so a lock released by the `omp_unset_lock` routine in a task region must be owned by the same task region. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " This change in ownership requires extra care when using locks. The following program is conforming in OpenMP 2.5 because the thread that releases the lock `lck` in the parallel region is the same thread that acquired the lock in the sequential part of the program (master thread of parallel region and the initial thread are the same). However, it is not conforming beginning with OpenMP 3.0, because the task region that releases the lock `lck` is different from the task region that acquires the lock." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " This change in ownership requires extra care when using locks. The following program is conforming in OpenMP 2.5 because the thread that releases the lock `lck` in the parallel region is the same thread that acquired the lock in the sequential part of the program (master thread of parallel region and the initial thread are the same). However, it is not conforming beginning with OpenMP 3.0, because the task region that releases the lock `lck` is different from the task region that acquires the lock. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_lock_owner.1.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_lock_owner.1.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_lock_owner.1.f" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_lock_owner.1.f " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_locks.ipynb b/notebook/Examples_locks.ipynb index ee7c5ff..bab60c3 100644 --- a/notebook/Examples_locks.ipynb +++ b/notebook/Examples_locks.ipynb @@ -1,24 +1,24 @@ { "cells": [ -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Lock Routines" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Lock Routines " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " This section is about the use of lock routines for synchronization." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " This section is about the use of lock routines for synchronization. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_master.ipynb b/notebook/Examples_master.ipynb index 2c0c141..7780658 100644 --- a/notebook/Examples_master.ipynb +++ b/notebook/Examples_master.ipynb @@ -1,42 +1,42 @@ { "cells": [ -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### The `master` Construct" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### The `master` Construct " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example demonstrates the master construct . In the example, the master keeps track of how many iterations have been executed and prints out a progress report. The other threads skip the master region without waiting." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example demonstrates the master construct . In the example, the master keeps track of how many iterations have been executed and prints out a progress report. The other threads skip the master region without waiting. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_master.1.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_master.1.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_master.1.f" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_master.1.f " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_mem_model.ipynb b/notebook/Examples_mem_model.ipynb index cd03f90..8cc65cb 100644 --- a/notebook/Examples_mem_model.ipynb +++ b/notebook/Examples_mem_model.ipynb @@ -1,99 +1,99 @@ { "cells": [ -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### The OpenMP Memory Model" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### The OpenMP Memory Model " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the following example, at Print 1, the value of _x_ could be either 2 or 5, depending on the timing of the threads, and the implementation of the assignment to _x_ . There are two reasons that the value at Print 1 might not be 5. First, Print 1 might be executed before the assignment to _x_ is executed. Second, even if Print 1 is executed after the assignment, the value 5 is not guaranteed to be seen by thread 1 because a flush may not have been executed by thread 0 since the assignment." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the following example, at Print 1, the value of _x_ could be either 2 or 5, depending on the timing of the threads, and the implementation of the assignment to _x_ . There are two reasons that the value at Print 1 might not be 5. First, Print 1 might be executed before the assignment to _x_ is executed. Second, even if Print 1 is executed after the assignment, the value 5 is not guaranteed to be seen by thread 1 because a flush may not have been executed by thread 0 since the assignment. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The barrier after Print 1 contains implicit flushes on all threads, as well as a thread synchronization, so the programmer is guaranteed that the value 5 will be printed by both Print 2 and Print 3." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The barrier after Print 1 contains implicit flushes on all threads, as well as a thread synchronization, so the programmer is guaranteed that the value 5 will be printed by both Print 2 and Print 3. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_mem_model.1.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_mem_model.1.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_mem_model.1.f90" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_mem_model.1.f90 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example demonstrates why synchronization is difficult to perform correctly through variables. The value of flag is undefined in both prints on thread 1 and the value of data is only well-defined in the second print." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example demonstrates why synchronization is difficult to perform correctly through variables. The value of flag is undefined in both prints on thread 1 and the value of data is only well-defined in the second print. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_mem_model.2.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_mem_model.2.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_mem_model.2.f" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_mem_model.2.f " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The next example demonstrates why synchronization is difficult to perform correctly through variables. Because the _write_ (1)- _flush_ (1)- _flush_ (2)- _read_ (2) sequence cannot be guaranteed in the example, the statements on thread 0 and thread 1 may execute in either order." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The next example demonstrates why synchronization is difficult to perform correctly through variables. Because the _write_ (1)- _flush_ (1)- _flush_ (2)- _read_ (2) sequence cannot be guaranteed in the example, the statements on thread 0 and thread 1 may execute in either order. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_mem_model.3.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_mem_model.3.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_mem_model.3.f" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_mem_model.3.f " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_nestable_lock.ipynb b/notebook/Examples_nestable_lock.ipynb index f78dc1d..b5c24da 100644 --- a/notebook/Examples_nestable_lock.ipynb +++ b/notebook/Examples_nestable_lock.ipynb @@ -1,42 +1,42 @@ { "cells": [ -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### Nestable Lock Routines" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### Nestable Lock Routines " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example demonstrates how a nestable lock can be used to synchronize updates both to a whole structure and to one of its members." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example demonstrates how a nestable lock can be used to synchronize updates both to a whole structure and to one of its members. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_nestable_lock.1.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_nestable_lock.1.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_nestable_lock.1.f" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_nestable_lock.1.f " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_nested_loop.ipynb b/notebook/Examples_nested_loop.ipynb index 28aeedb..0fdfd34 100644 --- a/notebook/Examples_nested_loop.ipynb +++ b/notebook/Examples_nested_loop.ipynb @@ -1,67 +1,67 @@ { "cells": [ -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Nested Loop Constructs" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Nested Loop Constructs " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example of loop construct nesting is conforming because the inner and outer loop regions bind to different `parallel` regions:" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example of loop construct nesting is conforming because the inner and outer loop regions bind to different `parallel` regions: " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_nested_loop.1.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_nested_loop.1.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_nested_loop.1.f" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_nested_loop.1.f " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following variation of the preceding example is also conforming:" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following variation of the preceding example is also conforming: " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_nested_loop.2.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_nested_loop.2.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_nested_loop.2.f" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_nested_loop.2.f " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_nesting_restrict.ipynb b/notebook/Examples_nesting_restrict.ipynb index e2d2fd6..6412b6b 100644 --- a/notebook/Examples_nesting_restrict.ipynb +++ b/notebook/Examples_nesting_restrict.ipynb @@ -1,174 +1,174 @@ { "cells": [ -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Restrictions on Nesting of Regions" - ] - }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The examples in this section illustrate the region nesting rules. " - ] - }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example is non-conforming because the inner and outer loop regions are closely nested:" - ] - }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_nesting_restrict.1.c" - ] - }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_nesting_restrict.1.f" - ] - }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following orphaned version of the preceding example is also non-conforming:" - ] - }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_nesting_restrict.2.c" - ] - }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_nesting_restrict.2.f" - ] - }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example is non-conforming because the loop and `single` regions are closely nested:" - ] - }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_nesting_restrict.3.c" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Restrictions on Nesting of Regions " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_nesting_restrict.3.f" - ] - }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example is non-conforming because a `barrier` region cannot be closely nested inside a loop region:" - ] - }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_nesting_restrict.4.c" - ] - }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_nesting_restrict.4.f" - ] + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The examples in this section illustrate the region nesting rules. " + ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example is non-conforming because the `barrier` region cannot be closely nested inside the `critical` region. If this were permitted, it would result in deadlock due to the fact that only one thread at a time can enter the `critical` region:" - ] + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example is non-conforming because the inner and outer loop regions are closely nested: " + ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_nesting_restrict.5.c" - ] + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_nesting_restrict.1.c " + ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_nesting_restrict.5.f" - ] + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_nesting_restrict.1.f " + ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example is non-conforming because the `barrier` region cannot be closely nested inside the `single` region. If this were permitted, it would result in deadlock due to the fact that only one thread executes the `single` region:" - ] + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following orphaned version of the preceding example is also non-conforming: " + ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_nesting_restrict.6.c" - ] + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_nesting_restrict.2.c " + ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_nesting_restrict.6.f" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_nesting_restrict.2.f " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example is non-conforming because the loop and `single` regions are closely nested: " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_nesting_restrict.3.c " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_nesting_restrict.3.f " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example is non-conforming because a `barrier` region cannot be closely nested inside a loop region: " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_nesting_restrict.4.c " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_nesting_restrict.4.f " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example is non-conforming because the `barrier` region cannot be closely nested inside the `critical` region. If this were permitted, it would result in deadlock due to the fact that only one thread at a time can enter the `critical` region: " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_nesting_restrict.5.c " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_nesting_restrict.5.f " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example is non-conforming because the `barrier` region cannot be closely nested inside the `single` region. If this were permitted, it would result in deadlock due to the fact that only one thread executes the `single` region: " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_nesting_restrict.6.c " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_nesting_restrict.6.f " ] - }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_nowait.ipynb b/notebook/Examples_nowait.ipynb index cd42c69..0e38089 100644 --- a/notebook/Examples_nowait.ipynb +++ b/notebook/Examples_nowait.ipynb @@ -1,74 +1,74 @@ { "cells": [ -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### The `nowait` Clause" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### The `nowait` Clause " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " If there are multiple independent loops within a `parallel` region, you can use the `nowait` clause to avoid the implied barrier at the end of the loop construct, as follows:" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " If there are multiple independent loops within a `parallel` region, you can use the `nowait` clause to avoid the implied barrier at the end of the loop construct, as follows: " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_nowait.1.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_nowait.1.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_nowait.1.f" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_nowait.1.f " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the following example, static scheduling distributes the same logical iteration numbers to the threads that execute the three loop regions. This allows the `nowait` clause to be used, even though there is a data dependence between the loops. The dependence is satisfied as long the same thread executes the same logical iteration numbers in each loop." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the following example, static scheduling distributes the same logical iteration numbers to the threads that execute the three loop regions. This allows the `nowait` clause to be used, even though there is a data dependence between the loops. The dependence is satisfied as long the same thread executes the same logical iteration numbers in each loop. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Note that the iteration count of the loops must be the same. The example satisfies this requirement, since the iteration space of the first two loops is from `0` to `n-1` (from `1` to `N` in the Fortran version), while the iteration space of the last loop is from `1` to `n` ( `2` to `N+1` in the Fortran version)." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Note that the iteration count of the loops must be the same. The example satisfies this requirement, since the iteration space of the first two loops is from `0` to `n-1` (from `1` to `N` in the Fortran version), while the iteration space of the last loop is from `1` to `n` ( `2` to `N+1` in the Fortran version). " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_nowait.2.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_nowait.2.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_nowait.2.f90" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_nowait.2.f90 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_nthrs_dynamic.ipynb b/notebook/Examples_nthrs_dynamic.ipynb index 2d63bf8..bb4bf33 100644 --- a/notebook/Examples_nthrs_dynamic.ipynb +++ b/notebook/Examples_nthrs_dynamic.ipynb @@ -1,81 +1,81 @@ { "cells": [ -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Interaction Between the `num_threads` Clause and `omp_set_dynamic` " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Interaction Between the `num_threads` Clause and `omp_set_dynamic` " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example demonstrates the `num_threads` clause and the effect of the `omp_set_dynamic` routine on it." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example demonstrates the `num_threads` clause and the effect of the `omp_set_dynamic` routine on it. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The call to the `omp_set_dynamic` routine with argument `0` in C/C++, or `.FALSE.` in Fortran, disables the dynamic adjustment of the number of threads in OpenMP implementations that support it. In this case, 10 threads are provided. Note that in case of an error the OpenMP implementation is free to abort the program or to supply any number of threads available." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The call to the `omp_set_dynamic` routine with argument `0` in C/C++, or `.FALSE.` in Fortran, disables the dynamic adjustment of the number of threads in OpenMP implementations that support it. In this case, 10 threads are provided. Note that in case of an error the OpenMP implementation is free to abort the program or to supply any number of threads available. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_nthrs_dynamic.1.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_nthrs_dynamic.1.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_nthrs_dynamic.1.f" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_nthrs_dynamic.1.f " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The call to the `omp_set_dynamic` routine with a non-zero argument in C/C++, or `.TRUE.` in Fortran, allows the OpenMP implementation to choose any number of threads between 1 and 10." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The call to the `omp_set_dynamic` routine with a non-zero argument in C/C++, or `.TRUE.` in Fortran, allows the OpenMP implementation to choose any number of threads between 1 and 10. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_nthrs_dynamic.2.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_nthrs_dynamic.2.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_nthrs_dynamic.2.f" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_nthrs_dynamic.2.f " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " It is good practice to set the _dyn-var_ ICV explicitly by calling the `omp_set_dynamic` routine, as its default setting is implementation defined." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " It is good practice to set the _dyn-var_ ICV explicitly by calling the `omp_set_dynamic` routine, as its default setting is implementation defined. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_nthrs_nesting.ipynb b/notebook/Examples_nthrs_nesting.ipynb index 41e1015..b00b02a 100644 --- a/notebook/Examples_nthrs_nesting.ipynb +++ b/notebook/Examples_nthrs_nesting.ipynb @@ -1,42 +1,42 @@ { "cells": [ -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Controlling the Number of Threads on Multiple Nesting Levels" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Controlling the Number of Threads on Multiple Nesting Levels " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following examples demonstrate how to use the `OMP_NUM_THREADS` environment variable to control the number of threads on multiple nesting levels:" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following examples demonstrate how to use the `OMP_NUM_THREADS` environment variable to control the number of threads on multiple nesting levels: " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_nthrs_nesting.1.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_nthrs_nesting.1.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_nthrs_nesting.1.f" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_nthrs_nesting.1.f " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_ordered.ipynb b/notebook/Examples_ordered.ipynb index bca663c..6738cb5 100644 --- a/notebook/Examples_ordered.ipynb +++ b/notebook/Examples_ordered.ipynb @@ -1,92 +1,92 @@ { "cells": [ -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### The `ordered` Clause and the `ordered` Construct" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### The `ordered` Clause and the `ordered` Construct " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Ordered constructs are useful for sequentially ordering the output from work that is done in parallel. The following program prints out the indices in sequential order:" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Ordered constructs are useful for sequentially ordering the output from work that is done in parallel. The following program prints out the indices in sequential order: " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_ordered.1.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_ordered.1.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_ordered.1.f" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_ordered.1.f " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " It is possible to have multiple `ordered` constructs within a loop region with the `ordered` clause specified. The first example is non-conforming because all iterations execute two `ordered` regions. An iteration of a loop must not execute more than one `ordered` region:" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " It is possible to have multiple `ordered` constructs within a loop region with the `ordered` clause specified. The first example is non-conforming because all iterations execute two `ordered` regions. An iteration of a loop must not execute more than one `ordered` region: " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_ordered.2.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_ordered.2.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_ordered.2.f" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_ordered.2.f " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following is a conforming example with more than one `ordered` construct. Each iteration will execute only one `ordered` region:" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following is a conforming example with more than one `ordered` construct. Each iteration will execute only one `ordered` region: " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_ordered.3.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_ordered.3.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_ordered.3.f" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_ordered.3.f " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_parallel.ipynb b/notebook/Examples_parallel.ipynb index cce0438..235b638 100644 --- a/notebook/Examples_parallel.ipynb +++ b/notebook/Examples_parallel.ipynb @@ -1,42 +1,42 @@ { "cells": [ -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### The `parallel` Construct" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### The `parallel` Construct " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `parallel` construct can be used in coarse-grain parallel programs. In the following example, each thread in the `parallel` region decides what part of the global array _x_ to work on, based on the thread number:" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `parallel` construct can be used in coarse-grain parallel programs. In the following example, each thread in the `parallel` region decides what part of the global array _x_ to work on, based on the thread number: " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_parallel.1.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_parallel.1.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_parallel.1.f" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_parallel.1.f " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_ploop.ipynb b/notebook/Examples_ploop.ipynb index 284d5e4..b928c52 100644 --- a/notebook/Examples_ploop.ipynb +++ b/notebook/Examples_ploop.ipynb @@ -1,42 +1,42 @@ { "cells": [ -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### A Simple Parallel Loop" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### A Simple Parallel Loop " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example demonstrates how to parallelize a simple loop using the parallel loop construct. The loop iteration variable is private by default, so it is not necessary to specify it explicitly in a `private` clause." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example demonstrates how to parallelize a simple loop using the parallel loop construct. The loop iteration variable is private by default, so it is not necessary to specify it explicitly in a `private` clause. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_ploop.1.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_ploop.1.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_ploop.1.f" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_ploop.1.f " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_pra_iterator.ipynb b/notebook/Examples_pra_iterator.ipynb index bbc714d..90c8c12 100644 --- a/notebook/Examples_pra_iterator.ipynb +++ b/notebook/Examples_pra_iterator.ipynb @@ -1,51 +1,51 @@ { "cells": [ -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Parallel Random Access Iterator Loop" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Parallel Random Access Iterator Loop " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_cppspecificstart" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_cppspecificstart " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows a parallel random access iterator loop." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows a parallel random access iterator loop. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_cppnexamplepra_iterator1" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_cppnexamplepra_iterator1 " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_cppspecificend" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_cppspecificend " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_private.ipynb b/notebook/Examples_private.ipynb index d4e4249..9f768ea 100644 --- a/notebook/Examples_private.ipynb +++ b/notebook/Examples_private.ipynb @@ -1,95 +1,95 @@ { "cells": [ -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### The `private` Clause" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### The `private` Clause " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the following example, the values of original list items _i_ and _j_ are retained on exit from the `parallel` region, while the private list items _i_ and _j_ are modified within the `parallel` construct. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the following example, the values of original list items _i_ and _j_ are retained on exit from the `parallel` region, while the private list items _i_ and _j_ are modified within the `parallel` construct. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_private.1.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_private.1.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_private.1.f" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_private.1.f " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the following example, all uses of the variable _a_ within the loop construct in the routine _f_ refer to a private list \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the following example, all uses of the variable _a_ within the loop construct in the routine _f_ refer to a private list \n", "* _a_ , while it is unspecified whether references to _a_ in the routine _g_ are to a private list \n", -"* or the original list item." +"* or the original list item. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_private.2.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_private.2.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_private.2.f" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_private.2.f " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example demonstrates that a list \n", -"* that appears in a `private` clause in a `parallel` construct may also appear in a `private` clause in an enclosed worksharing construct, which results in an additional private copy." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example demonstrates that a list \n", +"* that appears in a `private` clause in a `parallel` construct may also appear in a `private` clause in an enclosed worksharing construct, which results in an additional private copy. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_private.3.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_private.3.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_private.3.f" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_private.3.f " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_psections.ipynb b/notebook/Examples_psections.ipynb index 49eeed4..fd288c6 100644 --- a/notebook/Examples_psections.ipynb +++ b/notebook/Examples_psections.ipynb @@ -1,42 +1,42 @@ { "cells": [ -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### The `parallel` `sections` Construct" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### The `parallel` `sections` Construct " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the following example routines `XAXIS` , `YAXIS` , and `ZAXIS` can be executed concurrently. The first `section` directive is optional. Note that all `section` directives need to appear in the `parallel sections` construct." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the following example routines `XAXIS` , `YAXIS` , and `ZAXIS` can be executed concurrently. The first `section` directive is optional. Note that all `section` directives need to appear in the `parallel sections` construct. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_psections.1.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_psections.1.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_psections.1.f" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_psections.1.f " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_reduction.ipynb b/notebook/Examples_reduction.ipynb index 17cae6f..656bbac 100644 --- a/notebook/Examples_reduction.ipynb +++ b/notebook/Examples_reduction.ipynb @@ -1,187 +1,187 @@ { "cells": [ -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### The `reduction` Clause" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### The `reduction` Clause " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example demonstrates the `reduction` clause ; note that some reductions can be expressed in the loop in several ways, as shown for the `max` and `min` reductions below:" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example demonstrates the `reduction` clause ; note that some reductions can be expressed in the loop in several ways, as shown for the `max` and `min` reductions below: " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_reduction.1.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_reduction.1.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_reduction.1.f90" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_reduction.1.f90 " ] - }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " A common implementation of the preceding example is to treat it as if it had been written as follows:" + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " A common implementation of the preceding example is to treat it as if it had been written as follows: " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_reduction.2.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_reduction.2.c " ] - }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " fortranspecificstartffreenexample{reduction}{2}" + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " fortranspecificstartffreenexample{reduction}{2} " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following program is non-conforming because the reduction is on the emph{intrinsic procedure name} `MAX` but that name has been redefined to be the variable named `MAX` ." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following program is non-conforming because the reduction is on the emph{intrinsic procedure name} `MAX` but that name has been redefined to be the variable named `MAX` . " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_ffreenexamplereduction3" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_ffreenexamplereduction3 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -" blue line floater at top of this page for 'Fortran, cont.' [t!] linewitharrows{-1}{dashed}{Fortran (cont.)}{8em} " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +" blue line floater at top of this page for 'Fortran, cont.' [t!] linewitharrows{-1}{dashed}{Fortran (cont.)}{8em} " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following conforming program performs the reduction using the emph{intrinsic procedure name} `MAX` even though the intrinsic `MAX` has been renamed to `REN` ." - ] + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following conforming program performs the reduction using the emph{intrinsic procedure name} `MAX` even though the intrinsic `MAX` has been renamed to `REN` . " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_ffreenexamplereduction4 " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following conforming program performs the reduction using _intrinsic procedure name_ `MAX` even though the intrinsic `MAX` has been renamed to `MIN` . " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_ffreenexamplereduction5 " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " fortranspecificend " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example is non-conforming because the initialization ( `a = 0` ) of the original list \n", +"* `a` is not synchronized with the update of `a` as a result of the reduction computation in the `for` loop. Therefore, the example may print an incorrect value for `a` . " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " To avoid this problem, the initialization of the original list \n", +"* `a` should complete before any update of `a` as a result of the `reduction` clause. This can be achieved by adding an explicit barrier after the assignment `a = 0` , or by enclosing the assignment `a = 0` in a `single` directive (which has an implied barrier), or by initializing `a` before the start of the `parallel` region. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_reduction.6.c " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_reduction.6.f " + ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_ffreenexamplereduction4" - ] + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example demonstrates the reduction of array _a_ . In C/C++ this is illustrated by the explicit use of an array section _a[0:N]_ in the `reduction` clause. The corresponding Fortran example uses array syntax supported in the base language. As of the OpenMP 4.5 specification the explicit use of array section in the `reduction` clause in Fortran is not permitted. But this oversight will be fixed in the next release of the specification. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_reduction.7.c " + ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following conforming program performs the reduction using _intrinsic procedure name_ `MAX` even though the intrinsic `MAX` has been renamed to `MIN` ." - ] - }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_ffreenexamplereduction5" - ] - }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " fortranspecificend" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_reduction.7.f90 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example is non-conforming because the initialization ( `a = 0` ) of the original list \n", -"* `a` is not synchronized with the update of `a` as a result of the reduction computation in the `for` loop. Therefore, the example may print an incorrect value for `a` ." - ] - }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " To avoid this problem, the initialization of the original list \n", -"* `a` should complete before any update of `a` as a result of the `reduction` clause. This can be achieved by adding an explicit barrier after the assignment `a = 0` , or by enclosing the assignment `a = 0` in a `single` directive (which has an implied barrier), or by initializing `a` before the start of the `parallel` region." - ] - }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_reduction.6.c" - ] - }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_reduction.6.f" - ] - }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example demonstrates the reduction of array _a_ . In C/C++ this is illustrated by the explicit use of an array section _a[0:N]_ in the `reduction` clause. The corresponding Fortran example uses array syntax supported in the base language. As of the OpenMP 4.5 specification the explicit use of array section in the `reduction` clause in Fortran is not permitted. But this oversight will be fixed in the next release of the specification." - ] - }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_reduction.7.c" - ] - }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_reduction.7.f90" - ] - }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_set_dynamic_nthrs.ipynb b/notebook/Examples_set_dynamic_nthrs.ipynb index 3b7cbb7..d5e7e35 100644 --- a/notebook/Examples_set_dynamic_nthrs.ipynb +++ b/notebook/Examples_set_dynamic_nthrs.ipynb @@ -1,56 +1,56 @@ { "cells": [ -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "section{The `omp_set_dynamic` and " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "section{The `omp_set_dynamic` and " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " `omp_set_num_threads` Routines}" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " `omp_set_num_threads` Routines} " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Some programs rely on a fixed, prespecified number of threads to execute correctly. Because the default setting for the dynamic adjustment of the number of threads is implementation defined, such programs can choose to turn off the dynamic threads capability and set the number of threads explicitly to ensure portability. The following example shows how to do this using `omp_set_dynamic` , and `omp_set_num_threads` ." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Some programs rely on a fixed, prespecified number of threads to execute correctly. Because the default setting for the dynamic adjustment of the number of threads is implementation defined, such programs can choose to turn off the dynamic threads capability and set the number of threads explicitly to ensure portability. The following example shows how to do this using `omp_set_dynamic` , and `omp_set_num_threads` . " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In this example, the program executes correctly only if it is executed by 16 threads. If the implementation is not capable of supporting 16 threads, the behavior of this example is implementation defined. Note that the number of threads executing a `parallel` region remains constant during the region, regardless of the dynamic threads setting. The dynamic threads mechanism determines the number of threads to use at the start of the `parallel` region and keeps it constant for the duration of the region." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In this example, the program executes correctly only if it is executed by 16 threads. If the implementation is not capable of supporting 16 threads, the behavior of this example is implementation defined. Note that the number of threads executing a `parallel` region remains constant during the region, regardless of the dynamic threads setting. The dynamic threads mechanism determines the number of threads to use at the start of the `parallel` region and keeps it constant for the duration of the region. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_set_dynamic_nthrs.1.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_set_dynamic_nthrs.1.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_set_dynamic_nthrs.1.f" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_set_dynamic_nthrs.1.f " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_simple_lock.ipynb b/notebook/Examples_simple_lock.ipynb index cf23300..32e5360 100644 --- a/notebook/Examples_simple_lock.ipynb +++ b/notebook/Examples_simple_lock.ipynb @@ -1,56 +1,56 @@ { "cells": [ -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### Simple Lock Routines" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### Simple Lock Routines " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the following example, the lock routines cause the threads to be idle while waiting for entry to the first critical section, but to do other work while waiting for entry to the second. The `omp_set_lock` function blocks, but the `omp_test_lock` function does not, allowing the work in `skip` to be done. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the following example, the lock routines cause the threads to be idle while waiting for entry to the first critical section, but to do other work while waiting for entry to the second. The `omp_set_lock` function blocks, but the `omp_test_lock` function does not, allowing the work in `skip` to be done. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Note that the argument to the lock routines should have type `omp_lock_t` , and that there is no need to flush it. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Note that the argument to the lock routines should have type `omp_lock_t` , and that there is no need to flush it. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_simple_lock.1.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_simple_lock.1.c " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Note that there is no need to flush the lock variable. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Note that there is no need to flush the lock variable. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_simple_lock.1.f" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_simple_lock.1.f " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_single.ipynb b/notebook/Examples_single.ipynb index 49f3569..632ec04 100644 --- a/notebook/Examples_single.ipynb +++ b/notebook/Examples_single.ipynb @@ -1,42 +1,42 @@ { "cells": [ -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### The `single` Construct" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### The `single` Construct " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example demonstrates the `single` construct. In the example, only one thread prints each of the progress messages. All other threads will skip the `single` region and stop at the barrier at the end of the `single` construct until all threads in the team have reached the barrier. If other threads can proceed without waiting for the thread executing the `single` region, a `nowait` clause can be specified, as is done in the third `single` construct in this example. The user must not make any assumptions as to which thread will execute a `single` region." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example demonstrates the `single` construct. In the example, only one thread prints each of the progress messages. All other threads will skip the `single` region and stop at the barrier at the end of the `single` construct until all threads in the team have reached the barrier. If other threads can proceed without waiting for the thread executing the `single` region, a `nowait` clause can be specified, as is done in the third `single` construct in this example. The user must not make any assumptions as to which thread will execute a `single` region. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_single.1.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_single.1.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_single.1.f" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_single.1.f " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_standalone.ipynb b/notebook/Examples_standalone.ipynb index 93849df..65aa37b 100644 --- a/notebook/Examples_standalone.ipynb +++ b/notebook/Examples_standalone.ipynb @@ -1,88 +1,88 @@ { "cells": [ -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "section{Placement of `flush` , `barrier` , `taskwait` " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "section{Placement of `flush` , `barrier` , `taskwait` " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " and `taskyield` Directives}" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " and `taskyield` Directives} " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example is non-conforming, because the `flush` , `barrier` , `taskwait` , and `taskyield` directives are stand-alone directives and cannot be the immediate substatement of an `if` statement. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example is non-conforming, because the `flush` , `barrier` , `taskwait` , and `taskyield` directives are stand-alone directives and cannot be the immediate substatement of an `if` statement. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_standalone.1.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_standalone.1.c " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example is non-conforming, because the `flush` , `barrier` , `taskwait` , and `taskyield` directives are stand-alone directives and cannot be the action statement of an `if` statement or a labeled branch target." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example is non-conforming, because the `flush` , `barrier` , `taskwait` , and `taskyield` directives are stand-alone directives and cannot be the action statement of an `if` statement or a labeled branch target. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_standalone.1.f90" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_standalone.1.f90 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following version of the above example is conforming because the `flush` , `barrier` , `taskwait` , and `taskyield` directives are enclosed in a compound statement. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following version of the above example is conforming because the `flush` , `barrier` , `taskwait` , and `taskyield` directives are enclosed in a compound statement. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_standalone.2.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_standalone.2.c " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example is conforming because the `flush` , `barrier` , `taskwait` , and `taskyield` directives are enclosed in an `if` construct or follow the labeled branch target." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example is conforming because the `flush` , `barrier` , `taskwait` , and `taskyield` directives are enclosed in an `if` construct or follow the labeled branch target. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_standalone.2.f90" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_standalone.2.f90 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_target.ipynb b/notebook/Examples_target.ipynb index d0f7a52..276fa60 100644 --- a/notebook/Examples_target.ipynb +++ b/notebook/Examples_target.ipynb @@ -1,267 +1,267 @@ { "cells": [ -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### `target` Construct" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### `target` Construct " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### `target` Construct on `parallel` Construct" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### `target` Construct on `parallel` Construct " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " This following example shows how the `target` construct offloads a code region to a target device. The variables _p_ , _v1_ , _v2_ , and _N_ are implicitly mapped to the target device." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " This following example shows how the `target` construct offloads a code region to a target device. The variables _p_ , _v1_ , _v2_ , and _N_ are implicitly mapped to the target device. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target.1.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target.1.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target.1.f90" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target.1.f90 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### `target` Construct with `map` Clause" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### `target` Construct with `map` Clause " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " This following example shows how the `target` construct offloads a code region to a target device. The variables _p_ , _v1_ and _v2_ are explicitly mapped to the target device using the `map` clause. The variable _N_ is implicitly mapped to the target device." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " This following example shows how the `target` construct offloads a code region to a target device. The variables _p_ , _v1_ and _v2_ are explicitly mapped to the target device using the `map` clause. The variable _N_ is implicitly mapped to the target device. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target.2.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target.2.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target.2.f90" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target.2.f90 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### `map` Clause with `to` / `from` map-types" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### `map` Clause with `to` / `from` map-types " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows how the `target` construct offloads a code region to a target device. In the `map` clause, the `to` and `from` map-types define the mapping between the original (host) data and the target (device) data. The `to` map-type specifies that the data will only be read on the device, and the `from` map-type specifies that the data will only be written to on the device. By specifying a guaranteed access on the device, data transfers can be reduced for the `target` region." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows how the `target` construct offloads a code region to a target device. In the `map` clause, the `to` and `from` map-types define the mapping between the original (host) data and the target (device) data. The `to` map-type specifies that the data will only be read on the device, and the `from` map-type specifies that the data will only be written to on the device. By specifying a guaranteed access on the device, data transfers can be reduced for the `target` region. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `to` map-type indicates that at the start of the `target` region the variables _v1_ and _v2_ are initialized with the values of the corresponding variables on the host device, and at the end of the `target` region the variables _v1_ and _v2_ are not assigned to their corresponding variables on the host device." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `to` map-type indicates that at the start of the `target` region the variables _v1_ and _v2_ are initialized with the values of the corresponding variables on the host device, and at the end of the `target` region the variables _v1_ and _v2_ are not assigned to their corresponding variables on the host device. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `from` map-type indicates that at the start of the `target` region the variable _p_ is not initialized with the value of the corresponding variable on the host device, and at the end of the `target` region the variable _p_ is assigned to the corresponding variable on the host device." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `from` map-type indicates that at the start of the `target` region the variable _p_ is not initialized with the value of the corresponding variable on the host device, and at the end of the `target` region the variable _p_ is assigned to the corresponding variable on the host device. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target.3.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target.3.c " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `to` and `from` map-types allow programmers to optimize data motion. Since data for the _v_ arrays are not returned, and data for the _p_ array are not transferred to the device, only one-half of the data is moved, compared to the default behavior of an implicit mapping." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `to` and `from` map-types allow programmers to optimize data motion. Since data for the _v_ arrays are not returned, and data for the _p_ array are not transferred to the device, only one-half of the data is moved, compared to the default behavior of an implicit mapping. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target.3.f90" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target.3.f90 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### `map` Clause with Array Sections" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### `map` Clause with Array Sections " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows how the `target` construct offloads a code region to a target device. In the `map` clause, map-types are used to optimize the mapping of variables to the target device. Because variables _p_ , _v1_ and _v2_ are pointers, array section notation must be used to map the arrays. The notation `:N` is equivalent to `0:N` ." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows how the `target` construct offloads a code region to a target device. In the `map` clause, map-types are used to optimize the mapping of variables to the target device. Because variables _p_ , _v1_ and _v2_ are pointers, array section notation must be used to map the arrays. The notation `:N` is equivalent to `0:N` . " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target.4.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target.4.c " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In C, the length of the pointed-to array must be specified. In Fortran the extent of the array is known and the length need not be specified. A section of the array can be specified with the usual Fortran syntax, as shown in the following example. The value 1 is assumed for the lower bound for array section _v2(:N)_ ." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In C, the length of the pointed-to array must be specified. In Fortran the extent of the array is known and the length need not be specified. A section of the array can be specified with the usual Fortran syntax, as shown in the following example. The value 1 is assumed for the lower bound for array section _v2(:N)_ . " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target.4.f90" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target.4.f90 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " A more realistic situation in which an assumed-size array is passed to `vec_mult` requires that the length of the arrays be specified, because the compiler does not know the size of the storage. A section of the array must be specified with the usual Fortran syntax, as shown in the following example. The value 1 is assumed for the lower bound for array section _v2(:N)_ ." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " A more realistic situation in which an assumed-size array is passed to `vec_mult` requires that the length of the arrays be specified, because the compiler does not know the size of the storage. A section of the array must be specified with the usual Fortran syntax, as shown in the following example. The value 1 is assumed for the lower bound for array section _v2(:N)_ . " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target.4b.f90" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target.4b.f90 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### `target` Construct with `if` Clause" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### `target` Construct with `if` Clause " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows how the `target` construct offloads a code region to a target device." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows how the `target` construct offloads a code region to a target device. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `if` clause on the `target` construct indicates that if the variable _N_ is smaller than a given threshold, then the `target` region will be executed by the host device." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `if` clause on the `target` construct indicates that if the variable _N_ is smaller than a given threshold, then the `target` region will be executed by the host device. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `if` clause on the `parallel` construct indicates that if the variable _N_ is smaller than a second threshold then the `parallel` region is inactive." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `if` clause on the `parallel` construct indicates that if the variable _N_ is smaller than a second threshold then the `parallel` region is inactive. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target.5.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target.5.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target.5.f90" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target.5.f90 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example is a modification of the above _target.5_ code to show the combined `target` and parallel loop directives. It uses the _directive-name_ modifier in multiple `if` clauses to specify the component directive to which it applies. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example is a modification of the above _target.5_ code to show the combined `target` and parallel loop directives. It uses the _directive-name_ modifier in multiple `if` clauses to specify the component directive to which it applies. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `if` clause with the `target` modifier applies to the `target` component of the combined directive, and the `if` clause with the `parallel` modifier applies to the `parallel` component of the combined directive. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `if` clause with the `target` modifier applies to the `target` component of the combined directive, and the `if` clause with the `parallel` modifier applies to the `parallel` component of the combined directive. " ] - }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target.6.c" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target.6.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target.6.f90" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target.6.f90 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_target_data.ipynb b/notebook/Examples_target_data.ipynb index e7fa890..e51d8e6 100644 --- a/notebook/Examples_target_data.ipynb +++ b/notebook/Examples_target_data.ipynb @@ -1,325 +1,325 @@ { "cells": [ -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### `target` `data` Construct" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### `target` `data` Construct " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### Simple `target` `data` Construct" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### Simple `target` `data` Construct " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " This example shows how the `target` `data` construct maps variables to a device data environment. The `target` `data` construct creates a new device data environment and maps the variables _v1_ , _v2_ , and _p_ to the new device data environment. The `target` construct enclosed in the `target` `data` region creates a new device data environment, which inherits the variables _v1_ , _v2_ , and _p_ from the enclosing device data environment. The variable _N_ is mapped into the new device data environment from the encountering task's data environment." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " This example shows how the `target` `data` construct maps variables to a device data environment. The `target` `data` construct creates a new device data environment and maps the variables _v1_ , _v2_ , and _p_ to the new device data environment. The `target` construct enclosed in the `target` `data` region creates a new device data environment, which inherits the variables _v1_ , _v2_ , and _p_ from the enclosing device data environment. The variable _N_ is mapped into the new device data environment from the encountering task's data environment. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target_data.1.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target_data.1.c " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The Fortran code passes a reference and specifies the extent of the arrays in the declaration. No length information is necessary in the map clause, as is required with C/C++ pointers." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The Fortran code passes a reference and specifies the extent of the arrays in the declaration. No length information is necessary in the map clause, as is required with C/C++ pointers. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target_data.1.f90" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target_data.1.f90 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### `target` `data` Region Enclosing Multiple `target` Regions" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### `target` `data` Region Enclosing Multiple `target` Regions " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following examples show how the `target` `data` construct maps variables to a device data environment of a `target` region. The `target` `data` construct creates a device data environment and encloses `target` regions, which have their own device data environments. The device data environment of the `target` `data` region is inherited by the device data environment of an enclosed `target` region. The `target` `data` construct is used to create variables that will persist throughout the `target` `data` region." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following examples show how the `target` `data` construct maps variables to a device data environment of a `target` region. The `target` `data` construct creates a device data environment and encloses `target` regions, which have their own device data environments. The device data environment of the `target` `data` region is inherited by the device data environment of an enclosed `target` region. The `target` `data` construct is used to create variables that will persist throughout the `target` `data` region. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the following example the variables _v1_ and _v2_ are mapped at each `target` construct. Instead of mapping the variable _p_ twice, once at each `target` construct, _p_ is mapped once by the `target` `data` construct." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the following example the variables _v1_ and _v2_ are mapped at each `target` construct. Instead of mapping the variable _p_ twice, once at each `target` construct, _p_ is mapped once by the `target` `data` construct. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target_data.2.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target_data.2.c " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The Fortran code uses reference and specifies the extent of the _p_ , _v1_ and _v2_ arrays. No length information is necessary in the `map` clause, as is required with C/C++ pointers. The arrays _v1_ and _v2_ are mapped at each `target` construct. Instead of mapping the array _p_ twice, once at each target construct, _p_ is mapped once by the `target` `data` construct." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The Fortran code uses reference and specifies the extent of the _p_ , _v1_ and _v2_ arrays. No length information is necessary in the `map` clause, as is required with C/C++ pointers. The arrays _v1_ and _v2_ are mapped at each `target` construct. Instead of mapping the array _p_ twice, once at each target construct, _p_ is mapped once by the `target` `data` construct. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target_data.2.f90" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target_data.2.f90 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the following example, the variable tmp defaults to `tofrom` map-type and is mapped at each `target` construct. The array _Q_ is mapped once at the enclosing `target` `data` region instead of at each `target` construct. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the following example, the variable tmp defaults to `tofrom` map-type and is mapped at each `target` construct. The array _Q_ is mapped once at the enclosing `target` `data` region instead of at each `target` construct. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target_data.3.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target_data.3.c " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the following example the arrays _v1_ and _v2_ are mapped at each `target` construct. Instead of mapping the array _Q_ twice at each `target` construct, _Q_ is mapped once by the `target` `data` construct. Note, the _tmp_ variable is implicitly remapped for each `target` region, mapping the value from the device to the host at the end of the first `target` region, and from the host to the device for the second `target` region." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the following example the arrays _v1_ and _v2_ are mapped at each `target` construct. Instead of mapping the array _Q_ twice at each `target` construct, _Q_ is mapped once by the `target` `data` construct. Note, the _tmp_ variable is implicitly remapped for each `target` region, mapping the value from the device to the host at the end of the first `target` region, and from the host to the device for the second `target` region. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target_data.3.f90" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target_data.3.f90 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### `target` `data` Construct with Orphaned Call" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### `target` `data` Construct with Orphaned Call " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following two examples show how the `target` `data` construct maps variables to a device data environment. The `target` `data` construct's device data environment encloses the `target` construct's device data environment in the function `vec_mult()` ." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following two examples show how the `target` `data` construct maps variables to a device data environment. The `target` `data` construct's device data environment encloses the `target` construct's device data environment in the function `vec_mult()` . " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " When the type of the variable appearing in an array section is pointer, the pointer variable and the storage location of the corresponding array section are mapped to the device data environment. The pointer variable is treated as if it had appeared in a `map` clause with a map-type of `alloc` . The array section's storage location is mapped according to the map-type in the `map` clause (the default map-type is `tofrom` )." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " When the type of the variable appearing in an array section is pointer, the pointer variable and the storage location of the corresponding array section are mapped to the device data environment. The pointer variable is treated as if it had appeared in a `map` clause with a map-type of `alloc` . The array section's storage location is mapped according to the map-type in the `map` clause (the default map-type is `tofrom` ). " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `target` construct's device data environment inherits the storage locations of the array sections _v1[0:N]_ , _v2[:n]_ , and _p0[0:N]_ from the enclosing target data construct's device data environment. Neither initialization nor assignment is performed for the array sections in the new device data environment." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `target` construct's device data environment inherits the storage locations of the array sections _v1[0:N]_ , _v2[:n]_ , and _p0[0:N]_ from the enclosing target data construct's device data environment. Neither initialization nor assignment is performed for the array sections in the new device data environment. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The pointer variables _p1_ , _v3_ , and _v4_ are mapped into the target construct's device data environment with an implicit map-type of alloc and they are assigned the address of the storage location associated with their corresponding array sections. Note that the following pairs of array section storage locations are equivalent ( _p0[:N]_ , _p1[:N]_ ), ( _v1[:N]_ , _v3[:N]_ ), and ( _v2[:N]_ , _v4[:N]_ )." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The pointer variables _p1_ , _v3_ , and _v4_ are mapped into the target construct's device data environment with an implicit map-type of alloc and they are assigned the address of the storage location associated with their corresponding array sections. Note that the following pairs of array section storage locations are equivalent ( _p0[:N]_ , _p1[:N]_ ), ( _v1[:N]_ , _v3[:N]_ ), and ( _v2[:N]_ , _v4[:N]_ ). " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target_data.4.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target_data.4.c " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The Fortran code maps the pointers and storage in an identical manner (same extent, but uses indices from 1 to _N_ )." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The Fortran code maps the pointers and storage in an identical manner (same extent, but uses indices from 1 to _N_ ). " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `target` construct's device data environment inherits the storage locations of the arrays _v1_ , _v2_ and _p0_ from the enclosing `target` `data` constructs's device data environment. However, in Fortran the associated data of the pointer is known, and the shape is not required." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `target` construct's device data environment inherits the storage locations of the arrays _v1_ , _v2_ and _p0_ from the enclosing `target` `data` constructs's device data environment. However, in Fortran the associated data of the pointer is known, and the shape is not required. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The pointer variables _p1_ , _v3_ , and _v4_ are mapped into the `target` construct's device data environment with an implicit map-type of `alloc` and they are assigned the address of the storage location associated with their corresponding array sections. Note that the following pair of array storage locations are equivalent ( _p0_ , _p1_ ), ( _v1_ , _v3_ ), and ( _v2_ , _v4_ )." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The pointer variables _p1_ , _v3_ , and _v4_ are mapped into the `target` construct's device data environment with an implicit map-type of `alloc` and they are assigned the address of the storage location associated with their corresponding array sections. Note that the following pair of array storage locations are equivalent ( _p0_ , _p1_ ), ( _v1_ , _v3_ ), and ( _v2_ , _v4_ ). " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target_data.4.f90" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target_data.4.f90 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the following example, the variables _p1_ , _v3_ , and _v4_ are references to the pointer variables _p0_ , _v1_ and _v2_ respectively. The `target` construct's device data environment inherits the pointer variables _p0_ , _v1_ , and _v2_ from the enclosing `target` `data` construct's device data environment. Thus, _p1_ , _v3_ , and _v4_ are already present in the device data environment." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the following example, the variables _p1_ , _v3_ , and _v4_ are references to the pointer variables _p0_ , _v1_ and _v2_ respectively. The `target` construct's device data environment inherits the pointer variables _p0_ , _v1_ , and _v2_ from the enclosing `target` `data` construct's device data environment. Thus, _p1_ , _v3_ , and _v4_ are already present in the device data environment. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target_data.5.cpp" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target_data.5.cpp " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the following example, the usual Fortran approach is used for dynamic memory. The _p0_ , _v1_ , and _v2_ arrays are allocated in the main program and passed as references from one routine to another. In `vec_mult` , _p1_ , _v3_ and _v4_ are references to the _p0_ , _v1_ , and _v2_ arrays, respectively. The `target` construct's device data environment inherits the arrays _p0_ , _v1_ , and _v2_ from the enclosing target data construct's device data environment. Thus, _p1_ , _v3_ , and _v4_ are already present in the device data environment." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the following example, the usual Fortran approach is used for dynamic memory. The _p0_ , _v1_ , and _v2_ arrays are allocated in the main program and passed as references from one routine to another. In `vec_mult` , _p1_ , _v3_ and _v4_ are references to the _p0_ , _v1_ , and _v2_ arrays, respectively. The `target` construct's device data environment inherits the arrays _p0_ , _v1_ , and _v2_ from the enclosing target data construct's device data environment. Thus, _p1_ , _v3_ , and _v4_ are already present in the device data environment. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target_data.5.f90" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target_data.5.f90 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### `target` `data` Construct with `if` Clause" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### `target` `data` Construct with `if` Clause " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following two examples show how the `target` `data` construct maps variables to a device data environment." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following two examples show how the `target` `data` construct maps variables to a device data environment. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the following example, the if clause on the `target` `data` construct indicates that if the variable _N_ is smaller than a given threshold, then the `target` `data` construct will not create a device data environment." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the following example, the if clause on the `target` `data` construct indicates that if the variable _N_ is smaller than a given threshold, then the `target` `data` construct will not create a device data environment. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `target` constructs enclosed in the `target` `data` region must also use an `if` clause on the same condition, otherwise the pointer variable _p_ is implicitly mapped with a map-type of `tofrom` , but the storage location for the array section _p[0:N]_ will not be mapped in the device data environments of the `target` constructs." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `target` constructs enclosed in the `target` `data` region must also use an `if` clause on the same condition, otherwise the pointer variable _p_ is implicitly mapped with a map-type of `tofrom` , but the storage location for the array section _p[0:N]_ will not be mapped in the device data environments of the `target` constructs. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target_data.6.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target_data.6.c " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `if` clauses work the same way for the following Fortran code. The `target` constructs enclosed in the `target` `data` region should also use an `if` clause with the same condition, so that the `target` `data` region and the `target` region are either both created for the device, or are both ignored." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `if` clauses work the same way for the following Fortran code. The `target` constructs enclosed in the `target` `data` region should also use an `if` clause with the same condition, so that the `target` `data` region and the `target` region are either both created for the device, or are both ignored. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target_data.6.f90" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target_data.6.f90 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the following example, when the `if` clause conditional expression on the `target` construct evaluates to _false_ , the target region will execute on the host device. However, the `target` `data` construct created an enclosing device data environment that mapped _p[0:N]_ to a device data environment on the default device. At the end of the `target` `data` region the array section _p[0:N]_ will be assigned from the device data environment to the corresponding variable in the data environment of the task that encountered the `target` `data` construct, resulting in undefined values in _p[0:N]_ ." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the following example, when the `if` clause conditional expression on the `target` construct evaluates to _false_ , the target region will execute on the host device. However, the `target` `data` construct created an enclosing device data environment that mapped _p[0:N]_ to a device data environment on the default device. At the end of the `target` `data` region the array section _p[0:N]_ will be assigned from the device data environment to the corresponding variable in the data environment of the task that encountered the `target` `data` construct, resulting in undefined values in _p[0:N]_ . " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target_data.7.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target_data.7.c " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `if` clauses work the same way for the following Fortran code. When the `if` clause conditional expression on the `target` construct evaluates to _false_ , the `target` region will execute on the host device. However, the `target` `data` construct created an enclosing device data environment that mapped the _p_ array (and _v1_ and _v2_ ) to a device data environment on the default target device. At the end of the `target` `data` region the _p_ array will be assigned from the device data environment to the corresponding variable in the data environment of the task that encountered the `target` `data` construct, resulting in undefined values in _p_ ." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `if` clauses work the same way for the following Fortran code. When the `if` clause conditional expression on the `target` construct evaluates to _false_ , the `target` region will execute on the host device. However, the `target` `data` construct created an enclosing device data environment that mapped the _p_ array (and _v1_ and _v2_ ) to a device data environment on the default target device. At the end of the `target` `data` region the _p_ array will be assigned from the device data environment to the corresponding variable in the data environment of the task that encountered the `target` `data` construct, resulting in undefined values in _p_ . " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target_data.7.f90" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target_data.7.f90 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_target_unstructured_data.ipynb b/notebook/Examples_target_unstructured_data.ipynb index 698120b..ed2c87a 100644 --- a/notebook/Examples_target_unstructured_data.ipynb +++ b/notebook/Examples_target_unstructured_data.ipynb @@ -1,103 +1,103 @@ { "cells": [ -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"begin " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"begin " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### `target` `enter` `data` and `target` `exit` `data` Constructs" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### `target` `enter` `data` and `target` `exit` `data` Constructs " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -" ### Simple target enter data and target exit data Constructs" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +" ### Simple target enter data and target exit data Constructs " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The structured data construct ( `target` ~ `data` ) provides persistent data on a device for subsequent `target` constructs as shown in the `target` ~ `data` examples above. This is accomplished by creating a single `target` ~ `data` region containing `target` constructs." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The structured data construct ( `target` ~ `data` ) provides persistent data on a device for subsequent `target` constructs as shown in the `target` ~ `data` examples above. This is accomplished by creating a single `target` ~ `data` region containing `target` constructs. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The unstructured data constructs allow the creation and deletion of data on the device at any appropriate point within the host code, as shown below with the `target` ~ `enter` ~ `data` and `target` ~ `exit` ~ `data` constructs." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The unstructured data constructs allow the creation and deletion of data on the device at any appropriate point within the host code, as shown below with the `target` ~ `enter` ~ `data` and `target` ~ `exit` ~ `data` constructs. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following C++ code creates/deletes a vector in a constructor/destructor of a class. The constructor creates a vector with `target` ~ `enter` ~ `data` and uses an `alloc` modifier in the `map` clause to avoid copying values to the device. The destructor deletes the data ( `target` ~ `exit` ~ `data` ) and uses the `delete` modifier in the `map` clause to avoid copying data back to the host. Note, the stand-alone `target` ~ `enter` ~ `data` occurs after the host vector is created, and the `target` ~ `exit` ~ `data` construct occurs before the host data is deleted." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following C++ code creates/deletes a vector in a constructor/destructor of a class. The constructor creates a vector with `target` ~ `enter` ~ `data` and uses an `alloc` modifier in the `map` clause to avoid copying values to the device. The destructor deletes the data ( `target` ~ `exit` ~ `data` ) and uses the `delete` modifier in the `map` clause to avoid copying data back to the host. Note, the stand-alone `target` ~ `enter` ~ `data` occurs after the host vector is created, and the `target` ~ `exit` ~ `data` construct occurs before the host data is deleted. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target_unstructured_data.1.cpp" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target_unstructured_data.1.cpp " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following C code allocates and frees the data member of a Matrix structure. The `init_matrix` function allocates the memory used in the structure and uses the `target` ~ `enter` ~ `data` directive to map it to the target device. The `free_matrix` function removes the mapped array from the target device and then frees the memory on the host. Note, the stand-alone `target` ~ `enter` ~ `data` occurs after the host memory is allocated, and the `target` ~ `exit` ~ `data` construct occurs before the host data is freed." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following C code allocates and frees the data member of a Matrix structure. The `init_matrix` function allocates the memory used in the structure and uses the `target` ~ `enter` ~ `data` directive to map it to the target device. The `free_matrix` function removes the mapped array from the target device and then frees the memory on the host. Note, the stand-alone `target` ~ `enter` ~ `data` occurs after the host memory is allocated, and the `target` ~ `exit` ~ `data` construct occurs before the host data is freed. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target_unstructured_data.1.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target_unstructured_data.1.c " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following Fortran code allocates and deallocates a module array. The `initialize` subroutine allocates the module array and uses the `target` ~ `enter` ~ `data` directive to map it to the target device. The `finalize` subroutine removes the mapped array from the target device and then deallocates the array on the host. Note, the stand-alone `target` ~ `enter` ~ `data` occurs after the host memory is allocated, and the `target` ~ `exit` ~ `data` construct occurs before the host data is deallocated." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following Fortran code allocates and deallocates a module array. The `initialize` subroutine allocates the module array and uses the `target` ~ `enter` ~ `data` directive to map it to the target device. The `finalize` subroutine removes the mapped array from the target device and then deallocates the array on the host. Note, the stand-alone `target` ~ `enter` ~ `data` occurs after the host memory is allocated, and the `target` ~ `exit` ~ `data` construct occurs before the host data is deallocated. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target_unstructured_data.1.f90" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target_unstructured_data.1.f90 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"end" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +"end " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_target_update.ipynb b/notebook/Examples_target_update.ipynb index ca2a4af..e14f58d 100644 --- a/notebook/Examples_target_update.ipynb +++ b/notebook/Examples_target_update.ipynb @@ -1,137 +1,137 @@ { "cells": [ -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### `target` `update` Construct" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### `target` `update` Construct " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### Simple `target` `data` and `target` `update` Constructs" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### Simple `target` `data` and `target` `update` Constructs " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows how the `target` `update` construct updates variables in a device data environment." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows how the `target` `update` construct updates variables in a device data environment. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `target` `data` construct maps array sections _v1[:N]_ and _v2[:N]_ (arrays _v1_ and _v2_ in the Fortran code) into a device data environment." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `target` `data` construct maps array sections _v1[:N]_ and _v2[:N]_ (arrays _v1_ and _v2_ in the Fortran code) into a device data environment. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The task executing on the host device encounters the first `target` region and waits for the completion of the region." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The task executing on the host device encounters the first `target` region and waits for the completion of the region. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " After the execution of the first `target` region, the task executing on the host device then assigns new values to _v1[:N]_ and _v2[:N]_ ( _v1_ and _v2_ arrays in Fortran code) in the task's data environment by calling the function `init_again()` ." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " After the execution of the first `target` region, the task executing on the host device then assigns new values to _v1[:N]_ and _v2[:N]_ ( _v1_ and _v2_ arrays in Fortran code) in the task's data environment by calling the function `init_again()` . " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `target` `update` construct assigns the new values of _v1_ and _v2_ from the task's data environment to the corresponding mapped array sections in the device data environment of the `target` `data` construct." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `target` `update` construct assigns the new values of _v1_ and _v2_ from the task's data environment to the corresponding mapped array sections in the device data environment of the `target` `data` construct. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The task executing on the host device then encounters the second `target` region and waits for the completion of the region." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The task executing on the host device then encounters the second `target` region and waits for the completion of the region. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The second `target` region uses the updated values of _v1[:N]_ and _v2[:N]_ ." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The second `target` region uses the updated values of _v1[:N]_ and _v2[:N]_ . " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target_update.1.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target_update.1.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target_update.1.f90" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target_update.1.f90 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### `target` `update` Construct with `if` Clause" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### `target` `update` Construct with `if` Clause " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows how the `target` `update` construct updates variables in a device data environment." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows how the `target` `update` construct updates variables in a device data environment. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `target` `data` construct maps array sections _v1[:N]_ and _v2[:N]_ (arrays _v1_ and _v2_ in the Fortran code) into a device data environment. In between the two `target` regions, the task executing on the host device conditionally assigns new values to _v1_ and _v2_ in the task's data environment. The function `maybe_init_again()` returns _true_ if new data is written." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `target` `data` construct maps array sections _v1[:N]_ and _v2[:N]_ (arrays _v1_ and _v2_ in the Fortran code) into a device data environment. In between the two `target` regions, the task executing on the host device conditionally assigns new values to _v1_ and _v2_ in the task's data environment. The function `maybe_init_again()` returns _true_ if new data is written. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " When the conditional expression (the return value of `maybe_init_again()` ) in the `if` clause is _true_ , the `target` `update` construct assigns the new values of _v1_ and _v2_ from the task's data environment to the corresponding mapped array sections in the `target` `data` construct's device data environment." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " When the conditional expression (the return value of `maybe_init_again()` ) in the `if` clause is _true_ , the `target` `update` construct assigns the new values of _v1_ and _v2_ from the task's data environment to the corresponding mapped array sections in the `target` `data` construct's device data environment. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target_update.2.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target_update.2.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target_update.2.f90" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target_update.2.f90 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_task_dep.ipynb b/notebook/Examples_task_dep.ipynb index efd40d8..4aab0aa 100644 --- a/notebook/Examples_task_dep.ipynb +++ b/notebook/Examples_task_dep.ipynb @@ -1,205 +1,205 @@ { "cells": [ -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Task Dependences" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Task Dependences " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### Flow Dependence" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### Flow Dependence " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In this example we show a simple flow dependence expressed using the `depend` clause on the `task` construct." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In this example we show a simple flow dependence expressed using the `depend` clause on the `task` construct. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_task_dep.1.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_task_dep.1.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_task_dep.1.f90" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_task_dep.1.f90 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The program will always print ' x = 2 ' , because the `depend` clauses enforce the ordering of the tasks. If the `depend` clauses had been omitted, then the tasks could execute in any order and the program and the program would have a race condition." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The program will always print ' x = 2 ' , because the `depend` clauses enforce the ordering of the tasks. If the `depend` clauses had been omitted, then the tasks could execute in any order and the program and the program would have a race condition. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### Anti-dependence" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### Anti-dependence " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In this example we show an anti-dependence expressed using the `depend` clause on the `task` construct." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In this example we show an anti-dependence expressed using the `depend` clause on the `task` construct. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_task_dep.2.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_task_dep.2.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_task_dep.2.f90" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_task_dep.2.f90 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The program will always print ' x = 1 ' , because the `depend` clauses enforce the ordering of the tasks. If the `depend` clauses had been omitted, then the tasks could execute in any order and the program would have a race condition." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The program will always print ' x = 1 ' , because the `depend` clauses enforce the ordering of the tasks. If the `depend` clauses had been omitted, then the tasks could execute in any order and the program would have a race condition. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### Output Dependence" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### Output Dependence " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In this example we show an output dependence expressed using the `depend` clause on the `task` construct." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In this example we show an output dependence expressed using the `depend` clause on the `task` construct. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_task_dep.3.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_task_dep.3.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_task_dep.3.f90" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_task_dep.3.f90 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The program will always print ' x = 2 ' , because the `depend` clauses enforce the ordering of the tasks. If the `depend` clauses had been omitted, then the tasks could execute in any order and the program would have a race condition." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The program will always print ' x = 2 ' , because the `depend` clauses enforce the ordering of the tasks. If the `depend` clauses had been omitted, then the tasks could execute in any order and the program would have a race condition. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### Concurrent Execution with Dependences" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### Concurrent Execution with Dependences " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In this example we show potentially concurrent execution of tasks using multiple flow dependences expressed using the `depend` clause on the `task` construct." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In this example we show potentially concurrent execution of tasks using multiple flow dependences expressed using the `depend` clause on the `task` construct. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_task_dep.4.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_task_dep.4.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_task_dep.4.f90" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_task_dep.4.f90 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The last two tasks are dependent on the first task. However there is no dependence between the last two tasks, which may execute in any order (or concurrently if more than one thread is available). Thus, the possible outputs are ' x + 1 = 3. x + 2 = 4. ' and ' x + 2 = 4. x + 1 = 3. ' . If the `depend` clauses had been omitted, then all of the tasks could execute in any order and the program would have a race condition." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The last two tasks are dependent on the first task. However there is no dependence between the last two tasks, which may execute in any order (or concurrently if more than one thread is available). Thus, the possible outputs are ' x + 1 = 3. x + 2 = 4. ' and ' x + 2 = 4. x + 1 = 3. ' . If the `depend` clauses had been omitted, then all of the tasks could execute in any order and the program would have a race condition. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### Matrix multiplication" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### Matrix multiplication " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " This example shows a task-based blocked matrix multiplication. Matrices are of NxN elements, and the multiplication is implemented using blocks of BSxBS elements." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " This example shows a task-based blocked matrix multiplication. Matrices are of NxN elements, and the multiplication is implemented using blocks of BSxBS elements. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_task_dep.5.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_task_dep.5.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_task_dep.5.f90" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_task_dep.5.f90 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_task_priority.ipynb b/notebook/Examples_task_priority.ipynb index 36e4d73..64ce369 100644 --- a/notebook/Examples_task_priority.ipynb +++ b/notebook/Examples_task_priority.ipynb @@ -1,58 +1,58 @@ { "cells": [ -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Task Priority" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Task Priority " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", " #### Task Priority \n", -"" +" " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In this example we compute arrays in a matrix through a _compute_array_ routine. Each task has a priority value equal to the value of the loop variable _i_ at the moment of its creation. A higher priority on a task means that a task is a candidate to run sooner." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In this example we compute arrays in a matrix through a _compute_array_ routine. Each task has a priority value equal to the value of the loop variable _i_ at the moment of its creation. A higher priority on a task means that a task is a candidate to run sooner. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The creation of tasks occurs in ascending order (according to the iteration space of the loop) but a hint, by means of the `priority` clause, is provided to reverse the execution order." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The creation of tasks occurs in ascending order (according to the iteration space of the loop) but a hint, by means of the `priority` clause, is provided to reverse the execution order. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_task_priority.1.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_task_priority.1.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_task_priority.1.f90" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_task_priority.1.f90 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_taskgroup.ipynb b/notebook/Examples_taskgroup.ipynb index 3f0b0ae..627f782 100644 --- a/notebook/Examples_taskgroup.ipynb +++ b/notebook/Examples_taskgroup.ipynb @@ -1,49 +1,49 @@ { "cells": [ -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### The `taskgroup` Construct" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### The `taskgroup` Construct " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In this example, tasks are grouped and synchronized using the `taskgroup` construct." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In this example, tasks are grouped and synchronized using the `taskgroup` construct. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Initially, one task (the task executing the `start_background_work()` call) is created in the `parallel` region, and later a parallel tree traversal is started (the task executing the root of the recursive `compute_tree()` calls). While synchronizing tasks at the end of each tree traversal, using the `taskgroup` construct ensures that the formerly started background task does not participate in the synchronization, and is left free to execute in parallel. This is opposed to the behaviour of the `taskwait` construct, which would include the background tasks in the synchronization." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Initially, one task (the task executing the `start_background_work()` call) is created in the `parallel` region, and later a parallel tree traversal is started (the task executing the root of the recursive `compute_tree()` calls). While synchronizing tasks at the end of each tree traversal, using the `taskgroup` construct ensures that the formerly started background task does not participate in the synchronization, and is left free to execute in parallel. This is opposed to the behaviour of the `taskwait` construct, which would include the background tasks in the synchronization. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_taskgroup.1.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_taskgroup.1.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_taskgroup.1.f90" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_taskgroup.1.f90 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_tasking.ipynb b/notebook/Examples_tasking.ipynb index 3b69f18..20c7b03 100644 --- a/notebook/Examples_tasking.ipynb +++ b/notebook/Examples_tasking.ipynb @@ -1,402 +1,402 @@ { "cells": [ -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### The `task` and `taskwait` Constructs" - ] + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### The `task` and `taskwait` Constructs " + ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows how to traverse a tree-like structure using explicit tasks. Note that the `traverse` function should be called from within a parallel region for the different specified tasks to be executed in parallel. Also note that the tasks will be executed in no specified order because there are no synchronization directives. Thus, assuming that the traversal will be done in post order, as in the sequential code, is wrong." - ] + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows how to traverse a tree-like structure using explicit tasks. Note that the `traverse` function should be called from within a parallel region for the different specified tasks to be executed in parallel. Also note that the tasks will be executed in no specified order because there are no synchronization directives. Thus, assuming that the traversal will be done in post order, as in the sequential code, is wrong. " + ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_tasking.1.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_tasking.1.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_tasking.1.f90" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_tasking.1.f90 " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the next example, we force a postorder traversal of the tree by adding a `taskwait` directive. Now, we can safely assume that the left and right sons have been executed before we process the current node. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the next example, we force a postorder traversal of the tree by adding a `taskwait` directive. Now, we can safely assume that the left and right sons have been executed before we process the current node." + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_tasking.2.c " ] - }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_tasking.2.c" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_tasking.2.f90 " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example demonstrates how to use the `task` construct to process elements of a linked list in parallel. The thread executing the `single` region generates all of the explicit tasks, which are then executed by the threads in the current team. The pointer _p_ is `firstprivate` by default on the `task` construct so it is not necessary to specify it in a `firstprivate` clause. " ] - }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_tasking.2.f90" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_tasking.3.c " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_tasking.3.f90 " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `fib()` function should be called from within a `parallel` region for the different specified tasks to be executed in parallel. Also, only one thread of the `parallel` region should call `fib()` unless multiple concurrent Fibonacci computations are desired. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_tasking.4.c " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_tasking.4.f " ] - }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example demonstrates how to use the `task` construct to process elements of a linked list in parallel. The thread executing the `single` region generates all of the explicit tasks, which are then executed by the threads in the current team. The pointer _p_ is `firstprivate` by default on the `task` construct so it is not necessary to specify it in a `firstprivate` clause." + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Note: There are more efficient algorithms for computing Fibonacci numbers. This classic recursion algorithm is for illustrative purposes. " ] - }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_tasking.3.c" + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example demonstrates a way to generate a large number of tasks with one thread and execute them with the threads in the team. While generating these tasks, the implementation may reach its limit on unassigned tasks. If it does, the implementation is allowed to cause the thread executing the task generating loop to suspend its task at the task scheduling point in the `task` directive, and start executing unassigned tasks. Once the number of unassigned tasks is sufficiently low, the thread may resume execution of the task generating loop. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_tasking.3.f90" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_tasking.5.c " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `fib()` function should be called from within a `parallel` region for the different specified tasks to be executed in parallel. Also, only one thread of the `parallel` region should call `fib()` unless multiple concurrent Fibonacci computations are desired. " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_tasking.5.f " ] - }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_tasking.4.c" + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example is the same as the previous one, except that the tasks are generated in an untied task. While generating the tasks, the implementation may reach its limit on unassigned tasks. If it does, the implementation is allowed to cause the thread executing the task generating loop to suspend its task at the task scheduling point in the `task` directive, and start executing unassigned tasks. If that thread begins execution of a task that takes a long time to complete, the other threads may complete all the other tasks before it is finished. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_tasking.4.f" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In this case, since the loop is in an untied task, any other thread is eligible to resume the task generating loop. In the previous examples, the other threads would be forced to idle until the generating thread finishes its long task, since the task generating loop was in a tied task. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Note: There are more efficient algorithms for computing Fibonacci numbers. This classic recursion algorithm is for illustrative purposes." + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_tasking.6.c " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example demonstrates a way to generate a large number of tasks with one thread and execute them with the threads in the team. While generating these tasks, the implementation may reach its limit on unassigned tasks. If it does, the implementation is allowed to cause the thread executing the task generating loop to suspend its task at the task scheduling point in the `task` directive, and start executing unassigned tasks. Once the number of unassigned tasks is sufficiently low, the thread may resume execution of the task generating loop." + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_tasking.6.f " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_tasking.5.c" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following two examples demonstrate how the scheduling rules illustrated in Section 2.11.3 of the OpenMP 4.0 specification affect the usage of `threadprivate` variables in tasks. A `threadprivate` variable can be modified by another task that is executed by the same thread. Thus, the value of a `threadprivate` variable cannot be assumed to be unchanged across a task scheduling point. In untied tasks, task scheduling points may be added in any place by the implementation. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_tasking.5.f" - ] + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " A task switch may occur at a task scheduling point. A single thread may execute both of the task regions that modify `tp` . The parts of these task regions in which `tp` is modified may be executed in any order so the resulting value of `var` can be either 1 or 2. " + ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example is the same as the previous one, except that the tasks are generated in an untied task. While generating the tasks, the implementation may reach its limit on unassigned tasks. If it does, the implementation is allowed to cause the thread executing the task generating loop to suspend its task at the task scheduling point in the `task` directive, and start executing unassigned tasks. If that thread begins execution of a task that takes a long time to complete, the other threads may complete all the other tasks before it is finished." - ] - }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In this case, since the loop is in an untied task, any other thread is eligible to resume the task generating loop. In the previous examples, the other threads would be forced to idle until the generating thread finishes its long task, since the task generating loop was in a tied task." + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_tasking.7.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_tasking.6.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_tasking.7.f " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_tasking.6.f" - ] + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In this example, scheduling constraints prohibit a thread in the team from executing a new task that modifies `tp` while another such task region tied to the same thread is suspended. Therefore, the value written will persist across the task scheduling point. " + ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following two examples demonstrate how the scheduling rules illustrated in Section 2.11.3 of the OpenMP 4.0 specification affect the usage of `threadprivate` variables in tasks. A `threadprivate` variable can be modified by another task that is executed by the same thread. Thus, the value of a `threadprivate` variable cannot be assumed to be unchanged across a task scheduling point. In untied tasks, task scheduling points may be added in any place by the implementation." + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_tasking.8.c " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " A task switch may occur at a task scheduling point. A single thread may execute both of the task regions that modify `tp` . The parts of these task regions in which `tp` is modified may be executed in any order so the resulting value of `var` can be either 1 or 2." + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_tasking.8.f " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_tasking.7.c" - ] + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following two examples demonstrate how the scheduling rules illustrated in Section 2.11.3 of the OpenMP 4.0 specification affect the usage of locks and critical sections in tasks. If a lock is held across a task scheduling point, no attempt should be made to acquire the same lock in any code that may be interleaved. Otherwise, a deadlock is possible. " + ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_tasking.7.f" - ] + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the example below, suppose the thread executing task 1 defers task 2. When it encounters the task scheduling point at task 3, it could suspend task 1 and begin task 2 which will result in a deadlock when it tries to enter critical region 1. " + ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In this example, scheduling constraints prohibit a thread in the team from executing a new task that modifies `tp` while another such task region tied to the same thread is suspended. Therefore, the value written will persist across the task scheduling point." + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_tasking.9.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_tasking.8.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_tasking.9.f " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_tasking.8.f" - ] + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the following example, `lock` is held across a task scheduling point. However, according to the scheduling restrictions, the executing thread can't begin executing one of the non-descendant tasks that also acquires `lock` before the task region is complete. Therefore, no deadlock is possible. " + ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following two examples demonstrate how the scheduling rules illustrated in Section 2.11.3 of the OpenMP 4.0 specification affect the usage of locks and critical sections in tasks. If a lock is held across a task scheduling point, no attempt should be made to acquire the same lock in any code that may be interleaved. Otherwise, a deadlock is possible." + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_tasking.10.c " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the example below, suppose the thread executing task 1 defers task 2. When it encounters the task scheduling point at task 3, it could suspend task 1 and begin task 2 which will result in a deadlock when it tries to enter critical region 1." + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_tasking.10.f90 " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following examples illustrate the use of the `mergeable` clause in the `task` construct. In this first example, the `task` construct has been annotated with the `mergeable` clause. The addition of this clause allows the implementation to reuse the data environment (including the ICVs) of the parent task for the task inside `foo` if the task is included or undeferred. Thus, the result of the execution may differ depending on whether the task is merged or not. Therefore the mergeable clause needs to be used with caution. In this example, the use of the mergeable clause is safe. As `x` is a shared variable the outcome does not depend on whether or not the task is merged (that is, the task will always increment the same variable and will always compute the same value for `x` ). " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_tasking.9.c" - ] + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_tasking.11.c " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_tasking.11.f90 " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " This second example shows an incorrect use of the `mergeable` clause. In this example, the created task will access different instances of the variable `x` if the task is not merged, as `x` is `firstprivate` , but it will access the same variable `x` if the task is merged. As a result, the behavior of the program is unspecified and it can print two different values for `x` depending on the decisions taken by the implementation. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_tasking.12.c " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_tasking.12.f90 " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows the use of the `final` clause and the `omp_in_final` API call in a recursive binary search program. To reduce overhead, once a certain depth of recursion is reached the program uses the `final` clause to create only included tasks, which allow additional optimizations. " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The use of the `omp_in_final` API call allows programmers to optimize their code by specifying which parts of the program are not necessary when a task can create only included tasks (that is, the code is inside a `final` task). In this example, the use of a different state variable is not necessary so once the program reaches the part of the computation that is finalized and copying from the parent state to the new state is eliminated. The allocation of `new_state` in the stack could also be avoided but it would make this example less clear. The `final` clause is most effective when used in conjunction with the `mergeable` clause since all tasks created in a `final` task region are included tasks that can be merged if the `mergeable` clause is present. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_tasking.13.c " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_tasking.13.f90 " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example illustrates the difference between the `if` and the `final` clauses. The `if` clause has a local effect. In the first nest of tasks, the one that has the `if` clause will be undeferred but the task nested inside that task will not be affected by the `if` clause and will be created as usual. Alternatively, the `final` clause affects all `task` constructs in the `final` task region but not the `final` task itself. In the second nest of tasks, the nested tasks will be created as included tasks. Note also that the conditions for the `if` and `final` clauses are usually the opposite. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_tasking.14.c " + ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_tasking.9.f" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_tasking.14.f90 " ] - }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the following example, `lock` is held across a task scheduling point. However, according to the scheduling restrictions, the executing thread can't begin executing one of the non-descendant tasks that also acquires `lock` before the task region is complete. Therefore, no deadlock is possible." - ] - }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_tasking.10.c" - ] - }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_tasking.10.f90" - ] - }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following examples illustrate the use of the `mergeable` clause in the `task` construct. In this first example, the `task` construct has been annotated with the `mergeable` clause. The addition of this clause allows the implementation to reuse the data environment (including the ICVs) of the parent task for the task inside `foo` if the task is included or undeferred. Thus, the result of the execution may differ depending on whether the task is merged or not. Therefore the mergeable clause needs to be used with caution. In this example, the use of the mergeable clause is safe. As `x` is a shared variable the outcome does not depend on whether or not the task is merged (that is, the task will always increment the same variable and will always compute the same value for `x` )." - ] - }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_tasking.11.c" - ] - }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_tasking.11.f90" - ] - }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " This second example shows an incorrect use of the `mergeable` clause. In this example, the created task will access different instances of the variable `x` if the task is not merged, as `x` is `firstprivate` , but it will access the same variable `x` if the task is merged. As a result, the behavior of the program is unspecified and it can print two different values for `x` depending on the decisions taken by the implementation." - ] - }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_tasking.12.c" - ] - }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_tasking.12.f90" - ] - }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows the use of the `final` clause and the `omp_in_final` API call in a recursive binary search program. To reduce overhead, once a certain depth of recursion is reached the program uses the `final` clause to create only included tasks, which allow additional optimizations." - ] - }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The use of the `omp_in_final` API call allows programmers to optimize their code by specifying which parts of the program are not necessary when a task can create only included tasks (that is, the code is inside a `final` task). In this example, the use of a different state variable is not necessary so once the program reaches the part of the computation that is finalized and copying from the parent state to the new state is eliminated. The allocation of `new_state` in the stack could also be avoided but it would make this example less clear. The `final` clause is most effective when used in conjunction with the `mergeable` clause since all tasks created in a `final` task region are included tasks that can be merged if the `mergeable` clause is present." - ] - }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_tasking.13.c" - ] - }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_tasking.13.f90" - ] - }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example illustrates the difference between the `if` and the `final` clauses. The `if` clause has a local effect. In the first nest of tasks, the one that has the `if` clause will be undeferred but the task nested inside that task will not be affected by the `if` clause and will be created as usual. Alternatively, the `final` clause affects all `task` constructs in the `final` task region but not the `final` task itself. In the second nest of tasks, the nested tasks will be created as included tasks. Note also that the conditions for the `if` and `final` clauses are usually the opposite." - ] - }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_tasking.14.c" - ] - }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_tasking.14.f90" - ] - }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_taskloop.ipynb b/notebook/Examples_taskloop.ipynb index 44c573e..2b03efa 100644 --- a/notebook/Examples_taskloop.ipynb +++ b/notebook/Examples_taskloop.ipynb @@ -1,45 +1,45 @@ { "cells": [ -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### The `taskloop` Construct " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### The `taskloop` Construct " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example illustrates how to execute a long running task concurrently with tasks created with a `taskloop` directive for a loop having unbalanced amounts of work for its iterations. The `grainsize` clause specifies that each task is to execute at least 500 iterations of the loop. The `nogroup` clause removes the implicit taskgroup of the `taskloop` construct; the explicit `taskgroup` construct in the example ensures that the function is not exited before the long-running task and the loops have finished execution. cexample{taskloop}{1} " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example illustrates how to execute a long running task concurrently with tasks created with a `taskloop` directive for a loop having unbalanced amounts of work for its iterations. The `grainsize` clause specifies that each task is to execute at least 500 iterations of the loop. The `nogroup` clause removes the implicit taskgroup of the `taskloop` construct; the explicit `taskgroup` construct in the example ensures that the function is not exited before the long-running task and the loops have finished execution. cexample{taskloop}{1} " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ffreeexample{taskloop}{1} " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ffreeexample{taskloop}{1} " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_taskyield.ipynb b/notebook/Examples_taskyield.ipynb index 3babc48..a206dd9 100644 --- a/notebook/Examples_taskyield.ipynb +++ b/notebook/Examples_taskyield.ipynb @@ -1,42 +1,42 @@ { "cells": [ -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### The `taskyield` Construct" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### The `taskyield` Construct " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example illustrates the use of the `taskyield` directive. The tasks in the example compute something useful and then do some computation that must be done in a critical region. By using `taskyield` when a task cannot get access to the `critical` region the implementation can suspend the current task and schedule some other task that can do something useful. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example illustrates the use of the `taskyield` directive. The tasks in the example compute something useful and then do some computation that must be done in a critical region. By using `taskyield` when a task cannot get access to the `critical` region the implementation can suspend the current task and schedule some other task that can do something useful. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_taskyield.1.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_taskyield.1.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_taskyield.1.f90" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_taskyield.1.f90 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_teams.ipynb b/notebook/Examples_teams.ipynb index 750c223..17b949f 100644 --- a/notebook/Examples_teams.ipynb +++ b/notebook/Examples_teams.ipynb @@ -1,293 +1,293 @@ { "cells": [ -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### `teams` Constructs" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### `teams` Constructs " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "subsection{ `target` and `teams` Constructs with `omp_get_num_teams` " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "subsection{ `target` and `teams` Constructs with `omp_get_num_teams` " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " and `omp_get_team_num` Routines}" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " and `omp_get_team_num` Routines} " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows how the `target` and `teams` constructs are used to create a league of thread teams that execute a region. The `teams` construct creates a league of at most two teams where the master thread of each team executes the `teams` region." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows how the `target` and `teams` constructs are used to create a league of thread teams that execute a region. The `teams` construct creates a league of at most two teams where the master thread of each team executes the `teams` region. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `omp_get_num_teams` routine returns the number of teams executing in a `teams` region. The `omp_get_team_num` routine returns the team number, which is an integer between 0 and one less than the value returned by `omp_get_num_teams` . The following example manually distributes a loop across two teams." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `omp_get_num_teams` routine returns the number of teams executing in a `teams` region. The `omp_get_team_num` routine returns the team number, which is an integer between 0 and one less than the value returned by `omp_get_num_teams` . The following example manually distributes a loop across two teams. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_teams.1.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_teams.1.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_teams.1.f90" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_teams.1.f90 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### `target` , `teams` , and `distribute` Constructs" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### `target` , `teams` , and `distribute` Constructs " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows how the `target` , `teams` , and `distribute` constructs are used to execute a loop nest in a `target` region. The `teams` construct creates a league and the master thread of each team executes the `teams` region. The `distribute` construct schedules the subsequent loop iterations across the master threads of each team." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows how the `target` , `teams` , and `distribute` constructs are used to execute a loop nest in a `target` region. The `teams` construct creates a league and the master thread of each team executes the `teams` region. The `distribute` construct schedules the subsequent loop iterations across the master threads of each team. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The number of teams in the league is less than or equal to the variable _num_blocks_ . Each team in the league has a number of threads less than or equal to the variable _block_threads_ . The iterations in the outer loop are distributed among the master threads of each team." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The number of teams in the league is less than or equal to the variable _num_blocks_ . Each team in the league has a number of threads less than or equal to the variable _block_threads_ . The iterations in the outer loop are distributed among the master threads of each team. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " When a team's master thread encounters the parallel loop construct before the inner loop, the other threads in its team are activated. The team executes the `parallel` region and then workshares the execution of the loop." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " When a team's master thread encounters the parallel loop construct before the inner loop, the other threads in its team are activated. The team executes the `parallel` region and then workshares the execution of the loop. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Each master thread executing the `teams` region has a private copy of the variable _sum_ that is created by the `reduction` clause on the `teams` construct. The master thread and all threads in its team have a private copy of the variable _sum_ that is created by the `reduction` clause on the parallel loop construct. The second private _sum_ is reduced into the master thread's private copy of _sum_ created by the `teams` construct. At the end of the `teams` region, each master thread's private copy of _sum_ is reduced into the final _sum_ that is implicitly mapped into the `target` region." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Each master thread executing the `teams` region has a private copy of the variable _sum_ that is created by the `reduction` clause on the `teams` construct. The master thread and all threads in its team have a private copy of the variable _sum_ that is created by the `reduction` clause on the parallel loop construct. The second private _sum_ is reduced into the master thread's private copy of _sum_ created by the `teams` construct. At the end of the `teams` region, each master thread's private copy of _sum_ is reduced into the final _sum_ that is implicitly mapped into the `target` region. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_teams.2.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_teams.2.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_teams.2.f90" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_teams.2.f90 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### `target` `teams` , and Distribute Parallel Loop Constructs" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### `target` `teams` , and Distribute Parallel Loop Constructs " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows how the `target` `teams` and distribute parallel loop constructs are used to execute a `target` region. The `target` `teams` construct creates a league of teams where the master thread of each team executes the `teams` region." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows how the `target` `teams` and distribute parallel loop constructs are used to execute a `target` region. The `target` `teams` construct creates a league of teams where the master thread of each team executes the `teams` region. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The distribute parallel loop construct schedules the loop iterations across the master threads of each team and then across the threads of each team." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The distribute parallel loop construct schedules the loop iterations across the master threads of each team and then across the threads of each team. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_teams.3.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_teams.3.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_teams.3.f90" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_teams.3.f90 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "subsection{ `target` `teams` and Distribute Parallel Loop " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "subsection{ `target` `teams` and Distribute Parallel Loop " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Constructs with Scheduling Clauses}" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Constructs with Scheduling Clauses} " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows how the `target` `teams` and distribute parallel loop constructs are used to execute a `target` region. The `teams` construct creates a league of at most eight teams where the master thread of each team executes the `teams` region. The number of threads in each team is less than or equal to 16." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows how the `target` `teams` and distribute parallel loop constructs are used to execute a `target` region. The `teams` construct creates a league of at most eight teams where the master thread of each team executes the `teams` region. The number of threads in each team is less than or equal to 16. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `distribute` parallel loop construct schedules the subsequent loop iterations across the master threads of each team and then across the threads of each team." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `distribute` parallel loop construct schedules the subsequent loop iterations across the master threads of each team and then across the threads of each team. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `dist_schedule` clause on the distribute parallel loop construct indicates that loop iterations are distributed to the master thread of each team in chunks of 1024 iterations." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `dist_schedule` clause on the distribute parallel loop construct indicates that loop iterations are distributed to the master thread of each team in chunks of 1024 iterations. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `schedule` clause indicates that the 1024 iterations distributed to a master thread are then assigned to the threads in its associated team in chunks of 64 iterations." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `schedule` clause indicates that the 1024 iterations distributed to a master thread are then assigned to the threads in its associated team in chunks of 64 iterations. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_teams.4.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_teams.4.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_teams.4.f90" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_teams.4.f90 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### `target` `teams` and `distribute` `simd` Constructs" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### `target` `teams` and `distribute` `simd` Constructs " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows how the `target` `teams` and `distribute` `simd` constructs are used to execute a loop in a `target` region. The `target` `teams` construct creates a league of teams where the master thread of each team executes the `teams` region." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows how the `target` `teams` and `distribute` `simd` constructs are used to execute a loop in a `target` region. The `target` `teams` construct creates a league of teams where the master thread of each team executes the `teams` region. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `distribute` `simd` construct schedules the loop iterations across the master thread of each team and then uses SIMD parallelism to execute the iterations." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `distribute` `simd` construct schedules the loop iterations across the master thread of each team and then uses SIMD parallelism to execute the iterations. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_teams.5.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_teams.5.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_teams.5.f90" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_teams.5.f90 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### `target` `teams` and Distribute Parallel Loop SIMD Constructs" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### `target` `teams` and Distribute Parallel Loop SIMD Constructs " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows how the `target` `teams` and the distribute parallel loop SIMD constructs are used to execute a loop in a `target` `teams` region. The `target` `teams` construct creates a league of teams where the master thread of each team executes the `teams` region." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows how the `target` `teams` and the distribute parallel loop SIMD constructs are used to execute a loop in a `target` `teams` region. The `target` `teams` construct creates a league of teams where the master thread of each team executes the `teams` region. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The distribute parallel loop SIMD construct schedules the loop iterations across the master thread of each team and then across the threads of each team where each thread uses SIMD parallelism." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The distribute parallel loop SIMD construct schedules the loop iterations across the master thread of each team and then across the threads of each team where each thread uses SIMD parallelism. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_teams.6.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_teams.6.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_teams.6.f90" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_teams.6.f90 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_threadprivate.ipynb b/notebook/Examples_threadprivate.ipynb index ad88b35..d4b58b5 100644 --- a/notebook/Examples_threadprivate.ipynb +++ b/notebook/Examples_threadprivate.ipynb @@ -1,269 +1,269 @@ { "cells": [ -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### The `threadprivate` Directive" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### The `threadprivate` Directive " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following examples demonstrate how to use the `threadprivate` directive to give each thread a separate counter." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following examples demonstrate how to use the `threadprivate` directive to give each thread a separate counter. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_threadprivate.1.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_threadprivate.1.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_threadprivate.1.f" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_threadprivate.1.f " ] - }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ccppspecificstart The following example uses `threadprivate` on a static variable:" + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ccppspecificstart The following example uses `threadprivate` on a static variable: " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_threadprivate.2.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_threadprivate.2.c " ] - }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example demonstrates unspecified behavior for the initialization of a `threadprivate` variable. A `threadprivate` variable is initialized once at an unspecified point before its first reference. Because `a` is constructed using the value of `x` (which is modified by the statement `x++` ), the value of `a.val` at the start of the `parallel` region could be either 1 or 2. This problem is avoided for `b` , which uses an auxiliary `const` variable and a copy-constructor." + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example demonstrates unspecified behavior for the initialization of a `threadprivate` variable. A `threadprivate` variable is initialized once at an unspecified point before its first reference. Because `a` is constructed using the value of `x` (which is modified by the statement `x++` ), the value of `a.val` at the start of the `parallel` region could be either 1 or 2. This problem is avoided for `b` , which uses an auxiliary `const` variable and a copy-constructor. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_cppnexamplethreadprivate3" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_cppnexamplethreadprivate3 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ccppspecificend" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ccppspecificend " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following examples show non-conforming uses and correct uses of the `threadprivate` directive. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following examples show non-conforming uses and correct uses of the `threadprivate` directive. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " fortranspecificstart The following example is non-conforming because the common block is not declared local to the subroutine that refers to it:" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " fortranspecificstart The following example is non-conforming because the common block is not declared local to the subroutine that refers to it: " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_threadprivate.2.f" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_threadprivate.2.f " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example is also non-conforming because the common block is not declared local to the subroutine that refers to it:" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example is also non-conforming because the common block is not declared local to the subroutine that refers to it: " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_threadprivate.3.f" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_threadprivate.3.f " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example is a correct rewrite of the previous example:" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example is a correct rewrite of the previous example: " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_threadprivate.4.f" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_threadprivate.4.f " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following is an example of the use of `threadprivate` for local variables: \n", -" blue line floater at top of this page for 'Fortran, cont.' [t!] linewitharrows{-1}{dashed}{Fortran (cont.)}{8em} " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following is an example of the use of `threadprivate` for local variables: \n", +" blue line floater at top of this page for 'Fortran, cont.' [t!] linewitharrows{-1}{dashed}{Fortran (cont.)}{8em} " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_threadprivate.5.f" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_threadprivate.5.f " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The above program, if executed by two threads, will print one of the following two sets of output: " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The above program, if executed by two threads, will print one of the following two sets of output: " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " `a = 11 12 13` `ptr = 4` `i = 15` " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " `a = 11 12 13` `ptr = 4` `i = 15` " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " `A is not allocated` `ptr = 4` `i = 5` " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " `A is not allocated` `ptr = 4` `i = 5` " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " or" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " or " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " `A is not allocated` `ptr = 4` `i = 15` " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " `A is not allocated` `ptr = 4` `i = 15` " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " `a = 1 2 3` `ptr = 4` `i = 5` " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " `a = 1 2 3` `ptr = 4` `i = 5` " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following is an example of the use of `threadprivate` for module variables: \n", -" blue line floater at top of this page for 'Fortran, cont.' [t!] linewitharrows{-1}{dashed}{Fortran (cont.)}{8em} " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following is an example of the use of `threadprivate` for module variables: \n", +" blue line floater at top of this page for 'Fortran, cont.' [t!] linewitharrows{-1}{dashed}{Fortran (cont.)}{8em} " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_threadprivate.6.f" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_threadprivate.6.f " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " fortranspecificend" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " fortranspecificend " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_cppspecificstart" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_cppspecificstart " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example illustrates initialization of `threadprivate` variables for class-type `T` . `t1` is default constructed, `t2` is constructed taking a constructor accepting one argument of integer type, `t3` is copy constructed with argument `f()` :" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example illustrates initialization of `threadprivate` variables for class-type `T` . `t1` is default constructed, `t2` is constructed taking a constructor accepting one argument of integer type, `t3` is copy constructed with argument `f()` : " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_cppnexamplethreadprivate4" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_cppnexamplethreadprivate4 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example illustrates the use of `threadprivate` for static class members. The `threadprivate` directive for a static class member must be placed inside the class definition." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example illustrates the use of `threadprivate` for static class members. The `threadprivate` directive for a static class member must be placed inside the class definition. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_cppnexamplethreadprivate5" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_cppnexamplethreadprivate5 " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_cppspecificend" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_cppspecificend " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_workshare.ipynb b/notebook/Examples_workshare.ipynb index 1324a16..c3a85f4 100644 --- a/notebook/Examples_workshare.ipynb +++ b/notebook/Examples_workshare.ipynb @@ -1,180 +1,180 @@ { "cells": [ -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### The `workshare` Construct" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### The `workshare` Construct " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " fortranspecificstart" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " fortranspecificstart " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following are examples of the `workshare` construct. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following are examples of the `workshare` construct. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the following example, `workshare` spreads work across the threads executing the `parallel` region, and there is a barrier after the last statement. Implementations must enforce Fortran execution rules inside of the `workshare` block." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the following example, `workshare` spreads work across the threads executing the `parallel` region, and there is a barrier after the last statement. Implementations must enforce Fortran execution rules inside of the `workshare` block. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_workshare.1.f" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_workshare.1.f " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the following example, the barrier at the end of the first `workshare` region is eliminated with a `nowait` clause. Threads doing `CC = DD` immediately begin work on `EE = FF` when they are done with `CC = DD` ." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the following example, the barrier at the end of the first `workshare` region is eliminated with a `nowait` clause. Threads doing `CC = DD` immediately begin work on `EE = FF` when they are done with `CC = DD` . " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_workshare.2.f" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_workshare.2.f " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -" blue line floater at top of this page for 'Fortran, cont.' [t!] linewitharrows{-1}{dashed}{Fortran (cont.)}{8em} " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +" blue line floater at top of this page for 'Fortran, cont.' [t!] linewitharrows{-1}{dashed}{Fortran (cont.)}{8em} " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows the use of an `atomic` directive inside a `workshare` construct. The computation of `SUM(AA)` is workshared, but the update to `R` is atomic." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows the use of an `atomic` directive inside a `workshare` construct. The computation of `SUM(AA)` is workshared, but the update to `R` is atomic. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_workshare.3.f" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_workshare.3.f " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Fortran `WHERE` and `FORALL` statements are emph{compound statements}, made up of a emph{control} part and a emph{statement} part. When `workshare` is applied to one of these compound statements, both the control and the statement parts are workshared. The following example shows the use of a `WHERE` statement in a `workshare` construct." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Fortran `WHERE` and `FORALL` statements are emph{compound statements}, made up of a emph{control} part and a emph{statement} part. When `workshare` is applied to one of these compound statements, both the control and the statement parts are workshared. The following example shows the use of a `WHERE` statement in a `workshare` construct. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Each task gets worked on in order by the threads:" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Each task gets worked on in order by the threads: " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " `AA = BB` then `CC = DD` then `EE .ne. 0` then `FF = 1 / EE` then `GG = HH` " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " `AA = BB` then `CC = DD` then `EE .ne. 0` then `FF = 1 / EE` then `GG = HH` " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_workshare.4.f" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_workshare.4.f " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -" blue line floater at top of this page for 'Fortran, cont.' [t!] linewitharrows{-1}{dashed}{Fortran (cont.)}{8em} " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +" blue line floater at top of this page for 'Fortran, cont.' [t!] linewitharrows{-1}{dashed}{Fortran (cont.)}{8em} " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the following example, an assignment to a shared scalar variable is performed by one thread in a `workshare` while all other threads in the team wait." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the following example, an assignment to a shared scalar variable is performed by one thread in a `workshare` while all other threads in the team wait. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_workshare.5.f" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_workshare.5.f " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example contains an assignment to a private scalar variable, which is performed by one thread in a `workshare` while all other threads wait. It is non-conforming because the private scalar variable is undefined after the assignment statement. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example contains an assignment to a private scalar variable, which is performed by one thread in a `workshare` while all other threads wait. It is non-conforming because the private scalar variable is undefined after the assignment statement. " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_workshare.6.f" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_workshare.6.f " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Fortran execution rules must be enforced inside a `workshare` construct. In the following example, the same result is produced in the following program fragment regardless of whether the code is executed sequentially or inside an OpenMP program with multiple threads:" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Fortran execution rules must be enforced inside a `workshare` construct. In the following example, the same result is produced in the following program fragment regardless of whether the code is executed sequentially or inside an OpenMP program with multiple threads: " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_workshare.7.f" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_workshare.7.f " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " fortranspecificend" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " fortranspecificend " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_worksharing_critical.ipynb b/notebook/Examples_worksharing_critical.ipynb index caecc1e..51f73d1 100644 --- a/notebook/Examples_worksharing_critical.ipynb +++ b/notebook/Examples_worksharing_critical.ipynb @@ -1,42 +1,42 @@ { "cells": [ -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Worksharing Constructs Inside a `critical` Construct" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Worksharing Constructs Inside a `critical` Construct " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example demonstrates using a worksharing construct inside a `critical` construct. This example is conforming because the worksharing `single` region is not closely nested inside the `critical` region. A single thread executes the one and only section in the `sections` region, and executes the `critical` region. The same thread encounters the nested `parallel` region, creates a new team of threads, and becomes the master of the new team. One of the threads in the new team enters the `single` region and increments `i` by `1` . At the end of this example `i` is equal to `2` ." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example demonstrates using a worksharing construct inside a `critical` construct. This example is conforming because the worksharing `single` region is not closely nested inside the `critical` region. A single thread executes the one and only section in the `sections` region, and executes the `critical` region. The same thread encounters the nested `parallel` region, creates a new team of threads, and becomes the master of the new team. One of the threads in the new team enters the `single` region and increments `i` by `1` . At the end of this example `i` is equal to `2` . " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_worksharing_critical.1.c" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_worksharing_critical.1.c " ] }, -{ - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_worksharing_critical.1.f" + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_worksharing_critical.1.f " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/History.ipynb b/notebook/History.ipynb index 396097a..84a5e3c 100644 --- a/notebook/History.ipynb +++ b/notebook/History.ipynb @@ -1,24 +1,24 @@ { "cells": [ -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ## Document Revision History" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ## Document Revision History " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Changes from 4.0.2 to 4.5.0" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Changes from 4.0.2 to 4.5.0 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", "* Reorganized into chapters of major topics \n", "* Included file extensions in example labels to indicate source type \n", "* Applied the explicit `map(tofrom)` for scalar variables in a number of examples to comply with the change of the default behavior for scalar variables from `map(tofrom)` to `firstprivate` in the 4.5 specification \n", @@ -34,62 +34,62 @@ "* doacross loop nest () \n", "* locks with hints () \n", "* C/C++ array reduction () \n", -"* C++ reference types in data sharing clauses () " +"* C++ reference types in data sharing clauses () " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Changes from 4.0.1 to 4.0.2" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Changes from 4.0.1 to 4.0.2 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", "* Names of examples were changed from numbers to mnemonics \n", "* Added SIMD examples () \n", "* Applied miscellaneous fixes in several source codes \n", -"* Added the revision history " +"* Added the revision history " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Changes from 4.0 to 4.0.1" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Changes from 4.0 to 4.0.1 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Added the following new examples: \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Added the following new examples: \n", "* the `proc_bind` clause () \n", -"* the `taskgroup` construct () " +"* the `taskgroup` construct () " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Changes from 3.1 to 4.0" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Changes from 3.1 to 4.0 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Beginning with OpenMP 4.0, examples were placed in a separate document from the specification document." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Beginning with OpenMP 4.0, examples were placed in a separate document from the specification document. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Version 4.0 added the following new examples: \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Version 4.0 added the following new examples: \n", "* task dependences () \n", "* `target` construct () \n", "* `target` `data` construct () \n", @@ -100,14 +100,14 @@ "* array sections in device constructs () \n", "* device runtime routines () \n", "* Fortran ASSOCIATE construct () \n", -"* cancellation constructs () " +"* cancellation constructs () " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Introduction_Chapt.ipynb b/notebook/Introduction_Chapt.ipynb index fc9b114..753ae96 100644 --- a/notebook/Introduction_Chapt.ipynb +++ b/notebook/Introduction_Chapt.ipynb @@ -1,10 +1,10 @@ { "cells": [ -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", " This is the introduction for the OpenMP Examples document. \n", " This is an included file. See the master file (openmp-examples.tex) for more information. \n", " \n", @@ -39,86 +39,86 @@ " Prefer emph{} to italicize terminology, e.g.: \n", " This is a emph{definition}, not a placeholder. \n", " This is a _var-name_ . \n", -"" +" " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "chapter*{Introduction}" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "chapter*{Introduction} " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " addcontentsline{toc}{chapter}{protectnumberline{}Introduction} This collection of programming examples supplements the OpenMP API for Shared Memory Parallelization specifications, and is not part of the formal specifications. It assumes familiarity with the OpenMP specifications, and shares the typographical conventions used in that document." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " addcontentsline{toc}{chapter}{protectnumberline{}Introduction} This collection of programming examples supplements the OpenMP API for Shared Memory Parallelization specifications, and is not part of the formal specifications. It assumes familiarity with the OpenMP specifications, and shares the typographical conventions used in that document. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " notestart noteheader – This first release of the OpenMP Examples reflects the OpenMP Version 4.5 specifications. Additional examples are being developed and will be published in future releases of this document. noteend" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " notestart noteheader – This first release of the OpenMP Examples reflects the OpenMP Version 4.5 specifications. Additional examples are being developed and will be published in future releases of this document. noteend " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The OpenMP API specification provides a model for parallel programming that is portable across shared memory architectures from different vendors. Compilers from numerous vendors support the OpenMP API." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The OpenMP API specification provides a model for parallel programming that is portable across shared memory architectures from different vendors. Compilers from numerous vendors support the OpenMP API. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The directives, library routines, and environment variables demonstrated in this document allow users to create and manage parallel programs while permitting portability. The directives extend the C, C++ and Fortran base languages with single program multiple data (SPMD) constructs, tasking constructs, device constructs, worksharing constructs, and synchronization constructs, and they provide support for sharing and privatizing data. The functionality to control the runtime environment is provided by library routines and environment variables. Compilers that support the OpenMP API often include a command line option to the compiler that activates and allows interpretation of all OpenMP directives." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The directives, library routines, and environment variables demonstrated in this document allow users to create and manage parallel programs while permitting portability. The directives extend the C, C++ and Fortran base languages with single program multiple data (SPMD) constructs, tasking constructs, device constructs, worksharing constructs, and synchronization constructs, and they provide support for sharing and privatizing data. The functionality to control the runtime environment is provided by library routines and environment variables. Compilers that support the OpenMP API often include a command line option to the compiler that activates and allows interpretation of all OpenMP directives. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The latest source codes for OpenMP Examples can be downloaded from the `sources` directory at https://github.com/OpenMP/Examples The codes for this OpenMP VER{} Examples document have the tag _vVER_ ." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The latest source codes for OpenMP Examples can be downloaded from the `sources` directory at https://github.com/OpenMP/Examples The codes for this OpenMP VER{} Examples document have the tag _vVER_ . " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -" https://github.com/OpenMP/Examples/tree/master/sources " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +" https://github.com/OpenMP/Examples/tree/master/sources " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Complete information about the OpenMP API and a list of the compilers that support the OpenMP API can be found at the OpenMP.org web site" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Complete information about the OpenMP API and a list of the compilers that support the OpenMP API can be found at the OpenMP.org web site " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " `http://www.openmp.org` " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " `http://www.openmp.org` " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -" This is the end of introduction.tex of the OpenMP Examples document." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +" This is the end of introduction.tex of the OpenMP Examples document. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Title_Page.ipynb b/notebook/Title_Page.ipynb index 260ecab..fbfcc8d 100644 --- a/notebook/Title_Page.ipynb +++ b/notebook/Title_Page.ipynb @@ -1,10 +1,10 @@ { "cells": [ -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", "\n", "\n", "\n", @@ -99,104 +99,104 @@ "\n", "\n", " \n", -" Title page" +" Title page " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " hspace{-6em} includegraphics[width=0.4textwidth]{openmp-logo.png} " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " hspace{-6em} includegraphics[width=0.4textwidth]{openmp-logo.png} " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " {-0.75in}{0in} Huge textsf{OpenMPApplication ProgrammingInterface}" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " {-0.75in}{0in} Huge textsf{OpenMPApplication ProgrammingInterface} " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -" An optional subtitle can go here: vspace{0.5in}textsf{Examples}vspace{-0.7in} normalsize" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +" An optional subtitle can go here: vspace{0.5in}textsf{Examples}vspace{-0.7in} normalsize " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " vspace{1.0in}" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " vspace{1.0in} " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " textbf{Version VER{} -- VERDATE} " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " textbf{Version VER{} -- VERDATE} " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " vspace{2.3in} \n", -"was 3.0" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " vspace{2.3in} \n", +"was 3.0 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Source codes for OpenMP VER{} Examples can be downloaded from https://github.com/OpenMP/Examples/tree/vVER {github}." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Source codes for OpenMP VER{} Examples can be downloaded from https://github.com/OpenMP/Examples/tree/vVER {github}. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " {0pt}{1em}setlength{parskip}{0.25baselineskip}\n", -" Copyright © 1997-2016 OpenMP Architecture Review Board. Permission to copy without fee all or part of this material is granted, provided the OpenMP Architecture Review Board copyright notice and the title of this document appear. Notice is given that copying is by permission of OpenMP Architecture Review Board." + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " {0pt}{1em}setlength{parskip}{0.25baselineskip}\n", +" Copyright © 1997-2016 OpenMP Architecture Review Board. Permission to copy without fee all or part of this material is granted, provided the OpenMP Architecture Review Board copyright notice and the title of this document appear. Notice is given that copying is by permission of OpenMP Architecture Review Board. " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -" Blank page" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +" Blank page " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " clearpage thispagestyle{empty} phantom{a} emph{This page intentionally left blank}" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " clearpage thispagestyle{empty} phantom{a} emph{This page intentionally left blank} " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", "This working version enacted the following tickets: 180, 295, 299, 342, 381, \n", -"and a few other editorial changes. vfill" +"and a few other editorial changes. vfill " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/openmp-examples.ipynb b/notebook/openmp-examples.ipynb index b7649f7..d60a9a2 100644 --- a/notebook/openmp-examples.ipynb +++ b/notebook/openmp-examples.ipynb @@ -1,10 +1,10 @@ { "cells": [ -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", " Welcome to openmp-examples.tex. \n", " This is the master LaTex file for the OpenMP Examples document. \n", " \n", @@ -51,190 +51,190 @@ " Prefer emph{} to italicize terminology, e.g.: \n", " This is a emph{definition}, not a placeholder. \n", " This is a _var-name_ . \n", -"" +" " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -" The following says letter size, but the style sheet may change the size documentclass[10pt,letterpaper,twoside,makeidx,hidelinks]{scrreprt}" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +" The following says letter size, but the style sheet may change the size documentclass[10pt,letterpaper,twoside,makeidx,hidelinks]{scrreprt} " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -" Text to appear in the footer on even-numbered pages: newcommand{VER}{4.5.0} newcommand{VERDATE}{November 2016} newcommand{footerText}{OpenMP Examples Version VER{} - VERDATE}" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +" Text to appear in the footer on even-numbered pages: newcommand{VER}{4.5.0} newcommand{VERDATE}{November 2016} newcommand{footerText}{OpenMP Examples Version VER{} - VERDATE} " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -" Unified style sheet for OpenMP documents: input{openmp.sty}" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +" Unified style sheet for OpenMP documents: input{openmp.sty} " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " pagenumbering{roman} input{Title_Page}" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " pagenumbering{roman} input{Title_Page} " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " setcounter{page}{0} setcounter{tocdepth}{2}" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " setcounter{page}{0} setcounter{tocdepth}{2} " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " {1.3} tableofcontents " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " {1.3} tableofcontents " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -" Uncomment the next line to enable line numbering on the main body text: linenumberspagewiselinenumbers" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", +" Uncomment the next line to enable line numbering on the main body text: linenumberspagewiselinenumbers " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " newpagepagenumbering{arabic}" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " newpagepagenumbering{arabic} " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " input{Introduction_Chapt} input{Examples_Chapt}" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " input{Introduction_Chapt} input{Examples_Chapt} " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " setcounter{chapter}{0} \n", -" start chapter numbering here" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " setcounter{chapter}{0} \n", +" start chapter numbering here " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " input{Chap_parallel_execution} input{Examples_ploop} input{Examples_parallel} input{Examples_nthrs_nesting} input{Examples_nthrs_dynamic} input{Examples_fort_do} input{Examples_nowait} input{Examples_collapse} \n", -" linear Clause 475 input{Examples_linear_in_loop} input{Examples_psections} input{Examples_fpriv_sections} input{Examples_single} input{Examples_workshare} input{Examples_master} input{Examples_pra_iterator} input{Examples_set_dynamic_nthrs} input{Examples_get_nthrs}" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " input{Chap_parallel_execution} input{Examples_ploop} input{Examples_parallel} input{Examples_nthrs_nesting} input{Examples_nthrs_dynamic} input{Examples_fort_do} input{Examples_nowait} input{Examples_collapse} \n", +" linear Clause 475 input{Examples_linear_in_loop} input{Examples_psections} input{Examples_fpriv_sections} input{Examples_single} input{Examples_workshare} input{Examples_master} input{Examples_pra_iterator} input{Examples_set_dynamic_nthrs} input{Examples_get_nthrs} " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " input{Chap_affinity} input{Examples_affinity} input{Examples_affinity_query}" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " input{Chap_affinity} input{Examples_affinity} input{Examples_affinity_query} " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " input{Chap_tasking} input{Examples_tasking} input{Examples_task_priority} input{Examples_task_dep} input{Examples_taskgroup} input{Examples_taskyield} input{Examples_taskloop}" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " input{Chap_tasking} input{Examples_tasking} input{Examples_task_priority} input{Examples_task_dep} input{Examples_taskgroup} input{Examples_taskyield} input{Examples_taskloop} " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " input{Chap_devices} input{Examples_target} input{Examples_target_data} input{Examples_target_unstructured_data} input{Examples_target_update} input{Examples_declare_target} \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " input{Chap_devices} input{Examples_target} input{Examples_target_data} input{Examples_target_unstructured_data} input{Examples_target_update} input{Examples_declare_target} \n", " Link clause 474 input{Examples_teams} input{Examples_async_target_depend} input{Examples_async_target_with_tasks} \n", "Title change of 57.1 and 57.2 \n", "New subsection input{Examples_async_target_nowait} input{Examples_async_target_nowait_depend} input{Examples_array_sections} \n", " Structure Element in map 487 input{Examples_device} \n", -" MemoryRoutine and Device ptr 473" +" MemoryRoutine and Device ptr 473 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " input{Chap_SIMD} input{Examples_SIMD} \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " input{Chap_SIMD} input{Examples_SIMD} \n", " Forward Depend 370 \n", " simdlen 476 \n", -" simd linear modifier 480" +" simd linear modifier 480 " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " input{Chap_synchronization} input{Examples_critical} input{Examples_worksharing_critical} input{Examples_barrier_regions} input{Examples_atomic} input{Examples_atomic_restrict} input{Examples_flush_nolist} input{Examples_ordered} \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " input{Chap_synchronization} input{Examples_critical} input{Examples_worksharing_critical} input{Examples_barrier_regions} input{Examples_atomic} input{Examples_atomic_restrict} input{Examples_flush_nolist} input{Examples_ordered} \n", " Doacross loop 405 input{Examples_doacross} input{Examples_locks} input{Examples_init_lock} input{Examples_init_lock_with_hint} input{Examples_lock_owner} input{Examples_simple_lock} input{Examples_nestable_lock} \n", " \n", " LOCK with Hints 478 \n", " \n", " Hint Clause xxxxxx (included after init_lock) \n", " \n", -" Lock routines with hint " +" Lock routines with hint " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " input{Chap_data_environment} input{Examples_threadprivate} input{Examples_default_none} input{Examples_private} input{Examples_fort_loopvar} input{Examples_fort_sp_common} input{Examples_fort_sa_private} input{Examples_carrays_fpriv} input{Examples_lastprivate} input{Examples_reduction} \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " input{Chap_data_environment} input{Examples_threadprivate} input{Examples_default_none} input{Examples_private} input{Examples_fort_loopvar} input{Examples_fort_sp_common} input{Examples_fort_sa_private} input{Examples_carrays_fpriv} input{Examples_lastprivate} input{Examples_reduction} \n", " User UDR 287 \n", " C array reduction 377 input{Examples_copyin} input{Examples_copyprivate} input{Examples_cpp_reference} \n", " Fortran 2003 features 482 input{Examples_associate} \n", -"section--> subsection" +"section--> subsection " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " input{Chap_memory_model} input{Examples_mem_model} input{Examples_fort_race}" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " input{Chap_memory_model} input{Examples_mem_model} input{Examples_fort_race} " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " input{Chap_program_control} input{Examples_cond_comp} input{Examples_icv} \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " input{Chap_program_control} input{Examples_cond_comp} input{Examples_icv} \n", " If multi-ifs 471 input{Examples_standalone} input{Examples_cancellation} \n", -" New Section Nested Regions input{Examples_nested_loop} input{Examples_nesting_restrict}" +" New Section Nested Regions input{Examples_nested_loop} input{Examples_nesting_restrict} " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " setcounter{chapter}{0} \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " setcounter{chapter}{0} \n", " restart chapter numbering with 'letter A' renewcommand{thechapter}{Alph{chapter}}\n", -" appendix input{History}" +" appendix input{History} " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " ] }, -{ - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/tex2notebook.py b/notebook/tex2notebook.py index 8242774..f7a0936 100644 --- a/notebook/tex2notebook.py +++ b/notebook/tex2notebook.py @@ -32,23 +32,23 @@ '"nbformat_minor": 2\n' + \ '}\n' -MB = '{\n' + \ - ' "cell_type": "markdown",\n' + \ - ' "metadata": {},\n' + \ - ' "source": [\n' + \ +MB = ' {\n' + \ + ' "cell_type": "markdown",\n' + \ + ' "metadata": {},\n' + \ + ' "source": [\n' + \ + ' "' + +CB = ' {\n' + \ + ' "cell_type": "code",\n' + \ + ' "execution_count": null,\n' + \ + ' "metadata": {},\n' + \ + ' "outputs": [],\n' + \ + ' "source": [\n' + \ ' "' -CB = '{\n' + \ - ' "cell_type": "code",\n' + \ - ' "execution_count": null,\n' + \ - ' "metadata": {},\n' + \ - ' "outputs": [],\n' + \ - ' "source": [\n' + \ - ' "' - -E = '"\n ]\n },\n' +E = ' "\n ]\n },\n' E1 = ' \n ]\n },\n' -E2 = '"\n ]\n }\n' +E2 = ' "\n ]\n }\n' # Do some changes # ilegal symbols From 0daec20701f78e57c8e0eaad40600dbab1d4b955 Mon Sep 17 00:00:00 2001 From: Kewei Yan Date: Tue, 8 Oct 2019 11:42:16 -0400 Subject: [PATCH 09/21] test3 --- notebook/Chap_SIMD.ipynb | 28 +++---- notebook/Chap_affinity.ipynb | 28 +++---- notebook/Chap_data_environment.ipynb | 28 +++---- notebook/Chap_devices.ipynb | 28 +++---- notebook/Chap_memory_model.ipynb | 28 +++---- notebook/Chap_parallel_execution.ipynb | 28 +++---- notebook/Chap_program_control.ipynb | 28 +++---- notebook/Chap_synchronization.ipynb | 28 +++---- notebook/Chap_tasking.ipynb | 28 +++---- notebook/Examples_Chapt.ipynb | 28 +++---- notebook/Examples_SIMD.ipynb | 60 ++++++------- notebook/Examples_affinity.ipynb | 48 +++++------ notebook/Examples_affinity_query.ipynb | 32 +++---- notebook/Examples_array_sections.ipynb | 44 +++++----- notebook/Examples_associate.ipynb | 34 ++++---- notebook/Examples_async_target_depend.ipynb | 28 +++---- notebook/Examples_async_target_nowait.ipynb | 32 +++---- .../Examples_async_target_nowait_depend.ipynb | 32 +++---- .../Examples_async_target_with_tasks.ipynb | 36 ++++---- notebook/Examples_atomic.ipynb | 40 ++++----- notebook/Examples_atomic_restrict.ipynb | 38 ++++----- notebook/Examples_barrier_regions.ipynb | 32 +++---- notebook/Examples_cancellation.ipynb | 36 ++++---- notebook/Examples_carrays_fpriv.ipynb | 30 +++---- notebook/Examples_collapse.ipynb | 40 ++++----- notebook/Examples_cond_comp.ipynb | 32 +++---- notebook/Examples_copyin.ipynb | 32 +++---- notebook/Examples_copyprivate.ipynb | 40 ++++----- notebook/Examples_cpp_reference.ipynb | 34 ++++---- notebook/Examples_critical.ipynb | 36 ++++---- notebook/Examples_declare_target.ipynb | 56 ++++++------- notebook/Examples_default_none.ipynb | 32 +++---- notebook/Examples_device.ipynb | 42 +++++----- notebook/Examples_doacross.ipynb | 44 +++++----- notebook/Examples_flush_nolist.ipynb | 32 +++---- notebook/Examples_fort_do.ipynb | 32 +++---- notebook/Examples_fort_loopvar.ipynb | 32 +++---- notebook/Examples_fort_race.ipynb | 30 +++---- notebook/Examples_fort_sa_private.ipynb | 38 ++++----- notebook/Examples_fort_sp_common.ipynb | 38 ++++----- notebook/Examples_fpriv_sections.ipynb | 32 +++---- notebook/Examples_get_nthrs.ipynb | 36 ++++---- notebook/Examples_icv.ipynb | 32 +++---- notebook/Examples_init_lock.ipynb | 32 +++---- notebook/Examples_init_lock_with_hint.ipynb | 32 +++---- notebook/Examples_lastprivate.ipynb | 32 +++---- notebook/Examples_linear_in_loop.ipynb | 32 +++---- notebook/Examples_lock_owner.ipynb | 32 +++---- notebook/Examples_locks.ipynb | 28 +++---- notebook/Examples_master.ipynb | 32 +++---- notebook/Examples_mem_model.ipynb | 40 ++++----- notebook/Examples_nestable_lock.ipynb | 32 +++---- notebook/Examples_nested_loop.ipynb | 36 ++++---- notebook/Examples_nesting_restrict.ipynb | 52 ++++++------ notebook/Examples_nowait.ipynb | 36 ++++---- notebook/Examples_nthrs_dynamic.ipynb | 36 ++++---- notebook/Examples_nthrs_nesting.ipynb | 32 +++---- notebook/Examples_ordered.ipynb | 40 ++++----- notebook/Examples_parallel.ipynb | 32 +++---- notebook/Examples_ploop.ipynb | 32 +++---- notebook/Examples_pra_iterator.ipynb | 34 ++++---- notebook/Examples_private.ipynb | 40 ++++----- notebook/Examples_psections.ipynb | 32 +++---- notebook/Examples_reduction.ipynb | 48 +++++------ notebook/Examples_set_dynamic_nthrs.ipynb | 32 +++---- notebook/Examples_simple_lock.ipynb | 32 +++---- notebook/Examples_single.ipynb | 32 +++---- notebook/Examples_standalone.ipynb | 36 ++++---- notebook/Examples_target.ipynb | 54 ++++++------ notebook/Examples_target_data.ipynb | 56 ++++++------- .../Examples_target_unstructured_data.ipynb | 34 ++++---- notebook/Examples_target_update.ipynb | 36 ++++---- notebook/Examples_task_dep.ipynb | 48 +++++------ notebook/Examples_task_priority.ipynb | 32 +++---- notebook/Examples_taskgroup.ipynb | 32 +++---- notebook/Examples_tasking.ipynb | 84 +++++++++---------- notebook/Examples_taskloop.ipynb | 28 +++---- notebook/Examples_taskyield.ipynb | 32 +++---- notebook/Examples_teams.ipynb | 52 ++++++------ notebook/Examples_threadprivate.ipynb | 54 ++++++------ notebook/Examples_workshare.ipynb | 42 +++++----- notebook/Examples_worksharing_critical.ipynb | 32 +++---- notebook/History.ipynb | 28 +++---- notebook/Introduction_Chapt.ipynb | 28 +++---- notebook/Title_Page.ipynb | 28 +++---- notebook/openmp-examples.ipynb | 28 +++---- notebook/tex2notebook.py | 30 +++---- 87 files changed, 1562 insertions(+), 1562 deletions(-) diff --git a/notebook/Chap_SIMD.ipynb b/notebook/Chap_SIMD.ipynb index f453edd..ce6d018 100644 --- a/notebook/Chap_SIMD.ipynb +++ b/notebook/Chap_SIMD.ipynb @@ -55,19 +55,19 @@ "---end--- " ] } -], -"metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } -}, -"nbformat": 4, -"nbformat_minor": 2 + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/notebook/Chap_affinity.ipynb b/notebook/Chap_affinity.ipynb index f965bf0..30a7409 100644 --- a/notebook/Chap_affinity.ipynb +++ b/notebook/Chap_affinity.ipynb @@ -152,19 +152,19 @@ "---end--- " ] } -], -"metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } -}, -"nbformat": 4, -"nbformat_minor": 2 + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/notebook/Chap_data_environment.ipynb b/notebook/Chap_data_environment.ipynb index 4d9cb4a..9da5497 100644 --- a/notebook/Chap_data_environment.ipynb +++ b/notebook/Chap_data_environment.ipynb @@ -103,19 +103,19 @@ "---end--- " ] } -], -"metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } -}, -"nbformat": 4, -"nbformat_minor": 2 + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/notebook/Chap_devices.ipynb b/notebook/Chap_devices.ipynb index e0d8cdc..3670d95 100644 --- a/notebook/Chap_devices.ipynb +++ b/notebook/Chap_devices.ipynb @@ -63,19 +63,19 @@ "---end--- " ] } -], -"metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } -}, -"nbformat": 4, -"nbformat_minor": 2 + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/notebook/Chap_memory_model.ipynb b/notebook/Chap_memory_model.ipynb index 0dc5d90..58fda05 100644 --- a/notebook/Chap_memory_model.ipynb +++ b/notebook/Chap_memory_model.ipynb @@ -128,19 +128,19 @@ "---end--- " ] } -], -"metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } -}, -"nbformat": 4, -"nbformat_minor": 2 + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/notebook/Chap_parallel_execution.ipynb b/notebook/Chap_parallel_execution.ipynb index 34b0ff6..29a7827 100644 --- a/notebook/Chap_parallel_execution.ipynb +++ b/notebook/Chap_parallel_execution.ipynb @@ -147,19 +147,19 @@ "---end--- " ] } -], -"metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } -}, -"nbformat": 4, -"nbformat_minor": 2 + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/notebook/Chap_program_control.ipynb b/notebook/Chap_program_control.ipynb index 4fadc55..0d89d7a 100644 --- a/notebook/Chap_program_control.ipynb +++ b/notebook/Chap_program_control.ipynb @@ -133,19 +133,19 @@ "---end--- " ] } -], -"metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } -}, -"nbformat": 4, -"nbformat_minor": 2 + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/notebook/Chap_synchronization.ipynb b/notebook/Chap_synchronization.ipynb index e3ea386..0c919ac 100644 --- a/notebook/Chap_synchronization.ipynb +++ b/notebook/Chap_synchronization.ipynb @@ -72,19 +72,19 @@ "---end--- " ] } -], -"metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } -}, -"nbformat": 4, -"nbformat_minor": 2 + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/notebook/Chap_tasking.ipynb b/notebook/Chap_tasking.ipynb index a4514cd..22c1f6e 100644 --- a/notebook/Chap_tasking.ipynb +++ b/notebook/Chap_tasking.ipynb @@ -57,19 +57,19 @@ "---end--- " ] } -], -"metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } -}, -"nbformat": 4, -"nbformat_minor": 2 + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/notebook/Examples_Chapt.ipynb b/notebook/Examples_Chapt.ipynb index 0036111..cf5ad42 100644 --- a/notebook/Examples_Chapt.ipynb +++ b/notebook/Examples_Chapt.ipynb @@ -32,19 +32,19 @@ "---end--- " ] } -], -"metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } -}, -"nbformat": 4, -"nbformat_minor": 2 + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/notebook/Examples_SIMD.ipynb b/notebook/Examples_SIMD.ipynb index cdb52d4..e930057 100644 --- a/notebook/Examples_SIMD.ipynb +++ b/notebook/Examples_SIMD.ipynb @@ -21,7 +21,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_SIMD.1.c " + "%load ../sources/Example_SIMD.1.c " ] }, { @@ -30,7 +30,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_SIMD.1.f90 " + "%load ../sources/Example_SIMD.1.f90 " ] }, { @@ -67,7 +67,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_SIMD.2.c " + "%load ../sources/Example_SIMD.2.c " ] }, { @@ -76,7 +76,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_SIMD.2.f90 " + "%load ../sources/Example_SIMD.2.f90 " ] }, { @@ -92,7 +92,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_SIMD.3.c " + "%load ../sources/Example_SIMD.3.c " ] }, { @@ -101,7 +101,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_SIMD.3.f90 " + "%load ../sources/Example_SIMD.3.f90 " ] }, { @@ -117,7 +117,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_SIMD.4.c " + "%load ../sources/Example_SIMD.4.c " ] }, { @@ -126,7 +126,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_SIMD.4.f90 " + "%load ../sources/Example_SIMD.4.f90 " ] }, { @@ -142,7 +142,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_SIMD.5.c " + "%load ../sources/Example_SIMD.5.c " ] }, { @@ -151,7 +151,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_SIMD.5.f90 " + "%load ../sources/Example_SIMD.5.f90 " ] }, { @@ -177,7 +177,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_SIMD.6.c " + "%load ../sources/Example_SIMD.6.c " ] }, { @@ -186,7 +186,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_SIMD.6.f90 " + "%load ../sources/Example_SIMD.6.f90 " ] }, { @@ -202,7 +202,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_SIMD.7.c " + "%load ../sources/Example_SIMD.7.c " ] }, { @@ -211,7 +211,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_SIMD.7.f90 " + "%load ../sources/Example_SIMD.7.f90 " ] }, { @@ -251,7 +251,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_SIMD.8.c " + "%load ../sources/Example_SIMD.8.c " ] }, { @@ -260,7 +260,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_SIMD.8.f90 " + "%load ../sources/Example_SIMD.8.f90 " ] }, { @@ -270,19 +270,19 @@ "---end--- " ] } -], -"metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } -}, -"nbformat": 4, -"nbformat_minor": 2 + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/notebook/Examples_affinity.ipynb b/notebook/Examples_affinity.ipynb index 7f51393..9353da4 100644 --- a/notebook/Examples_affinity.ipynb +++ b/notebook/Examples_affinity.ipynb @@ -70,7 +70,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_affinity.1.c " + "%load ../sources/Example_affinity.1.c " ] }, { @@ -79,7 +79,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_affinity.1.f " + "%load ../sources/Example_affinity.1.f " ] }, { @@ -180,7 +180,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_affinity.2.c " + "%load ../sources/Example_affinity.2.c " ] }, { @@ -189,7 +189,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_affinity.2.f90 " + "%load ../sources/Example_affinity.2.f90 " ] }, { @@ -354,7 +354,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_affinity.3.c " + "%load ../sources/Example_affinity.3.c " ] }, { @@ -363,7 +363,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_affinity.3.f " + "%load ../sources/Example_affinity.3.f " ] }, { @@ -464,7 +464,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_affinity.4.c " + "%load ../sources/Example_affinity.4.c " ] }, { @@ -473,7 +473,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_affinity.4.f90 " + "%load ../sources/Example_affinity.4.f90 " ] }, { @@ -638,7 +638,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_affinity.5.c " + "%load ../sources/Example_affinity.5.c " ] }, { @@ -647,7 +647,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_affinity.5.f " + "%load ../sources/Example_affinity.5.f " ] }, { @@ -687,19 +687,19 @@ "---end--- " ] } -], -"metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } -}, -"nbformat": 4, -"nbformat_minor": 2 + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/notebook/Examples_affinity_query.ipynb b/notebook/Examples_affinity_query.ipynb index 1f27f7c..f93f00d 100644 --- a/notebook/Examples_affinity_query.ipynb +++ b/notebook/Examples_affinity_query.ipynb @@ -48,7 +48,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_affinity.6.c " + "%load ../sources/Example_affinity.6.c " ] }, { @@ -57,7 +57,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_affinity.6.f90 " + "%load ../sources/Example_affinity.6.f90 " ] }, { @@ -67,19 +67,19 @@ "---end--- " ] } -], -"metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } -}, -"nbformat": 4, -"nbformat_minor": 2 + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/notebook/Examples_array_sections.ipynb b/notebook/Examples_array_sections.ipynb index 0441780..032262a 100644 --- a/notebook/Examples_array_sections.ipynb +++ b/notebook/Examples_array_sections.ipynb @@ -27,7 +27,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_array_sections.1.c " + "%load ../sources/Example_array_sections.1.c " ] }, { @@ -36,7 +36,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_array_sections.1.f90 " + "%load ../sources/Example_array_sections.1.f90 " ] }, { @@ -52,7 +52,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_array_sections.2.c " + "%load ../sources/Example_array_sections.2.c " ] }, { @@ -61,7 +61,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_array_sections.2.f90 " + "%load ../sources/Example_array_sections.2.f90 " ] }, { @@ -77,7 +77,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_array_sections.3.c " + "%load ../sources/Example_array_sections.3.c " ] }, { @@ -86,7 +86,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_array_sections.3.f90 " + "%load ../sources/Example_array_sections.3.f90 " ] }, { @@ -102,7 +102,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_array_sections.4.c " + "%load ../sources/Example_array_sections.4.c " ] }, { @@ -111,7 +111,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_array_sections.4.f90 " + "%load ../sources/Example_array_sections.4.f90 " ] }, { @@ -121,19 +121,19 @@ "---end--- " ] } -], -"metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } -}, -"nbformat": 4, -"nbformat_minor": 2 + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/notebook/Examples_associate.ipynb b/notebook/Examples_associate.ipynb index 0eef380..276f4f1 100644 --- a/notebook/Examples_associate.ipynb +++ b/notebook/Examples_associate.ipynb @@ -27,7 +27,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_associate.1.f " + "%load ../sources/Example_associate.1.f " ] }, { @@ -43,7 +43,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_associate.2.f " + "%load ../sources/Example_associate.2.f " ] }, { @@ -59,7 +59,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_ffreenexampleassociate3 " + "%load ../sources/Example_ffreenexampleassociate3 " ] }, { @@ -76,19 +76,19 @@ "---end--- " ] } -], -"metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } -}, -"nbformat": 4, -"nbformat_minor": 2 + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/notebook/Examples_async_target_depend.ipynb b/notebook/Examples_async_target_depend.ipynb index 5366519..3e34389 100644 --- a/notebook/Examples_async_target_depend.ipynb +++ b/notebook/Examples_async_target_depend.ipynb @@ -35,19 +35,19 @@ "---end--- " ] } -], -"metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } -}, -"nbformat": 4, -"nbformat_minor": 2 + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/notebook/Examples_async_target_nowait.ipynb b/notebook/Examples_async_target_nowait.ipynb index 63f25e4..45974c6 100644 --- a/notebook/Examples_async_target_nowait.ipynb +++ b/notebook/Examples_async_target_nowait.ipynb @@ -41,7 +41,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_async_target.3.c " + "%load ../sources/Example_async_target.3.c " ] }, { @@ -50,7 +50,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_async_target.3.f90 " + "%load ../sources/Example_async_target.3.f90 " ] }, { @@ -60,19 +60,19 @@ "---end--- " ] } -], -"metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } -}, -"nbformat": 4, -"nbformat_minor": 2 + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/notebook/Examples_async_target_nowait_depend.ipynb b/notebook/Examples_async_target_nowait_depend.ipynb index 80f8cd5..aa85679 100644 --- a/notebook/Examples_async_target_nowait_depend.ipynb +++ b/notebook/Examples_async_target_nowait_depend.ipynb @@ -35,7 +35,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_async_target.4.c " + "%load ../sources/Example_async_target.4.c " ] }, { @@ -44,7 +44,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_async_target.4.f90 " + "%load ../sources/Example_async_target.4.f90 " ] }, { @@ -62,19 +62,19 @@ "---end--- " ] } -], -"metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } -}, -"nbformat": 4, -"nbformat_minor": 2 + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/notebook/Examples_async_target_with_tasks.ipynb b/notebook/Examples_async_target_with_tasks.ipynb index dd568a9..824bde1 100644 --- a/notebook/Examples_async_target_with_tasks.ipynb +++ b/notebook/Examples_async_target_with_tasks.ipynb @@ -20,7 +20,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_async_target.1.c " + "%load ../sources/Example_async_target.1.c " ] }, { @@ -36,7 +36,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_async_target.1.f90 " + "%load ../sources/Example_async_target.1.f90 " ] }, { @@ -52,7 +52,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_async_target.2.c " + "%load ../sources/Example_async_target.2.c " ] }, { @@ -96,7 +96,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_async_target.2.f90 " + "%load ../sources/Example_async_target.2.f90 " ] }, { @@ -106,19 +106,19 @@ "---end--- " ] } -], -"metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } -}, -"nbformat": 4, -"nbformat_minor": 2 + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/notebook/Examples_atomic.ipynb b/notebook/Examples_atomic.ipynb index 8899d92..1965683 100644 --- a/notebook/Examples_atomic.ipynb +++ b/notebook/Examples_atomic.ipynb @@ -34,7 +34,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_atomic.1.c " + "%load ../sources/Example_atomic.1.c " ] }, { @@ -43,7 +43,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_atomic.1.f " + "%load ../sources/Example_atomic.1.f " ] }, { @@ -59,7 +59,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_atomic.2.c " + "%load ../sources/Example_atomic.2.c " ] }, { @@ -68,7 +68,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_atomic.2.f " + "%load ../sources/Example_atomic.2.f " ] }, { @@ -84,7 +84,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_atomic.3.c " + "%load ../sources/Example_atomic.3.c " ] }, { @@ -93,7 +93,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_atomic.3.f " + "%load ../sources/Example_atomic.3.f " ] }, { @@ -103,19 +103,19 @@ "---end--- " ] } -], -"metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } -}, -"nbformat": 4, -"nbformat_minor": 2 + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/notebook/Examples_atomic_restrict.ipynb b/notebook/Examples_atomic_restrict.ipynb index b0b2323..3433d4a 100644 --- a/notebook/Examples_atomic_restrict.ipynb +++ b/notebook/Examples_atomic_restrict.ipynb @@ -20,7 +20,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_atomic_restrict.1.c " + "%load ../sources/Example_atomic_restrict.1.c " ] }, { @@ -29,7 +29,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_atomic_restrict.1.f " + "%load ../sources/Example_atomic_restrict.1.f " ] }, { @@ -38,7 +38,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_atomic_restrict.2.c " + "%load ../sources/Example_atomic_restrict.2.c " ] }, { @@ -54,7 +54,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_atomic_restrict.2.f " + "%load ../sources/Example_atomic_restrict.2.f " ] }, { @@ -70,7 +70,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_atomic_restrict.3.f " + "%load ../sources/Example_atomic_restrict.3.f " ] }, { @@ -87,19 +87,19 @@ "---end--- " ] } -], -"metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } -}, -"nbformat": 4, -"nbformat_minor": 2 + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/notebook/Examples_barrier_regions.ipynb b/notebook/Examples_barrier_regions.ipynb index 53441bc..fd71495 100644 --- a/notebook/Examples_barrier_regions.ipynb +++ b/notebook/Examples_barrier_regions.ipynb @@ -34,7 +34,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_barrier_regions.1.c " + "%load ../sources/Example_barrier_regions.1.c " ] }, { @@ -43,7 +43,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_barrier_regions.1.f " + "%load ../sources/Example_barrier_regions.1.f " ] }, { @@ -53,19 +53,19 @@ "---end--- " ] } -], -"metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } -}, -"nbformat": 4, -"nbformat_minor": 2 + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/notebook/Examples_cancellation.ipynb b/notebook/Examples_cancellation.ipynb index 1488b55..d15353b 100644 --- a/notebook/Examples_cancellation.ipynb +++ b/notebook/Examples_cancellation.ipynb @@ -20,7 +20,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_cancellation.1.cpp " + "%load ../sources/Example_cancellation.1.cpp " ] }, { @@ -36,7 +36,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_cancellation.1.f90 " + "%load ../sources/Example_cancellation.1.f90 " ] }, { @@ -52,7 +52,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_cancellation.2.c " + "%load ../sources/Example_cancellation.2.c " ] }, { @@ -68,7 +68,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_cancellation.2.f90 " + "%load ../sources/Example_cancellation.2.f90 " ] }, { @@ -78,19 +78,19 @@ "---end--- " ] } -], -"metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } -}, -"nbformat": 4, -"nbformat_minor": 2 + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/notebook/Examples_carrays_fpriv.ipynb b/notebook/Examples_carrays_fpriv.ipynb index d4835fb..1e1c079 100644 --- a/notebook/Examples_carrays_fpriv.ipynb +++ b/notebook/Examples_carrays_fpriv.ipynb @@ -89,7 +89,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_carrays_fpriv.1.c " + "%load ../sources/Example_carrays_fpriv.1.c " ] }, { @@ -106,19 +106,19 @@ "---end--- " ] } -], -"metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } -}, -"nbformat": 4, -"nbformat_minor": 2 + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/notebook/Examples_collapse.ipynb b/notebook/Examples_collapse.ipynb index d119dc4..54a8931 100644 --- a/notebook/Examples_collapse.ipynb +++ b/notebook/Examples_collapse.ipynb @@ -27,7 +27,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_collapse.1.c " + "%load ../sources/Example_collapse.1.c " ] }, { @@ -36,7 +36,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_collapse.1.f " + "%load ../sources/Example_collapse.1.f " ] }, { @@ -59,7 +59,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_collapse.2.c " + "%load ../sources/Example_collapse.2.c " ] }, { @@ -68,7 +68,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_collapse.2.f " + "%load ../sources/Example_collapse.2.f " ] }, { @@ -112,7 +112,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_collapse.3.c " + "%load ../sources/Example_collapse.3.c " ] }, { @@ -121,7 +121,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_collapse.3.f " + "%load ../sources/Example_collapse.3.f " ] }, { @@ -131,19 +131,19 @@ "---end--- " ] } -], -"metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } -}, -"nbformat": 4, -"nbformat_minor": 2 + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/notebook/Examples_cond_comp.ipynb b/notebook/Examples_cond_comp.ipynb index fcd809b..1b7479c 100644 --- a/notebook/Examples_cond_comp.ipynb +++ b/notebook/Examples_cond_comp.ipynb @@ -20,7 +20,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_cond_comp.1.c " + "%load ../sources/Example_cond_comp.1.c " ] }, { @@ -43,7 +43,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_cond_comp.1.f " + "%load ../sources/Example_cond_comp.1.f " ] }, { @@ -60,19 +60,19 @@ "---end--- " ] } -], -"metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } -}, -"nbformat": 4, -"nbformat_minor": 2 + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/notebook/Examples_copyin.ipynb b/notebook/Examples_copyin.ipynb index c7c13e0..f975163 100644 --- a/notebook/Examples_copyin.ipynb +++ b/notebook/Examples_copyin.ipynb @@ -20,7 +20,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_copyin.1.c " + "%load ../sources/Example_copyin.1.c " ] }, { @@ -29,7 +29,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_copyin.1.f " + "%load ../sources/Example_copyin.1.f " ] }, { @@ -39,19 +39,19 @@ "---end--- " ] } -], -"metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } -}, -"nbformat": 4, -"nbformat_minor": 2 + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/notebook/Examples_copyprivate.ipynb b/notebook/Examples_copyprivate.ipynb index 23479c0..0b16465 100644 --- a/notebook/Examples_copyprivate.ipynb +++ b/notebook/Examples_copyprivate.ipynb @@ -27,7 +27,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_copyprivate.1.c " + "%load ../sources/Example_copyprivate.1.c " ] }, { @@ -36,7 +36,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_copyprivate.1.f " + "%load ../sources/Example_copyprivate.1.f " ] }, { @@ -52,7 +52,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_copyprivate.2.c " + "%load ../sources/Example_copyprivate.2.c " ] }, { @@ -61,7 +61,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_copyprivate.2.f " + "%load ../sources/Example_copyprivate.2.f " ] }, { @@ -77,7 +77,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_copyprivate.3.c " + "%load ../sources/Example_copyprivate.3.c " ] }, { @@ -100,7 +100,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_copyprivate.4.f " + "%load ../sources/Example_copyprivate.4.f " ] }, { @@ -117,19 +117,19 @@ "---end--- " ] } -], -"metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } -}, -"nbformat": 4, -"nbformat_minor": 2 + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/notebook/Examples_cpp_reference.ipynb b/notebook/Examples_cpp_reference.ipynb index 9ceeb4a..244460d 100644 --- a/notebook/Examples_cpp_reference.ipynb +++ b/notebook/Examples_cpp_reference.ipynb @@ -13,7 +13,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_cppspecificstart " + "%load ../sources/Example_cppspecificstart " ] }, { @@ -29,7 +29,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_cppnexamplecpp_reference1 " + "%load ../sources/Example_cppnexamplecpp_reference1 " ] }, { @@ -38,7 +38,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_cppspecificend " + "%load ../sources/Example_cppspecificend " ] }, { @@ -48,19 +48,19 @@ "---end--- " ] } -], -"metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } -}, -"nbformat": 4, -"nbformat_minor": 2 + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/notebook/Examples_critical.ipynb b/notebook/Examples_critical.ipynb index e4774cf..73871ee 100644 --- a/notebook/Examples_critical.ipynb +++ b/notebook/Examples_critical.ipynb @@ -20,7 +20,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_critical.1.c " + "%load ../sources/Example_critical.1.c " ] }, { @@ -29,7 +29,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_critical.1.f " + "%load ../sources/Example_critical.1.f " ] }, { @@ -45,7 +45,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_critical.2.c " + "%load ../sources/Example_critical.2.c " ] }, { @@ -54,7 +54,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_critical.2.f " + "%load ../sources/Example_critical.2.f " ] }, { @@ -64,19 +64,19 @@ "---end--- " ] } -], -"metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } -}, -"nbformat": 4, -"nbformat_minor": 2 + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/notebook/Examples_declare_target.ipynb b/notebook/Examples_declare_target.ipynb index ac21458..e68bf30 100644 --- a/notebook/Examples_declare_target.ipynb +++ b/notebook/Examples_declare_target.ipynb @@ -41,7 +41,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_declare_target.1.c " + "%load ../sources/Example_declare_target.1.c " ] }, { @@ -64,7 +64,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_declare_target.1.f90 " + "%load ../sources/Example_declare_target.1.f90 " ] }, { @@ -80,7 +80,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_declare_target.2.f90 " + "%load ../sources/Example_declare_target.2.f90 " ] }, { @@ -96,7 +96,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_cppspecificstart " + "%load ../sources/Example_cppspecificstart " ] }, { @@ -112,7 +112,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_cppnexampledeclare_target2 " + "%load ../sources/Example_cppnexampledeclare_target2 " ] }, { @@ -121,7 +121,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_cppspecificend " + "%load ../sources/Example_cppspecificend " ] }, { @@ -151,7 +151,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_declare_target.3.c " + "%load ../sources/Example_declare_target.3.c " ] }, { @@ -167,7 +167,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_declare_target.3.f90 " + "%load ../sources/Example_declare_target.3.f90 " ] }, { @@ -190,7 +190,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_declare_target.4.c " + "%load ../sources/Example_declare_target.4.c " ] }, { @@ -206,7 +206,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_declare_target.4.f90 " + "%load ../sources/Example_declare_target.4.f90 " ] }, { @@ -229,7 +229,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_declare_target.5.c " + "%load ../sources/Example_declare_target.5.c " ] }, { @@ -245,7 +245,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_declare_target.5.f90 " + "%load ../sources/Example_declare_target.5.f90 " ] }, { @@ -289,7 +289,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_declare_target.6.c " + "%load ../sources/Example_declare_target.6.c " ] }, { @@ -298,7 +298,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_declare_target.6.f90 " + "%load ../sources/Example_declare_target.6.f90 " ] }, { @@ -308,19 +308,19 @@ "---end--- " ] } -], -"metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } -}, -"nbformat": 4, -"nbformat_minor": 2 + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/notebook/Examples_default_none.ipynb b/notebook/Examples_default_none.ipynb index 50044f0..e231f3d 100644 --- a/notebook/Examples_default_none.ipynb +++ b/notebook/Examples_default_none.ipynb @@ -27,7 +27,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_default_none.1.c " + "%load ../sources/Example_default_none.1.c " ] }, { @@ -43,7 +43,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_default_none.1.f " + "%load ../sources/Example_default_none.1.f " ] }, { @@ -53,19 +53,19 @@ "---end--- " ] } -], -"metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } -}, -"nbformat": 4, -"nbformat_minor": 2 + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/notebook/Examples_device.ipynb b/notebook/Examples_device.ipynb index cb48d50..9d0341f 100644 --- a/notebook/Examples_device.ipynb +++ b/notebook/Examples_device.ipynb @@ -27,7 +27,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_device.1.c " + "%load ../sources/Example_device.1.c " ] }, { @@ -36,7 +36,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_device.1.f90 " + "%load ../sources/Example_device.1.f90 " ] }, { @@ -59,7 +59,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_device.2.c " + "%load ../sources/Example_device.2.c " ] }, { @@ -68,7 +68,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_device.2.f90 " + "%load ../sources/Example_device.2.f90 " ] }, { @@ -98,7 +98,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_device.3.c " + "%load ../sources/Example_device.3.c " ] }, { @@ -107,7 +107,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_device.3.f90 " + "%load ../sources/Example_device.3.f90 " ] }, { @@ -144,7 +144,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_device.4.c " + "%load ../sources/Example_device.4.c " ] }, { @@ -154,19 +154,19 @@ "---end--- " ] } -], -"metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } -}, -"nbformat": 4, -"nbformat_minor": 2 + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/notebook/Examples_doacross.ipynb b/notebook/Examples_doacross.ipynb index aeff986..3f97240 100644 --- a/notebook/Examples_doacross.ipynb +++ b/notebook/Examples_doacross.ipynb @@ -27,7 +27,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_doacross.1.c " + "%load ../sources/Example_doacross.1.c " ] }, { @@ -36,7 +36,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_doacross.1.f90 " + "%load ../sources/Example_doacross.1.f90 " ] }, { @@ -52,7 +52,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_doacross.2.c " + "%load ../sources/Example_doacross.2.c " ] }, { @@ -61,7 +61,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_doacross.2.f90 " + "%load ../sources/Example_doacross.2.f90 " ] }, { @@ -77,7 +77,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_doacross.3.c " + "%load ../sources/Example_doacross.3.c " ] }, { @@ -86,7 +86,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_doacross.3.f90 " + "%load ../sources/Example_doacross.3.f90 " ] }, { @@ -102,7 +102,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_doacross.4.c " + "%load ../sources/Example_doacross.4.c " ] }, { @@ -111,7 +111,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_doacross.4.f90 " + "%load ../sources/Example_doacross.4.f90 " ] }, { @@ -121,19 +121,19 @@ "---end--- " ] } -], -"metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } -}, -"nbformat": 4, -"nbformat_minor": 2 + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/notebook/Examples_flush_nolist.ipynb b/notebook/Examples_flush_nolist.ipynb index 20af185..7ea5d65 100644 --- a/notebook/Examples_flush_nolist.ipynb +++ b/notebook/Examples_flush_nolist.ipynb @@ -20,7 +20,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_flush_nolist.1.c " + "%load ../sources/Example_flush_nolist.1.c " ] }, { @@ -29,7 +29,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_flush_nolist.1.f " + "%load ../sources/Example_flush_nolist.1.f " ] }, { @@ -39,19 +39,19 @@ "---end--- " ] } -], -"metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } -}, -"nbformat": 4, -"nbformat_minor": 2 + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/notebook/Examples_fort_do.ipynb b/notebook/Examples_fort_do.ipynb index a69af2b..3d2e603 100644 --- a/notebook/Examples_fort_do.ipynb +++ b/notebook/Examples_fort_do.ipynb @@ -27,7 +27,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_fort_do.1.f " + "%load ../sources/Example_fort_do.1.f " ] }, { @@ -43,7 +43,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_fort_do.2.f " + "%load ../sources/Example_fort_do.2.f " ] }, { @@ -60,19 +60,19 @@ "---end--- " ] } -], -"metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } -}, -"nbformat": 4, -"nbformat_minor": 2 + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/notebook/Examples_fort_loopvar.ipynb b/notebook/Examples_fort_loopvar.ipynb index 90b4061..29fbf9c 100644 --- a/notebook/Examples_fort_loopvar.ipynb +++ b/notebook/Examples_fort_loopvar.ipynb @@ -27,7 +27,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_ffreenexamplefort_loopvar1 " + "%load ../sources/Example_ffreenexamplefort_loopvar1 " ] }, { @@ -43,7 +43,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_ffreenexamplefort_loopvar2 " + "%load ../sources/Example_ffreenexamplefort_loopvar2 " ] }, { @@ -60,19 +60,19 @@ "---end--- " ] } -], -"metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } -}, -"nbformat": 4, -"nbformat_minor": 2 + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/notebook/Examples_fort_race.ipynb b/notebook/Examples_fort_race.ipynb index a38e763..fe60c43 100644 --- a/notebook/Examples_fort_race.ipynb +++ b/notebook/Examples_fort_race.ipynb @@ -27,7 +27,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_ffreenexamplefort_race1 " + "%load ../sources/Example_ffreenexamplefort_race1 " ] }, { @@ -44,19 +44,19 @@ "---end--- " ] } -], -"metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } -}, -"nbformat": 4, -"nbformat_minor": 2 + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/notebook/Examples_fort_sa_private.ipynb b/notebook/Examples_fort_sa_private.ipynb index 7c7955b..de0583b 100644 --- a/notebook/Examples_fort_sa_private.ipynb +++ b/notebook/Examples_fort_sa_private.ipynb @@ -27,7 +27,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_fort_sa_private.1.f " + "%load ../sources/Example_fort_sa_private.1.f " ] }, { @@ -36,7 +36,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_fort_sa_private.2.f " + "%load ../sources/Example_fort_sa_private.2.f " ] }, { @@ -45,7 +45,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_fort_sa_private.3.f " + "%load ../sources/Example_fort_sa_private.3.f " ] }, { @@ -62,7 +62,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_fort_sa_private.4.f " + "%load ../sources/Example_fort_sa_private.4.f " ] }, { @@ -71,7 +71,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_fort_sa_private.5.f " + "%load ../sources/Example_fort_sa_private.5.f " ] }, { @@ -88,19 +88,19 @@ "---end--- " ] } -], -"metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } -}, -"nbformat": 4, -"nbformat_minor": 2 + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/notebook/Examples_fort_sp_common.ipynb b/notebook/Examples_fort_sp_common.ipynb index 800445f..ec9a9a4 100644 --- a/notebook/Examples_fort_sp_common.ipynb +++ b/notebook/Examples_fort_sp_common.ipynb @@ -34,7 +34,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_fort_sp_common.1.f " + "%load ../sources/Example_fort_sp_common.1.f " ] }, { @@ -50,7 +50,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_fort_sp_common.2.f " + "%load ../sources/Example_fort_sp_common.2.f " ] }, { @@ -74,7 +74,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_fort_sp_common.3.f " + "%load ../sources/Example_fort_sp_common.3.f " ] }, { @@ -90,7 +90,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_fort_sp_common.4.f " + "%load ../sources/Example_fort_sp_common.4.f " ] }, { @@ -106,7 +106,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_fort_sp_common.5.f " + "%load ../sources/Example_fort_sp_common.5.f " ] }, { @@ -123,19 +123,19 @@ "---end--- " ] } -], -"metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } -}, -"nbformat": 4, -"nbformat_minor": 2 + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/notebook/Examples_fpriv_sections.ipynb b/notebook/Examples_fpriv_sections.ipynb index 3654615..df5eed6 100644 --- a/notebook/Examples_fpriv_sections.ipynb +++ b/notebook/Examples_fpriv_sections.ipynb @@ -20,7 +20,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_fpriv_sections.1.c " + "%load ../sources/Example_fpriv_sections.1.c " ] }, { @@ -29,7 +29,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_fpriv_sections.1.f90 " + "%load ../sources/Example_fpriv_sections.1.f90 " ] }, { @@ -39,19 +39,19 @@ "---end--- " ] } -], -"metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } -}, -"nbformat": 4, -"nbformat_minor": 2 + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/notebook/Examples_get_nthrs.ipynb b/notebook/Examples_get_nthrs.ipynb index 656169b..5aa7991 100644 --- a/notebook/Examples_get_nthrs.ipynb +++ b/notebook/Examples_get_nthrs.ipynb @@ -20,7 +20,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_get_nthrs.1.c " + "%load ../sources/Example_get_nthrs.1.c " ] }, { @@ -29,7 +29,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_get_nthrs.1.f " + "%load ../sources/Example_get_nthrs.1.f " ] }, { @@ -45,7 +45,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_get_nthrs.2.c " + "%load ../sources/Example_get_nthrs.2.c " ] }, { @@ -54,7 +54,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_get_nthrs.2.f " + "%load ../sources/Example_get_nthrs.2.f " ] }, { @@ -64,19 +64,19 @@ "---end--- " ] } -], -"metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } -}, -"nbformat": 4, -"nbformat_minor": 2 + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/notebook/Examples_icv.ipynb b/notebook/Examples_icv.ipynb index b2fb417..64611d5 100644 --- a/notebook/Examples_icv.ipynb +++ b/notebook/Examples_icv.ipynb @@ -76,7 +76,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_icv.1.c " + "%load ../sources/Example_icv.1.c " ] }, { @@ -85,7 +85,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_icv.1.f " + "%load ../sources/Example_icv.1.f " ] }, { @@ -95,19 +95,19 @@ "---end--- " ] } -], -"metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } -}, -"nbformat": 4, -"nbformat_minor": 2 + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/notebook/Examples_init_lock.ipynb b/notebook/Examples_init_lock.ipynb index 2a57c07..4f87cbb 100644 --- a/notebook/Examples_init_lock.ipynb +++ b/notebook/Examples_init_lock.ipynb @@ -20,7 +20,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_init_lock.1.cpp " + "%load ../sources/Example_init_lock.1.cpp " ] }, { @@ -29,7 +29,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_init_lock.1.f " + "%load ../sources/Example_init_lock.1.f " ] }, { @@ -39,19 +39,19 @@ "---end--- " ] } -], -"metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } -}, -"nbformat": 4, -"nbformat_minor": 2 + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/notebook/Examples_init_lock_with_hint.ipynb b/notebook/Examples_init_lock_with_hint.ipynb index 64614f0..5326a89 100644 --- a/notebook/Examples_init_lock_with_hint.ipynb +++ b/notebook/Examples_init_lock_with_hint.ipynb @@ -21,7 +21,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_init_lock_with_hint.1.cpp " + "%load ../sources/Example_init_lock_with_hint.1.cpp " ] }, { @@ -30,7 +30,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_init_lock_with_hint.1.f " + "%load ../sources/Example_init_lock_with_hint.1.f " ] }, { @@ -40,19 +40,19 @@ "---end--- " ] } -], -"metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } -}, -"nbformat": 4, -"nbformat_minor": 2 + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/notebook/Examples_lastprivate.ipynb b/notebook/Examples_lastprivate.ipynb index 4910ae0..bf7e62f 100644 --- a/notebook/Examples_lastprivate.ipynb +++ b/notebook/Examples_lastprivate.ipynb @@ -20,7 +20,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_lastprivate.1.c " + "%load ../sources/Example_lastprivate.1.c " ] }, { @@ -29,7 +29,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_lastprivate.1.f " + "%load ../sources/Example_lastprivate.1.f " ] }, { @@ -39,19 +39,19 @@ "---end--- " ] } -], -"metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } -}, -"nbformat": 4, -"nbformat_minor": 2 + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/notebook/Examples_linear_in_loop.ipynb b/notebook/Examples_linear_in_loop.ipynb index 2f28ef9..f838186 100644 --- a/notebook/Examples_linear_in_loop.ipynb +++ b/notebook/Examples_linear_in_loop.ipynb @@ -20,7 +20,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_linear_in_loop.1.c " + "%load ../sources/Example_linear_in_loop.1.c " ] }, { @@ -29,7 +29,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_linear_in_loop.1.f90 " + "%load ../sources/Example_linear_in_loop.1.f90 " ] }, { @@ -39,19 +39,19 @@ "---end--- " ] } -], -"metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } -}, -"nbformat": 4, -"nbformat_minor": 2 + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/notebook/Examples_lock_owner.ipynb b/notebook/Examples_lock_owner.ipynb index 4f00112..e18505a 100644 --- a/notebook/Examples_lock_owner.ipynb +++ b/notebook/Examples_lock_owner.ipynb @@ -27,7 +27,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_lock_owner.1.c " + "%load ../sources/Example_lock_owner.1.c " ] }, { @@ -36,7 +36,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_lock_owner.1.f " + "%load ../sources/Example_lock_owner.1.f " ] }, { @@ -46,19 +46,19 @@ "---end--- " ] } -], -"metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } -}, -"nbformat": 4, -"nbformat_minor": 2 + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/notebook/Examples_locks.ipynb b/notebook/Examples_locks.ipynb index bab60c3..c8cab0a 100644 --- a/notebook/Examples_locks.ipynb +++ b/notebook/Examples_locks.ipynb @@ -21,19 +21,19 @@ "---end--- " ] } -], -"metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } -}, -"nbformat": 4, -"nbformat_minor": 2 + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/notebook/Examples_master.ipynb b/notebook/Examples_master.ipynb index 7780658..71c2112 100644 --- a/notebook/Examples_master.ipynb +++ b/notebook/Examples_master.ipynb @@ -20,7 +20,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_master.1.c " + "%load ../sources/Example_master.1.c " ] }, { @@ -29,7 +29,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_master.1.f " + "%load ../sources/Example_master.1.f " ] }, { @@ -39,19 +39,19 @@ "---end--- " ] } -], -"metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } -}, -"nbformat": 4, -"nbformat_minor": 2 + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/notebook/Examples_mem_model.ipynb b/notebook/Examples_mem_model.ipynb index 8cc65cb..0050170 100644 --- a/notebook/Examples_mem_model.ipynb +++ b/notebook/Examples_mem_model.ipynb @@ -27,7 +27,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_mem_model.1.c " + "%load ../sources/Example_mem_model.1.c " ] }, { @@ -36,7 +36,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_mem_model.1.f90 " + "%load ../sources/Example_mem_model.1.f90 " ] }, { @@ -52,7 +52,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_mem_model.2.c " + "%load ../sources/Example_mem_model.2.c " ] }, { @@ -61,7 +61,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_mem_model.2.f " + "%load ../sources/Example_mem_model.2.f " ] }, { @@ -77,7 +77,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_mem_model.3.c " + "%load ../sources/Example_mem_model.3.c " ] }, { @@ -86,7 +86,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_mem_model.3.f " + "%load ../sources/Example_mem_model.3.f " ] }, { @@ -96,19 +96,19 @@ "---end--- " ] } -], -"metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } -}, -"nbformat": 4, -"nbformat_minor": 2 + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/notebook/Examples_nestable_lock.ipynb b/notebook/Examples_nestable_lock.ipynb index b5c24da..68b19be 100644 --- a/notebook/Examples_nestable_lock.ipynb +++ b/notebook/Examples_nestable_lock.ipynb @@ -20,7 +20,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_nestable_lock.1.c " + "%load ../sources/Example_nestable_lock.1.c " ] }, { @@ -29,7 +29,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_nestable_lock.1.f " + "%load ../sources/Example_nestable_lock.1.f " ] }, { @@ -39,19 +39,19 @@ "---end--- " ] } -], -"metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } -}, -"nbformat": 4, -"nbformat_minor": 2 + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/notebook/Examples_nested_loop.ipynb b/notebook/Examples_nested_loop.ipynb index 0fdfd34..82e9c05 100644 --- a/notebook/Examples_nested_loop.ipynb +++ b/notebook/Examples_nested_loop.ipynb @@ -20,7 +20,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_nested_loop.1.c " + "%load ../sources/Example_nested_loop.1.c " ] }, { @@ -29,7 +29,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_nested_loop.1.f " + "%load ../sources/Example_nested_loop.1.f " ] }, { @@ -45,7 +45,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_nested_loop.2.c " + "%load ../sources/Example_nested_loop.2.c " ] }, { @@ -54,7 +54,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_nested_loop.2.f " + "%load ../sources/Example_nested_loop.2.f " ] }, { @@ -64,19 +64,19 @@ "---end--- " ] } -], -"metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } -}, -"nbformat": 4, -"nbformat_minor": 2 + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/notebook/Examples_nesting_restrict.ipynb b/notebook/Examples_nesting_restrict.ipynb index 6412b6b..7666764 100644 --- a/notebook/Examples_nesting_restrict.ipynb +++ b/notebook/Examples_nesting_restrict.ipynb @@ -27,7 +27,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_nesting_restrict.1.c " + "%load ../sources/Example_nesting_restrict.1.c " ] }, { @@ -36,7 +36,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_nesting_restrict.1.f " + "%load ../sources/Example_nesting_restrict.1.f " ] }, { @@ -52,7 +52,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_nesting_restrict.2.c " + "%load ../sources/Example_nesting_restrict.2.c " ] }, { @@ -61,7 +61,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_nesting_restrict.2.f " + "%load ../sources/Example_nesting_restrict.2.f " ] }, { @@ -77,7 +77,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_nesting_restrict.3.c " + "%load ../sources/Example_nesting_restrict.3.c " ] }, { @@ -86,7 +86,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_nesting_restrict.3.f " + "%load ../sources/Example_nesting_restrict.3.f " ] }, { @@ -102,7 +102,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_nesting_restrict.4.c " + "%load ../sources/Example_nesting_restrict.4.c " ] }, { @@ -111,7 +111,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_nesting_restrict.4.f " + "%load ../sources/Example_nesting_restrict.4.f " ] }, { @@ -127,7 +127,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_nesting_restrict.5.c " + "%load ../sources/Example_nesting_restrict.5.c " ] }, { @@ -136,7 +136,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_nesting_restrict.5.f " + "%load ../sources/Example_nesting_restrict.5.f " ] }, { @@ -152,7 +152,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_nesting_restrict.6.c " + "%load ../sources/Example_nesting_restrict.6.c " ] }, { @@ -161,7 +161,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_nesting_restrict.6.f " + "%load ../sources/Example_nesting_restrict.6.f " ] }, { @@ -171,19 +171,19 @@ "---end--- " ] } -], -"metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } -}, -"nbformat": 4, -"nbformat_minor": 2 + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/notebook/Examples_nowait.ipynb b/notebook/Examples_nowait.ipynb index 0e38089..1347094 100644 --- a/notebook/Examples_nowait.ipynb +++ b/notebook/Examples_nowait.ipynb @@ -20,7 +20,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_nowait.1.c " + "%load ../sources/Example_nowait.1.c " ] }, { @@ -29,7 +29,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_nowait.1.f " + "%load ../sources/Example_nowait.1.f " ] }, { @@ -52,7 +52,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_nowait.2.c " + "%load ../sources/Example_nowait.2.c " ] }, { @@ -61,7 +61,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_nowait.2.f90 " + "%load ../sources/Example_nowait.2.f90 " ] }, { @@ -71,19 +71,19 @@ "---end--- " ] } -], -"metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } -}, -"nbformat": 4, -"nbformat_minor": 2 + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/notebook/Examples_nthrs_dynamic.ipynb b/notebook/Examples_nthrs_dynamic.ipynb index bb4bf33..a1541ff 100644 --- a/notebook/Examples_nthrs_dynamic.ipynb +++ b/notebook/Examples_nthrs_dynamic.ipynb @@ -27,7 +27,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_nthrs_dynamic.1.c " + "%load ../sources/Example_nthrs_dynamic.1.c " ] }, { @@ -36,7 +36,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_nthrs_dynamic.1.f " + "%load ../sources/Example_nthrs_dynamic.1.f " ] }, { @@ -52,7 +52,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_nthrs_dynamic.2.c " + "%load ../sources/Example_nthrs_dynamic.2.c " ] }, { @@ -61,7 +61,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_nthrs_dynamic.2.f " + "%load ../sources/Example_nthrs_dynamic.2.f " ] }, { @@ -78,19 +78,19 @@ "---end--- " ] } -], -"metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } -}, -"nbformat": 4, -"nbformat_minor": 2 + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/notebook/Examples_nthrs_nesting.ipynb b/notebook/Examples_nthrs_nesting.ipynb index b00b02a..ce4a796 100644 --- a/notebook/Examples_nthrs_nesting.ipynb +++ b/notebook/Examples_nthrs_nesting.ipynb @@ -20,7 +20,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_nthrs_nesting.1.c " + "%load ../sources/Example_nthrs_nesting.1.c " ] }, { @@ -29,7 +29,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_nthrs_nesting.1.f " + "%load ../sources/Example_nthrs_nesting.1.f " ] }, { @@ -39,19 +39,19 @@ "---end--- " ] } -], -"metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } -}, -"nbformat": 4, -"nbformat_minor": 2 + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/notebook/Examples_ordered.ipynb b/notebook/Examples_ordered.ipynb index 6738cb5..972fa00 100644 --- a/notebook/Examples_ordered.ipynb +++ b/notebook/Examples_ordered.ipynb @@ -20,7 +20,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_ordered.1.c " + "%load ../sources/Example_ordered.1.c " ] }, { @@ -29,7 +29,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_ordered.1.f " + "%load ../sources/Example_ordered.1.f " ] }, { @@ -45,7 +45,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_ordered.2.c " + "%load ../sources/Example_ordered.2.c " ] }, { @@ -54,7 +54,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_ordered.2.f " + "%load ../sources/Example_ordered.2.f " ] }, { @@ -70,7 +70,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_ordered.3.c " + "%load ../sources/Example_ordered.3.c " ] }, { @@ -79,7 +79,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_ordered.3.f " + "%load ../sources/Example_ordered.3.f " ] }, { @@ -89,19 +89,19 @@ "---end--- " ] } -], -"metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } -}, -"nbformat": 4, -"nbformat_minor": 2 + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/notebook/Examples_parallel.ipynb b/notebook/Examples_parallel.ipynb index 235b638..47a5c3b 100644 --- a/notebook/Examples_parallel.ipynb +++ b/notebook/Examples_parallel.ipynb @@ -20,7 +20,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_parallel.1.c " + "%load ../sources/Example_parallel.1.c " ] }, { @@ -29,7 +29,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_parallel.1.f " + "%load ../sources/Example_parallel.1.f " ] }, { @@ -39,19 +39,19 @@ "---end--- " ] } -], -"metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } -}, -"nbformat": 4, -"nbformat_minor": 2 + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/notebook/Examples_ploop.ipynb b/notebook/Examples_ploop.ipynb index b928c52..b21ade4 100644 --- a/notebook/Examples_ploop.ipynb +++ b/notebook/Examples_ploop.ipynb @@ -20,7 +20,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_ploop.1.c " + "%load ../sources/Example_ploop.1.c " ] }, { @@ -29,7 +29,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_ploop.1.f " + "%load ../sources/Example_ploop.1.f " ] }, { @@ -39,19 +39,19 @@ "---end--- " ] } -], -"metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } -}, -"nbformat": 4, -"nbformat_minor": 2 + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/notebook/Examples_pra_iterator.ipynb b/notebook/Examples_pra_iterator.ipynb index 90c8c12..29c9a62 100644 --- a/notebook/Examples_pra_iterator.ipynb +++ b/notebook/Examples_pra_iterator.ipynb @@ -13,7 +13,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_cppspecificstart " + "%load ../sources/Example_cppspecificstart " ] }, { @@ -29,7 +29,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_cppnexamplepra_iterator1 " + "%load ../sources/Example_cppnexamplepra_iterator1 " ] }, { @@ -38,7 +38,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_cppspecificend " + "%load ../sources/Example_cppspecificend " ] }, { @@ -48,19 +48,19 @@ "---end--- " ] } -], -"metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } -}, -"nbformat": 4, -"nbformat_minor": 2 + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/notebook/Examples_private.ipynb b/notebook/Examples_private.ipynb index 9f768ea..3b1fe5e 100644 --- a/notebook/Examples_private.ipynb +++ b/notebook/Examples_private.ipynb @@ -20,7 +20,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_private.1.c " + "%load ../sources/Example_private.1.c " ] }, { @@ -29,7 +29,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_private.1.f " + "%load ../sources/Example_private.1.f " ] }, { @@ -47,7 +47,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_private.2.c " + "%load ../sources/Example_private.2.c " ] }, { @@ -56,7 +56,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_private.2.f " + "%load ../sources/Example_private.2.f " ] }, { @@ -73,7 +73,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_private.3.c " + "%load ../sources/Example_private.3.c " ] }, { @@ -82,7 +82,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_private.3.f " + "%load ../sources/Example_private.3.f " ] }, { @@ -92,19 +92,19 @@ "---end--- " ] } -], -"metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } -}, -"nbformat": 4, -"nbformat_minor": 2 + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/notebook/Examples_psections.ipynb b/notebook/Examples_psections.ipynb index fd288c6..0a689f1 100644 --- a/notebook/Examples_psections.ipynb +++ b/notebook/Examples_psections.ipynb @@ -20,7 +20,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_psections.1.c " + "%load ../sources/Example_psections.1.c " ] }, { @@ -29,7 +29,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_psections.1.f " + "%load ../sources/Example_psections.1.f " ] }, { @@ -39,19 +39,19 @@ "---end--- " ] } -], -"metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } -}, -"nbformat": 4, -"nbformat_minor": 2 + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/notebook/Examples_reduction.ipynb b/notebook/Examples_reduction.ipynb index 656bbac..1007d2d 100644 --- a/notebook/Examples_reduction.ipynb +++ b/notebook/Examples_reduction.ipynb @@ -20,7 +20,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_reduction.1.c " + "%load ../sources/Example_reduction.1.c " ] }, { @@ -29,7 +29,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_reduction.1.f90 " + "%load ../sources/Example_reduction.1.f90 " ] }, { @@ -45,7 +45,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_reduction.2.c " + "%load ../sources/Example_reduction.2.c " ] }, { @@ -68,7 +68,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_ffreenexamplereduction3 " + "%load ../sources/Example_ffreenexamplereduction3 " ] }, { @@ -92,7 +92,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_ffreenexamplereduction4 " + "%load ../sources/Example_ffreenexamplereduction4 " ] }, { @@ -108,7 +108,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_ffreenexamplereduction5 " + "%load ../sources/Example_ffreenexamplereduction5 " ] }, { @@ -140,7 +140,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_reduction.6.c " + "%load ../sources/Example_reduction.6.c " ] }, { @@ -149,7 +149,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_reduction.6.f " + "%load ../sources/Example_reduction.6.f " ] }, { @@ -165,7 +165,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_reduction.7.c " + "%load ../sources/Example_reduction.7.c " ] }, { @@ -174,7 +174,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_reduction.7.f90 " + "%load ../sources/Example_reduction.7.f90 " ] }, { @@ -184,19 +184,19 @@ "---end--- " ] } -], -"metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } -}, -"nbformat": 4, -"nbformat_minor": 2 + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/notebook/Examples_set_dynamic_nthrs.ipynb b/notebook/Examples_set_dynamic_nthrs.ipynb index d5e7e35..99e62cc 100644 --- a/notebook/Examples_set_dynamic_nthrs.ipynb +++ b/notebook/Examples_set_dynamic_nthrs.ipynb @@ -34,7 +34,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_set_dynamic_nthrs.1.c " + "%load ../sources/Example_set_dynamic_nthrs.1.c " ] }, { @@ -43,7 +43,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_set_dynamic_nthrs.1.f " + "%load ../sources/Example_set_dynamic_nthrs.1.f " ] }, { @@ -53,19 +53,19 @@ "---end--- " ] } -], -"metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } -}, -"nbformat": 4, -"nbformat_minor": 2 + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/notebook/Examples_simple_lock.ipynb b/notebook/Examples_simple_lock.ipynb index 32e5360..b0700d3 100644 --- a/notebook/Examples_simple_lock.ipynb +++ b/notebook/Examples_simple_lock.ipynb @@ -27,7 +27,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_simple_lock.1.c " + "%load ../sources/Example_simple_lock.1.c " ] }, { @@ -43,7 +43,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_simple_lock.1.f " + "%load ../sources/Example_simple_lock.1.f " ] }, { @@ -53,19 +53,19 @@ "---end--- " ] } -], -"metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } -}, -"nbformat": 4, -"nbformat_minor": 2 + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/notebook/Examples_single.ipynb b/notebook/Examples_single.ipynb index 632ec04..99f86ac 100644 --- a/notebook/Examples_single.ipynb +++ b/notebook/Examples_single.ipynb @@ -20,7 +20,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_single.1.c " + "%load ../sources/Example_single.1.c " ] }, { @@ -29,7 +29,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_single.1.f " + "%load ../sources/Example_single.1.f " ] }, { @@ -39,19 +39,19 @@ "---end--- " ] } -], -"metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } -}, -"nbformat": 4, -"nbformat_minor": 2 + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/notebook/Examples_standalone.ipynb b/notebook/Examples_standalone.ipynb index 65aa37b..49a6cee 100644 --- a/notebook/Examples_standalone.ipynb +++ b/notebook/Examples_standalone.ipynb @@ -27,7 +27,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_standalone.1.c " + "%load ../sources/Example_standalone.1.c " ] }, { @@ -43,7 +43,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_standalone.1.f90 " + "%load ../sources/Example_standalone.1.f90 " ] }, { @@ -59,7 +59,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_standalone.2.c " + "%load ../sources/Example_standalone.2.c " ] }, { @@ -75,7 +75,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_standalone.2.f90 " + "%load ../sources/Example_standalone.2.f90 " ] }, { @@ -85,19 +85,19 @@ "---end--- " ] } -], -"metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } -}, -"nbformat": 4, -"nbformat_minor": 2 + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/notebook/Examples_target.ipynb b/notebook/Examples_target.ipynb index 276fa60..2d2dcef 100644 --- a/notebook/Examples_target.ipynb +++ b/notebook/Examples_target.ipynb @@ -27,7 +27,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_target.1.c " + "%load ../sources/Example_target.1.c " ] }, { @@ -36,7 +36,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_target.1.f90 " + "%load ../sources/Example_target.1.f90 " ] }, { @@ -59,7 +59,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_target.2.c " + "%load ../sources/Example_target.2.c " ] }, { @@ -68,7 +68,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_target.2.f90 " + "%load ../sources/Example_target.2.f90 " ] }, { @@ -105,7 +105,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_target.3.c " + "%load ../sources/Example_target.3.c " ] }, { @@ -121,7 +121,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_target.3.f90 " + "%load ../sources/Example_target.3.f90 " ] }, { @@ -144,7 +144,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_target.4.c " + "%load ../sources/Example_target.4.c " ] }, { @@ -160,7 +160,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_target.4.f90 " + "%load ../sources/Example_target.4.f90 " ] }, { @@ -176,7 +176,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_target.4b.f90 " + "%load ../sources/Example_target.4b.f90 " ] }, { @@ -213,7 +213,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_target.5.c " + "%load ../sources/Example_target.5.c " ] }, { @@ -222,7 +222,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_target.5.f90 " + "%load ../sources/Example_target.5.f90 " ] }, { @@ -245,7 +245,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_target.6.c " + "%load ../sources/Example_target.6.c " ] }, { @@ -254,7 +254,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_target.6.f90 " + "%load ../sources/Example_target.6.f90 " ] }, { @@ -264,19 +264,19 @@ "---end--- " ] } -], -"metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } -}, -"nbformat": 4, -"nbformat_minor": 2 + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/notebook/Examples_target_data.ipynb b/notebook/Examples_target_data.ipynb index e51d8e6..6dd2515 100644 --- a/notebook/Examples_target_data.ipynb +++ b/notebook/Examples_target_data.ipynb @@ -27,7 +27,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_target_data.1.c " + "%load ../sources/Example_target_data.1.c " ] }, { @@ -43,7 +43,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_target_data.1.f90 " + "%load ../sources/Example_target_data.1.f90 " ] }, { @@ -73,7 +73,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_target_data.2.c " + "%load ../sources/Example_target_data.2.c " ] }, { @@ -89,7 +89,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_target_data.2.f90 " + "%load ../sources/Example_target_data.2.f90 " ] }, { @@ -105,7 +105,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_target_data.3.c " + "%load ../sources/Example_target_data.3.c " ] }, { @@ -121,7 +121,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_target_data.3.f90 " + "%load ../sources/Example_target_data.3.f90 " ] }, { @@ -165,7 +165,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_target_data.4.c " + "%load ../sources/Example_target_data.4.c " ] }, { @@ -195,7 +195,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_target_data.4.f90 " + "%load ../sources/Example_target_data.4.f90 " ] }, { @@ -211,7 +211,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_target_data.5.cpp " + "%load ../sources/Example_target_data.5.cpp " ] }, { @@ -227,7 +227,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_target_data.5.f90 " + "%load ../sources/Example_target_data.5.f90 " ] }, { @@ -264,7 +264,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_target_data.6.c " + "%load ../sources/Example_target_data.6.c " ] }, { @@ -280,7 +280,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_target_data.6.f90 " + "%load ../sources/Example_target_data.6.f90 " ] }, { @@ -296,7 +296,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_target_data.7.c " + "%load ../sources/Example_target_data.7.c " ] }, { @@ -312,7 +312,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_target_data.7.f90 " + "%load ../sources/Example_target_data.7.f90 " ] }, { @@ -322,19 +322,19 @@ "---end--- " ] } -], -"metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } -}, -"nbformat": 4, -"nbformat_minor": 2 + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/notebook/Examples_target_unstructured_data.ipynb b/notebook/Examples_target_unstructured_data.ipynb index ed2c87a..3010091 100644 --- a/notebook/Examples_target_unstructured_data.ipynb +++ b/notebook/Examples_target_unstructured_data.ipynb @@ -50,7 +50,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_target_unstructured_data.1.cpp " + "%load ../sources/Example_target_unstructured_data.1.cpp " ] }, { @@ -66,7 +66,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_target_unstructured_data.1.c " + "%load ../sources/Example_target_unstructured_data.1.c " ] }, { @@ -82,7 +82,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_target_unstructured_data.1.f90 " + "%load ../sources/Example_target_unstructured_data.1.f90 " ] }, { @@ -100,19 +100,19 @@ "---end--- " ] } -], -"metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } -}, -"nbformat": 4, -"nbformat_minor": 2 + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/notebook/Examples_target_update.ipynb b/notebook/Examples_target_update.ipynb index e14f58d..21e05a4 100644 --- a/notebook/Examples_target_update.ipynb +++ b/notebook/Examples_target_update.ipynb @@ -69,7 +69,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_target_update.1.c " + "%load ../sources/Example_target_update.1.c " ] }, { @@ -78,7 +78,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_target_update.1.f90 " + "%load ../sources/Example_target_update.1.f90 " ] }, { @@ -115,7 +115,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_target_update.2.c " + "%load ../sources/Example_target_update.2.c " ] }, { @@ -124,7 +124,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_target_update.2.f90 " + "%load ../sources/Example_target_update.2.f90 " ] }, { @@ -134,19 +134,19 @@ "---end--- " ] } -], -"metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } -}, -"nbformat": 4, -"nbformat_minor": 2 + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/notebook/Examples_task_dep.ipynb b/notebook/Examples_task_dep.ipynb index 4aab0aa..fc7aa47 100644 --- a/notebook/Examples_task_dep.ipynb +++ b/notebook/Examples_task_dep.ipynb @@ -27,7 +27,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_task_dep.1.c " + "%load ../sources/Example_task_dep.1.c " ] }, { @@ -36,7 +36,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_task_dep.1.f90 " + "%load ../sources/Example_task_dep.1.f90 " ] }, { @@ -66,7 +66,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_task_dep.2.c " + "%load ../sources/Example_task_dep.2.c " ] }, { @@ -75,7 +75,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_task_dep.2.f90 " + "%load ../sources/Example_task_dep.2.f90 " ] }, { @@ -105,7 +105,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_task_dep.3.c " + "%load ../sources/Example_task_dep.3.c " ] }, { @@ -114,7 +114,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_task_dep.3.f90 " + "%load ../sources/Example_task_dep.3.f90 " ] }, { @@ -144,7 +144,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_task_dep.4.c " + "%load ../sources/Example_task_dep.4.c " ] }, { @@ -153,7 +153,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_task_dep.4.f90 " + "%load ../sources/Example_task_dep.4.f90 " ] }, { @@ -183,7 +183,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_task_dep.5.c " + "%load ../sources/Example_task_dep.5.c " ] }, { @@ -192,7 +192,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_task_dep.5.f90 " + "%load ../sources/Example_task_dep.5.f90 " ] }, { @@ -202,19 +202,19 @@ "---end--- " ] } -], -"metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } -}, -"nbformat": 4, -"nbformat_minor": 2 + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/notebook/Examples_task_priority.ipynb b/notebook/Examples_task_priority.ipynb index 64ce369..3cb4acd 100644 --- a/notebook/Examples_task_priority.ipynb +++ b/notebook/Examples_task_priority.ipynb @@ -36,7 +36,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_task_priority.1.c " + "%load ../sources/Example_task_priority.1.c " ] }, { @@ -45,7 +45,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_task_priority.1.f90 " + "%load ../sources/Example_task_priority.1.f90 " ] }, { @@ -55,19 +55,19 @@ "---end--- " ] } -], -"metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } -}, -"nbformat": 4, -"nbformat_minor": 2 + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/notebook/Examples_taskgroup.ipynb b/notebook/Examples_taskgroup.ipynb index 627f782..ae6e358 100644 --- a/notebook/Examples_taskgroup.ipynb +++ b/notebook/Examples_taskgroup.ipynb @@ -27,7 +27,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_taskgroup.1.c " + "%load ../sources/Example_taskgroup.1.c " ] }, { @@ -36,7 +36,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_taskgroup.1.f90 " + "%load ../sources/Example_taskgroup.1.f90 " ] }, { @@ -46,19 +46,19 @@ "---end--- " ] } -], -"metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } -}, -"nbformat": 4, -"nbformat_minor": 2 + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/notebook/Examples_tasking.ipynb b/notebook/Examples_tasking.ipynb index 20c7b03..a245f12 100644 --- a/notebook/Examples_tasking.ipynb +++ b/notebook/Examples_tasking.ipynb @@ -20,7 +20,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_tasking.1.c " + "%load ../sources/Example_tasking.1.c " ] }, { @@ -29,7 +29,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_tasking.1.f90 " + "%load ../sources/Example_tasking.1.f90 " ] }, { @@ -45,7 +45,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_tasking.2.c " + "%load ../sources/Example_tasking.2.c " ] }, { @@ -54,7 +54,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_tasking.2.f90 " + "%load ../sources/Example_tasking.2.f90 " ] }, { @@ -70,7 +70,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_tasking.3.c " + "%load ../sources/Example_tasking.3.c " ] }, { @@ -79,7 +79,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_tasking.3.f90 " + "%load ../sources/Example_tasking.3.f90 " ] }, { @@ -95,7 +95,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_tasking.4.c " + "%load ../sources/Example_tasking.4.c " ] }, { @@ -104,7 +104,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_tasking.4.f " + "%load ../sources/Example_tasking.4.f " ] }, { @@ -127,7 +127,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_tasking.5.c " + "%load ../sources/Example_tasking.5.c " ] }, { @@ -136,7 +136,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_tasking.5.f " + "%load ../sources/Example_tasking.5.f " ] }, { @@ -159,7 +159,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_tasking.6.c " + "%load ../sources/Example_tasking.6.c " ] }, { @@ -168,7 +168,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_tasking.6.f " + "%load ../sources/Example_tasking.6.f " ] }, { @@ -191,7 +191,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_tasking.7.c " + "%load ../sources/Example_tasking.7.c " ] }, { @@ -200,7 +200,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_tasking.7.f " + "%load ../sources/Example_tasking.7.f " ] }, { @@ -216,7 +216,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_tasking.8.c " + "%load ../sources/Example_tasking.8.c " ] }, { @@ -225,7 +225,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_tasking.8.f " + "%load ../sources/Example_tasking.8.f " ] }, { @@ -248,7 +248,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_tasking.9.c " + "%load ../sources/Example_tasking.9.c " ] }, { @@ -257,7 +257,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_tasking.9.f " + "%load ../sources/Example_tasking.9.f " ] }, { @@ -273,7 +273,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_tasking.10.c " + "%load ../sources/Example_tasking.10.c " ] }, { @@ -282,7 +282,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_tasking.10.f90 " + "%load ../sources/Example_tasking.10.f90 " ] }, { @@ -298,7 +298,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_tasking.11.c " + "%load ../sources/Example_tasking.11.c " ] }, { @@ -307,7 +307,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_tasking.11.f90 " + "%load ../sources/Example_tasking.11.f90 " ] }, { @@ -323,7 +323,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_tasking.12.c " + "%load ../sources/Example_tasking.12.c " ] }, { @@ -332,7 +332,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_tasking.12.f90 " + "%load ../sources/Example_tasking.12.f90 " ] }, { @@ -355,7 +355,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_tasking.13.c " + "%load ../sources/Example_tasking.13.c " ] }, { @@ -364,7 +364,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_tasking.13.f90 " + "%load ../sources/Example_tasking.13.f90 " ] }, { @@ -380,7 +380,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_tasking.14.c " + "%load ../sources/Example_tasking.14.c " ] }, { @@ -389,7 +389,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_tasking.14.f90 " + "%load ../sources/Example_tasking.14.f90 " ] }, { @@ -399,19 +399,19 @@ "---end--- " ] } -], -"metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } -}, -"nbformat": 4, -"nbformat_minor": 2 + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/notebook/Examples_taskloop.ipynb b/notebook/Examples_taskloop.ipynb index 2b03efa..18521c7 100644 --- a/notebook/Examples_taskloop.ipynb +++ b/notebook/Examples_taskloop.ipynb @@ -42,19 +42,19 @@ "---end--- " ] } -], -"metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } -}, -"nbformat": 4, -"nbformat_minor": 2 + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/notebook/Examples_taskyield.ipynb b/notebook/Examples_taskyield.ipynb index a206dd9..caf6c99 100644 --- a/notebook/Examples_taskyield.ipynb +++ b/notebook/Examples_taskyield.ipynb @@ -20,7 +20,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_taskyield.1.c " + "%load ../sources/Example_taskyield.1.c " ] }, { @@ -29,7 +29,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_taskyield.1.f90 " + "%load ../sources/Example_taskyield.1.f90 " ] }, { @@ -39,19 +39,19 @@ "---end--- " ] } -], -"metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } -}, -"nbformat": 4, -"nbformat_minor": 2 + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/notebook/Examples_teams.ipynb b/notebook/Examples_teams.ipynb index 17b949f..b4e1c74 100644 --- a/notebook/Examples_teams.ipynb +++ b/notebook/Examples_teams.ipynb @@ -41,7 +41,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_teams.1.c " + "%load ../sources/Example_teams.1.c " ] }, { @@ -50,7 +50,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_teams.1.f90 " + "%load ../sources/Example_teams.1.f90 " ] }, { @@ -94,7 +94,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_teams.2.c " + "%load ../sources/Example_teams.2.c " ] }, { @@ -103,7 +103,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_teams.2.f90 " + "%load ../sources/Example_teams.2.f90 " ] }, { @@ -133,7 +133,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_teams.3.c " + "%load ../sources/Example_teams.3.c " ] }, { @@ -142,7 +142,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_teams.3.f90 " + "%load ../sources/Example_teams.3.f90 " ] }, { @@ -193,7 +193,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_teams.4.c " + "%load ../sources/Example_teams.4.c " ] }, { @@ -202,7 +202,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_teams.4.f90 " + "%load ../sources/Example_teams.4.f90 " ] }, { @@ -232,7 +232,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_teams.5.c " + "%load ../sources/Example_teams.5.c " ] }, { @@ -241,7 +241,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_teams.5.f90 " + "%load ../sources/Example_teams.5.f90 " ] }, { @@ -271,7 +271,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_teams.6.c " + "%load ../sources/Example_teams.6.c " ] }, { @@ -280,7 +280,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_teams.6.f90 " + "%load ../sources/Example_teams.6.f90 " ] }, { @@ -290,19 +290,19 @@ "---end--- " ] } -], -"metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } -}, -"nbformat": 4, -"nbformat_minor": 2 + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/notebook/Examples_threadprivate.ipynb b/notebook/Examples_threadprivate.ipynb index d4b58b5..8bfc4d2 100644 --- a/notebook/Examples_threadprivate.ipynb +++ b/notebook/Examples_threadprivate.ipynb @@ -20,7 +20,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_threadprivate.1.c " + "%load ../sources/Example_threadprivate.1.c " ] }, { @@ -29,7 +29,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_threadprivate.1.f " + "%load ../sources/Example_threadprivate.1.f " ] }, { @@ -45,7 +45,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_threadprivate.2.c " + "%load ../sources/Example_threadprivate.2.c " ] }, { @@ -61,7 +61,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_cppnexamplethreadprivate3 " + "%load ../sources/Example_cppnexamplethreadprivate3 " ] }, { @@ -91,7 +91,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_threadprivate.2.f " + "%load ../sources/Example_threadprivate.2.f " ] }, { @@ -107,7 +107,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_threadprivate.3.f " + "%load ../sources/Example_threadprivate.3.f " ] }, { @@ -123,7 +123,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_threadprivate.4.f " + "%load ../sources/Example_threadprivate.4.f " ] }, { @@ -140,7 +140,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_threadprivate.5.f " + "%load ../sources/Example_threadprivate.5.f " ] }, { @@ -199,7 +199,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_threadprivate.6.f " + "%load ../sources/Example_threadprivate.6.f " ] }, { @@ -215,7 +215,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_cppspecificstart " + "%load ../sources/Example_cppspecificstart " ] }, { @@ -231,7 +231,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_cppnexamplethreadprivate4 " + "%load ../sources/Example_cppnexamplethreadprivate4 " ] }, { @@ -247,7 +247,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_cppnexamplethreadprivate5 " + "%load ../sources/Example_cppnexamplethreadprivate5 " ] }, { @@ -256,7 +256,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_cppspecificend " + "%load ../sources/Example_cppspecificend " ] }, { @@ -266,19 +266,19 @@ "---end--- " ] } -], -"metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } -}, -"nbformat": 4, -"nbformat_minor": 2 + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/notebook/Examples_workshare.ipynb b/notebook/Examples_workshare.ipynb index c3a85f4..38d318c 100644 --- a/notebook/Examples_workshare.ipynb +++ b/notebook/Examples_workshare.ipynb @@ -34,7 +34,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_workshare.1.f " + "%load ../sources/Example_workshare.1.f " ] }, { @@ -50,7 +50,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_workshare.2.f " + "%load ../sources/Example_workshare.2.f " ] }, { @@ -74,7 +74,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_workshare.3.f " + "%load ../sources/Example_workshare.3.f " ] }, { @@ -104,7 +104,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_workshare.4.f " + "%load ../sources/Example_workshare.4.f " ] }, { @@ -128,7 +128,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_workshare.5.f " + "%load ../sources/Example_workshare.5.f " ] }, { @@ -144,7 +144,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_workshare.6.f " + "%load ../sources/Example_workshare.6.f " ] }, { @@ -160,7 +160,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_workshare.7.f " + "%load ../sources/Example_workshare.7.f " ] }, { @@ -177,19 +177,19 @@ "---end--- " ] } -], -"metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } -}, -"nbformat": 4, -"nbformat_minor": 2 + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/notebook/Examples_worksharing_critical.ipynb b/notebook/Examples_worksharing_critical.ipynb index 51f73d1..5a788a6 100644 --- a/notebook/Examples_worksharing_critical.ipynb +++ b/notebook/Examples_worksharing_critical.ipynb @@ -20,7 +20,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_worksharing_critical.1.c " + "%load ../sources/Example_worksharing_critical.1.c " ] }, { @@ -29,7 +29,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_worksharing_critical.1.f " + "%load ../sources/Example_worksharing_critical.1.f " ] }, { @@ -39,19 +39,19 @@ "---end--- " ] } -], -"metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } -}, -"nbformat": 4, -"nbformat_minor": 2 + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/notebook/History.ipynb b/notebook/History.ipynb index 84a5e3c..3a999c0 100644 --- a/notebook/History.ipynb +++ b/notebook/History.ipynb @@ -110,19 +110,19 @@ "---end--- " ] } -], -"metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } -}, -"nbformat": 4, -"nbformat_minor": 2 + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/notebook/Introduction_Chapt.ipynb b/notebook/Introduction_Chapt.ipynb index 753ae96..8653146 100644 --- a/notebook/Introduction_Chapt.ipynb +++ b/notebook/Introduction_Chapt.ipynb @@ -121,19 +121,19 @@ "---end--- " ] } -], -"metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } -}, -"nbformat": 4, -"nbformat_minor": 2 + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/notebook/Title_Page.ipynb b/notebook/Title_Page.ipynb index fbfcc8d..bd43872 100644 --- a/notebook/Title_Page.ipynb +++ b/notebook/Title_Page.ipynb @@ -199,19 +199,19 @@ "---end--- " ] } -], -"metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } -}, -"nbformat": 4, -"nbformat_minor": 2 + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/notebook/openmp-examples.ipynb b/notebook/openmp-examples.ipynb index d60a9a2..29f7c60 100644 --- a/notebook/openmp-examples.ipynb +++ b/notebook/openmp-examples.ipynb @@ -237,19 +237,19 @@ "---end--- " ] } -], -"metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" + ], + "metadata": { + "kernelspec": { + "display_name": "C", + "language": "c", + "name": "c" + }, + "language_info": { + "file_extension": ".c", + "mimetype": "text/plain", + "name": "c" + } }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } -}, -"nbformat": 4, -"nbformat_minor": 2 + "nbformat": 4, + "nbformat_minor": 2 } diff --git a/notebook/tex2notebook.py b/notebook/tex2notebook.py index f7a0936..872308c 100644 --- a/notebook/tex2notebook.py +++ b/notebook/tex2notebook.py @@ -15,21 +15,21 @@ # with open('NBSets/code.txt', 'r') as f: # CB = f.read() -LanguageSet = '],\n' + \ - '"metadata": {\n' + \ - ' "kernelspec": {\n' + \ - ' "display_name": "C",\n' + \ - ' "language": "c",\n' + \ - ' "name": "c"\n' + \ +LanguageSet = ' ],\n' + \ + ' "metadata": {\n' + \ + ' "kernelspec": {\n' + \ + ' "display_name": "C",\n' + \ + ' "language": "c",\n' + \ + ' "name": "c"\n' + \ + ' },\n' + \ + ' "language_info": {\n' + \ + ' "file_extension": ".c",\n' + \ + ' "mimetype": "text/plain",\n' + \ + ' "name": "c"\n' + \ + ' }\n' + \ ' },\n' + \ - ' "language_info": {\n' + \ - ' "file_extension": ".c",\n' + \ - ' "mimetype": "text/plain",\n' + \ - ' "name": "c"\n' + \ - ' }\n' + \ - '},\n' + \ - '"nbformat": 4,\n' + \ - '"nbformat_minor": 2\n' + \ + ' "nbformat": 4,\n' + \ + ' "nbformat_minor": 2\n' + \ '}\n' MB = ' {\n' + \ @@ -44,7 +44,7 @@ ' "metadata": {},\n' + \ ' "outputs": [],\n' + \ ' "source": [\n' + \ - ' "' + ' "' E = ' "\n ]\n },\n' E1 = ' \n ]\n },\n' From d44b3b1b1bd7559712919e1e8f85a6ec364c0707 Mon Sep 17 00:00:00 2001 From: Kewei Yan Date: Tue, 8 Oct 2019 11:44:56 -0400 Subject: [PATCH 10/21] test4 --- notebook/Chap_SIMD.ipynb | 70 +- notebook/Chap_affinity.ipynb | 140 +-- notebook/Chap_data_environment.ipynb | 140 +-- notebook/Chap_devices.ipynb | 90 +- notebook/Chap_memory_model.ipynb | 90 +- notebook/Chap_parallel_execution.ipynb | 200 ++-- notebook/Chap_program_control.ipynb | 170 ++-- notebook/Chap_synchronization.ipynb | 100 +- notebook/Chap_tasking.ipynb | 80 +- notebook/Examples_Chapt.ipynb | 40 +- notebook/Examples_SIMD.ipynb | 412 ++++---- notebook/Examples_affinity.ipynb | 920 +++++++++--------- notebook/Examples_affinity_query.ipynb | 98 +- notebook/Examples_array_sections.ipynb | 182 ++-- notebook/Examples_associate.ipynb | 112 +-- notebook/Examples_async_target_depend.ipynb | 50 +- notebook/Examples_async_target_nowait.ipynb | 88 +- .../Examples_async_target_nowait_depend.ipynb | 88 +- .../Examples_async_target_with_tasks.ipynb | 156 +-- notebook/Examples_atomic.ipynb | 154 +-- notebook/Examples_atomic_restrict.ipynb | 130 +-- notebook/Examples_barrier_regions.ipynb | 78 +- notebook/Examples_cancellation.ipynb | 116 +-- notebook/Examples_carrays_fpriv.ipynb | 144 +-- notebook/Examples_collapse.ipynb | 194 ++-- notebook/Examples_cond_comp.ipynb | 88 +- notebook/Examples_copyin.ipynb | 58 +- notebook/Examples_copyprivate.ipynb | 174 ++-- notebook/Examples_cpp_reference.ipynb | 72 +- notebook/Examples_critical.ipynb | 96 +- notebook/Examples_declare_target.ipynb | 456 ++++----- notebook/Examples_default_none.ipynb | 78 +- notebook/Examples_device.ipynb | 228 ++--- notebook/Examples_doacross.ipynb | 182 ++-- notebook/Examples_flush_nolist.ipynb | 58 +- notebook/Examples_fort_do.ipynb | 88 +- notebook/Examples_fort_loopvar.ipynb | 88 +- notebook/Examples_fort_race.ipynb | 64 +- notebook/Examples_fort_sa_private.ipynb | 130 +-- notebook/Examples_fort_sp_common.ipynb | 180 ++-- notebook/Examples_fpriv_sections.ipynb | 58 +- notebook/Examples_get_nthrs.ipynb | 96 +- notebook/Examples_icv.ipynb | 138 +-- notebook/Examples_init_lock.ipynb | 58 +- notebook/Examples_init_lock_with_hint.ipynb | 58 +- notebook/Examples_lastprivate.ipynb | 58 +- notebook/Examples_linear_in_loop.ipynb | 58 +- notebook/Examples_lock_owner.ipynb | 68 +- notebook/Examples_locks.ipynb | 30 +- notebook/Examples_master.ipynb | 58 +- notebook/Examples_mem_model.ipynb | 144 +-- notebook/Examples_nestable_lock.ipynb | 58 +- notebook/Examples_nested_loop.ipynb | 96 +- notebook/Examples_nesting_restrict.ipynb | 320 +++--- notebook/Examples_nowait.ipynb | 106 +- notebook/Examples_nthrs_dynamic.ipynb | 116 +-- notebook/Examples_nthrs_nesting.ipynb | 58 +- notebook/Examples_ordered.ipynb | 134 +-- notebook/Examples_parallel.ipynb | 58 +- notebook/Examples_ploop.ipynb | 58 +- notebook/Examples_pra_iterator.ipynb | 72 +- notebook/Examples_private.ipynb | 134 +-- notebook/Examples_psections.ipynb | 58 +- notebook/Examples_reduction.ipynb | 306 +++--- notebook/Examples_set_dynamic_nthrs.ipynb | 78 +- notebook/Examples_simple_lock.ipynb | 78 +- notebook/Examples_single.ipynb | 58 +- notebook/Examples_standalone.ipynb | 126 +-- notebook/Examples_target.ipynb | 394 ++++---- notebook/Examples_target_data.ipynb | 476 ++++----- .../Examples_target_unstructured_data.ipynb | 142 +-- notebook/Examples_target_update.ipynb | 196 ++-- notebook/Examples_task_dep.ipynb | 300 +++--- notebook/Examples_task_priority.ipynb | 78 +- notebook/Examples_taskgroup.ipynb | 68 +- notebook/Examples_tasking.ipynb | 698 ++++++------- notebook/Examples_taskloop.ipynb | 60 +- notebook/Examples_taskyield.ipynb | 58 +- notebook/Examples_teams.ipynb | 428 ++++---- notebook/Examples_threadprivate.ipynb | 394 ++++---- notebook/Examples_workshare.ipynb | 258 ++--- notebook/Examples_worksharing_critical.ipynb | 58 +- notebook/History.ipynb | 110 +-- notebook/Introduction_Chapt.ipynb | 120 +-- notebook/Title_Page.ipynb | 140 +-- notebook/openmp-examples.ipynb | 230 ++--- notebook/tex2notebook.py | 26 +- 87 files changed, 6527 insertions(+), 6527 deletions(-) diff --git a/notebook/Chap_SIMD.ipynb b/notebook/Chap_SIMD.ipynb index ce6d018..4a50475 100644 --- a/notebook/Chap_SIMD.ipynb +++ b/notebook/Chap_SIMD.ipynb @@ -1,45 +1,45 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ## SIMD " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ## SIMD " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Single instruction, multiple data (SIMD) is a form of parallel execution in which the same operation is performed on multiple data elements independently in hardware vector processing units (VPU), also called SIMD units. The addition of two vectors to form a third vector is a SIMD operation. Many processors have SIMD (vector) units that can perform simultaneously 2, 4, 8 or more executions of the same operation (by a single SIMD unit). " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Single instruction, multiple data (SIMD) is a form of parallel execution in which the same operation is performed on multiple data elements independently in hardware vector processing units (VPU), also called SIMD units. The addition of two vectors to form a third vector is a SIMD operation. Many processors have SIMD (vector) units that can perform simultaneously 2, 4, 8 or more executions of the same operation (by a single SIMD unit). " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Loops without loop-carried backward dependency (or with dependency preserved using ordered simd) are candidates for vectorization by the compiler for execution with SIMD units. In addition, with state-of-the-art vectorization technology and `declare simd` construct extensions for function vectorization in the OpenMP 4.5 specification, loops with function calls can be vectorized as well. The basic idea is that a scalar function call in a loop can be replaced by a vector version of the function, and the loop can be vectorized simultaneously by combining a loop vectorization ( `simd` directive on the loop) and a function vectorization ( `declare simd` directive on the function). " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Loops without loop-carried backward dependency (or with dependency preserved using ordered simd) are candidates for vectorization by the compiler for execution with SIMD units. In addition, with state-of-the-art vectorization technology and `declare simd` construct extensions for function vectorization in the OpenMP 4.5 specification, loops with function calls can be vectorized as well. The basic idea is that a scalar function call in a loop can be replaced by a vector version of the function, and the loop can be vectorized simultaneously by combining a loop vectorization ( `simd` directive on the loop) and a function vectorization ( `declare simd` directive on the function). " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " A `simd` construct states that SIMD operations be performed on the data within the loop. A number of clauses are available to provide data-sharing attributes ( `private` , `linear` , `reduction` and `lastprivate` ). Other clauses provide vector length preference/restrictions ( `simdlen` / `safelen` ), loop fusion ( `collapse` ), and data alignment ( `aligned` ). " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " A `simd` construct states that SIMD operations be performed on the data within the loop. A number of clauses are available to provide data-sharing attributes ( `private` , `linear` , `reduction` and `lastprivate` ). Other clauses provide vector length preference/restrictions ( `simdlen` / `safelen` ), loop fusion ( `collapse` ), and data alignment ( `aligned` ). " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `declare simd` directive designates that a vector version of the function should also be constructed for execution within loops that contain the function and have a `simd` directive. Clauses provide argument specifications ( `linear` , `uniform` , and `aligned` ), a requested vector length ( `simdlen` ), and designate whether the function is always/never called conditionally in a loop ( `branch` / `inbranch` ). The latter is for optimizing peformance. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `declare simd` directive designates that a vector version of the function should also be constructed for execution within loops that contain the function and have a `simd` directive. Clauses provide argument specifications ( `linear` , `uniform` , and `aligned` ), a requested vector length ( `simdlen` ), and designate whether the function is always/never called conditionally in a loop ( `branch` / `inbranch` ). The latter is for optimizing peformance. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Also, the `simd` construct has been combined with the worksharing loop constructs ( `for simd` and `do simd` ) to enable simultaneous thread execution in different SIMD units. \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Also, the `simd` construct has been combined with the worksharing loop constructs ( `for simd` and `do simd` ) to enable simultaneous thread execution in different SIMD units. \n", "Hence, the `simd` construct can be \n", "used alone on a loop to direct vectorization (SIMD execution), or in \n", "combination with a parallel loop construct to include thread parallelism \n", @@ -48,11 +48,11 @@ " `parallel for simd` ). " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end--- " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Chap_affinity.ipynb b/notebook/Chap_affinity.ipynb index 30a7409..5d505dc 100644 --- a/notebook/Chap_affinity.ipynb +++ b/notebook/Chap_affinity.ipynb @@ -1,38 +1,38 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ## OpenMP Affinity " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ## OpenMP Affinity " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " OpenMP Affinity consists of a `proc_bind` policy (thread affinity policy) and a specification of places ( ' location units ' or _processors_ that may be cores, hardware threads, sockets, etc.). OpenMP Affinity enables users to bind computations on specific places. The placement will hold for the duration of the parallel region. However, the runtime is free to migrate the OpenMP threads to different cores (hardware threads, sockets, etc.) prescribed within a given place, if two or more cores (hardware threads, sockets, etc.) have been assigned to a given place. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " OpenMP Affinity consists of a `proc_bind` policy (thread affinity policy) and a specification of places ( ' location units ' or _processors_ that may be cores, hardware threads, sockets, etc.). OpenMP Affinity enables users to bind computations on specific places. The placement will hold for the duration of the parallel region. However, the runtime is free to migrate the OpenMP threads to different cores (hardware threads, sockets, etc.) prescribed within a given place, if two or more cores (hardware threads, sockets, etc.) have been assigned to a given place. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Often the binding can be managed without resorting to explicitly setting places. Without the specification of places in the `OMP_PLACES` variable, the OpenMP runtime will distribute and bind threads using the entire range of processors for the OpenMP program, according to the `OMP_PROC_BIND` environment variable or the `proc_bind` clause. When places are specified, the OMP runtime binds threads to the places according to a default distribution policy, or those specified in the `OMP_PROC_BIND` environment variable or the `proc_bind` clause. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Often the binding can be managed without resorting to explicitly setting places. Without the specification of places in the `OMP_PLACES` variable, the OpenMP runtime will distribute and bind threads using the entire range of processors for the OpenMP program, according to the `OMP_PROC_BIND` environment variable or the `proc_bind` clause. When places are specified, the OMP runtime binds threads to the places according to a default distribution policy, or those specified in the `OMP_PROC_BIND` environment variable or the `proc_bind` clause. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the OpenMP Specifications document a processor refers to an execution unit that is enabled for an OpenMP thread to use. A processor is a core when there is no SMT (Simultaneous Multi-Threading) support or SMT is disabled. When SMT is enabled, a processor is a hardware thread (HW-thread). (This is the usual case; but actually, the execution unit is implementation defined.) Processor numbers are numbered sequentially from 0 to the number of cores less one (without SMT), or 0 to the number HW-threads less one (with SMT). OpenMP places use the processor number to designate binding locations (unless an ' abstract name ' is used.) " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the OpenMP Specifications document a processor refers to an execution unit that is enabled for an OpenMP thread to use. A processor is a core when there is no SMT (Simultaneous Multi-Threading) support or SMT is disabled. When SMT is enabled, a processor is a hardware thread (HW-thread). (This is the usual case; but actually, the execution unit is implementation defined.) Processor numbers are numbered sequentially from 0 to the number of cores less one (without SMT), or 0 to the number HW-threads less one (with SMT). OpenMP places use the processor number to designate binding locations (unless an ' abstract name ' is used.) " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The processors available to a process may be a subset of the system's processors. This restriction may be the result of a wrapper process controlling the execution (such as `numactl` on Linux systems), compiler options, library-specific environment variables, or default kernel settings. For instance, the execution of multiple MPI processes, launched on a single compute node, will each have a subset of processors as determined by the MPI launcher or set by MPI affinity environment variables for the MPI library. \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The processors available to a process may be a subset of the system's processors. This restriction may be the result of a wrapper process controlling the execution (such as `numactl` on Linux systems), compiler options, library-specific environment variables, or default kernel settings. For instance, the execution of multiple MPI processes, launched on a single compute node, will each have a subset of processors as determined by the MPI launcher or set by MPI affinity environment variables for the MPI library. \n", "Forked threads within an MPI process \n", "(for a hybrid execution of MPI and OpenMP code) inherit the valid \n", "processor set for execution from the parent process (the initial task region) \n", @@ -41,11 +41,11 @@ "the subset of processors available to _the particular_ MPI process. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", "Also, setting an explicit list of processor numbers in the `OMP_PLACES` \n", "variable before an MPI launch (which involves more than one MPI process) will \n", "result in unspecified behavior (and doesn't make sense) because the set of \n", @@ -55,41 +55,41 @@ "which sets `OMP_PLACES` specifically for the MPI process. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Threads of a team are positioned onto places in a compact manner, a scattered distribution, or onto the master's place, by setting the `OMP_PROC_BIND` environment variable or the `proc_bind` clause to _close_ , _spread_ , or _master_ , respectively. When `OMP_PROC_BIND` is set to FALSE no binding is enforced; and when the value is TRUE, the binding is implementation defined to a set of places in the `OMP_PLACES` variable or to places defined by the implementation if the `OMP_PLACES` variable is not set. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Threads of a team are positioned onto places in a compact manner, a scattered distribution, or onto the master's place, by setting the `OMP_PROC_BIND` environment variable or the `proc_bind` clause to _close_ , _spread_ , or _master_ , respectively. When `OMP_PROC_BIND` is set to FALSE no binding is enforced; and when the value is TRUE, the binding is implementation defined to a set of places in the `OMP_PLACES` variable or to places defined by the implementation if the `OMP_PLACES` variable is not set. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `OMP_PLACES` variable can also be set to an abstract name ( _threads_ , _cores_ , _sockets_ ) to specify that a place is either a single hardware thread, a core, or a socket, respectively. This description of the `OMP_PLACES` is most useful when the number of threads is equal to the number of hardware thread, cores or sockets. It can also be used with a _close_ or _spread_ distribution policy when the equality doesn't hold. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `OMP_PLACES` variable can also be set to an abstract name ( _threads_ , _cores_ , _sockets_ ) to specify that a place is either a single hardware thread, a core, or a socket, respectively. This description of the `OMP_PLACES` is most useful when the number of threads is equal to the number of hardware thread, cores or sockets. It can also be used with a _close_ or _spread_ distribution policy when the equality doesn't hold. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", " We need an example of using sockets, cores and threads: " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", " case 1 cores: " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", " Hyper-Threads on (2 hardware threads per core) \n", " 1 socket x 4 cores x 2 HW-threads \n", " \n", @@ -104,11 +104,11 @@ " thread # 3 _ _ _ _ _ _ * _ #mask for thread 3 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", " case 2 threads: \n", " \n", " Hyper-Threads on (2 hardware threads per core) \n", @@ -125,11 +125,11 @@ " thread # 3 _ _ _ _ _ _ * * #mask for thread 3 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", " case 3 sockets: \n", " \n", " No Hyper-Threads \n", @@ -145,11 +145,11 @@ " thread # 0 _ _ _ _ _ _ _ _ * * * * #mask for thread 2 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end--- " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Chap_data_environment.ipynb b/notebook/Chap_data_environment.ipynb index 9da5497..3432430 100644 --- a/notebook/Chap_data_environment.ipynb +++ b/notebook/Chap_data_environment.ipynb @@ -1,106 +1,106 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ## Data Environment " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ## Data Environment " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The OpenMP _data environment_ contains data attributes of variables and objects. Many constructs (such as `parallel` , `simd` , `task` ) accept clauses to control _data-sharing_ attributes of referenced variables in the construct, where _data-sharing_ applies to whether the attribute of the variable is _shared_ , is _private_ storage, or has special operational characteristics (as found in the `firstprivate` , `lastprivate` , `linear` , or `reduction` clause). " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The OpenMP _data environment_ contains data attributes of variables and objects. Many constructs (such as `parallel` , `simd` , `task` ) accept clauses to control _data-sharing_ attributes of referenced variables in the construct, where _data-sharing_ applies to whether the attribute of the variable is _shared_ , is _private_ storage, or has special operational characteristics (as found in the `firstprivate` , `lastprivate` , `linear` , or `reduction` clause). " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The data environment for a device (distinguished as a _device data environment_ ) is controlled on the host by _data-mapping_ attributes, which determine the relationship of the data on the host, the _original_ data, and the data on the device, the _corresponding_ data. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The data environment for a device (distinguished as a _device data environment_ ) is controlled on the host by _data-mapping_ attributes, which determine the relationship of the data on the host, the _original_ data, and the data on the device, the _corresponding_ data. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " bigskip DATA-SHARING ATTRIBUTES " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " bigskip DATA-SHARING ATTRIBUTES " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Data-sharing attributes of variables can be classified as being _predetermined_ , _explicitly determined_ or _implicitly determined_ . " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Data-sharing attributes of variables can be classified as being _predetermined_ , _explicitly determined_ or _implicitly determined_ . " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Certain variables and objects have predetermined attributes. A commonly found case is the loop iteration variable in associated loops of a `for` or `do` construct. It has a private data-sharing attribute. Variables with predetermined data-sharing attributes can not be listed in a data-sharing clause; but there are some exceptions (mainly concerning loop iteration variables). " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Certain variables and objects have predetermined attributes. A commonly found case is the loop iteration variable in associated loops of a `for` or `do` construct. It has a private data-sharing attribute. Variables with predetermined data-sharing attributes can not be listed in a data-sharing clause; but there are some exceptions (mainly concerning loop iteration variables). " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Variables with explicitly determined data-sharing attributes are those that are referenced in a given construct and are listed in a data-sharing attribute clause on the construct. Some of the common data-sharing clauses are: `shared` , `private` , `firstprivate` , `lastprivate` , `linear` , and `reduction` . \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Variables with explicitly determined data-sharing attributes are those that are referenced in a given construct and are listed in a data-sharing attribute clause on the construct. Some of the common data-sharing clauses are: `shared` , `private` , `firstprivate` , `lastprivate` , `linear` , and `reduction` . \n", " Are these all of them? " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Variables with implicitly determined data-sharing attributes are those that are referenced in a given construct, do not have predetermined data-sharing attributes, and are not listed in a data-sharing attribute clause of an enclosing construct. For a complete list of variables and objects with predetermined and implicitly determined attributes, please refer to the _Data-sharing Attribute Rules for Variables Referenced in a Construct_ subsection of the OpenMP Specifications document. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Variables with implicitly determined data-sharing attributes are those that are referenced in a given construct, do not have predetermined data-sharing attributes, and are not listed in a data-sharing attribute clause of an enclosing construct. For a complete list of variables and objects with predetermined and implicitly determined attributes, please refer to the _Data-sharing Attribute Rules for Variables Referenced in a Construct_ subsection of the OpenMP Specifications document. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " bigskip DATA-MAPPING ATTRIBUTES " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " bigskip DATA-MAPPING ATTRIBUTES " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `map` clause on a device construct explictly specifies how the list items in the clause are mapped from the encountering task's data environment (on the host) to the corresponding \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `map` clause on a device construct explictly specifies how the list items in the clause are mapped from the encountering task's data environment (on the host) to the corresponding \n", "* in the device data environment (on the device). The common _list items_ are arrays, array sections, scalars, pointers, and structure elements (members). " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Procedures and global variables have predetermined data mapping if they appear within the list or block of a `declare target` directive. Also, a C/C++ pointer is mapped as a zero-length array section, as is a C++ variable that is a reference to a pointer. \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Procedures and global variables have predetermined data mapping if they appear within the list or block of a `declare target` directive. Also, a C/C++ pointer is mapped as a zero-length array section, as is a C++ variable that is a reference to a pointer. \n", " Waiting for response from Eric on this. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Without explict mapping, non-scalar and non-pointer variables within the scope of the `target` construct are implicitly mapped with a _map-type_ of `tofrom` . Without explicit mapping, scalar variables within the scope of the `target` construct are not mapped, but have an implicit firstprivate data-sharing attribute. (That is, the value of the original variable is given to a private variable of the same name on the device.) This behavior can be changed with the `defaultmap` clause. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Without explict mapping, non-scalar and non-pointer variables within the scope of the `target` construct are implicitly mapped with a _map-type_ of `tofrom` . Without explicit mapping, scalar variables within the scope of the `target` construct are not mapped, but have an implicit firstprivate data-sharing attribute. (That is, the value of the original variable is given to a private variable of the same name on the device.) This behavior can be changed with the `defaultmap` clause. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `map` clause can appear on `target` , `target data` and `target enter/exit data` constructs. The operations of creation and removal of device storage as well as assignment of the original list \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `map` clause can appear on `target` , `target data` and `target enter/exit data` constructs. The operations of creation and removal of device storage as well as assignment of the original list \n", "* values to the corresponding list items may be complicated when the list \n", "* appears on multiple constructs or when the host and device storage is shared. In these cases the item's reference count, the number of times it has been referenced (+1 on entry and -1 on exited) in nested (structured) map regions and/or accumulative (unstructured) mappings, determines the operation. Details of the `map` clause and reference count operation are specified in the _map Clause_ subsection of the OpenMP Specifications document. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end--- " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Chap_devices.ipynb b/notebook/Chap_devices.ipynb index 3670d95..344df1f 100644 --- a/notebook/Chap_devices.ipynb +++ b/notebook/Chap_devices.ipynb @@ -1,66 +1,66 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ## Devices " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ## Devices " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `target` construct consists of a `target` directive and an execution region. The `target` region is executed on the default device or the device specified in the `device` clause. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `target` construct consists of a `target` directive and an execution region. The `target` region is executed on the default device or the device specified in the `device` clause. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In OpenMP version 4.0, by default, all variables within the lexical scope of the construct are copied _to_ and _from_ the device, unless the device is the host, or the data exists on the device from a previously executed data-type construct that has created space on the device and possibly copied host data to the device storage. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In OpenMP version 4.0, by default, all variables within the lexical scope of the construct are copied _to_ and _from_ the device, unless the device is the host, or the data exists on the device from a previously executed data-type construct that has created space on the device and possibly copied host data to the device storage. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The constructs that explicitly create storage, transfer data, and free storage on the device are catagorized as structured and unstructured. The `target` `data` construct is structured. It creates a data region around `target` constructs, and is convenient for providing persistent data throughout multiple `target` regions. The `target` `enter` `data` and `target` `exit` `data` constructs are unstructured, because they can occur anywhere and do not support a 'structure' (a region) for enclosing `target` constructs, as does the `target` `data` construct. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The constructs that explicitly create storage, transfer data, and free storage on the device are catagorized as structured and unstructured. The `target` `data` construct is structured. It creates a data region around `target` constructs, and is convenient for providing persistent data throughout multiple `target` regions. The `target` `enter` `data` and `target` `exit` `data` constructs are unstructured, because they can occur anywhere and do not support a 'structure' (a region) for enclosing `target` constructs, as does the `target` `data` construct. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `map` clause is used on `target` constructs and the data-type constructs to map host data. It specifies the device storage and data movement `to` and `from` the device, and controls on the storage duration. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `map` clause is used on `target` constructs and the data-type constructs to map host data. It specifies the device storage and data movement `to` and `from` the device, and controls on the storage duration. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " There is an important change in the OpenMP 4.5 specification that alters the data model for scalar variables and C/C++ pointer variables. The default behavior for scalar variables and C/C++ pointer variables in an 4.5 compliant code is `firstprivate` . Example codes that have been updated to reflect this new behavior are annotated with a description that describes changes required for correct execution. Often it is a simple matter of mapping the variable as `tofrom` to obtain the intended 4.0 behavior. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " There is an important change in the OpenMP 4.5 specification that alters the data model for scalar variables and C/C++ pointer variables. The default behavior for scalar variables and C/C++ pointer variables in an 4.5 compliant code is `firstprivate` . Example codes that have been updated to reflect this new behavior are annotated with a description that describes changes required for correct execution. Often it is a simple matter of mapping the variable as `tofrom` to obtain the intended 4.0 behavior. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In OpenMP version 4.5 the mechanism for target execution is specified as occuring through a _target task_ . When the `target` construct is encountered a new _target task_ is generated. The _target task_ completes after the `target` region has executed and all data transfers have finished. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In OpenMP version 4.5 the mechanism for target execution is specified as occuring through a _target task_ . When the `target` construct is encountered a new _target task_ is generated. The _target task_ completes after the `target` region has executed and all data transfers have finished. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " This new specification does not affect the execution of pre-4.5 code; it is a necessary element for asynchronous execution of the `target` region when using the new `nowait` clause introduced in OpenMP 4.5. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " This new specification does not affect the execution of pre-4.5 code; it is a necessary element for asynchronous execution of the `target` region when using the new `nowait` clause introduced in OpenMP 4.5. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end--- " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Chap_memory_model.ipynb b/notebook/Chap_memory_model.ipynb index 58fda05..81e662f 100644 --- a/notebook/Chap_memory_model.ipynb +++ b/notebook/Chap_memory_model.ipynb @@ -1,52 +1,52 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ## Memory Model " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ## Memory Model " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In this chapter, examples illustrate race conditions on access to variables with shared data-sharing attributes. A race condition can exist when two or more threads are involved in accessing a variable in which not all of the accesses are reads; that is, a WaR, RaW or WaW condition exists (R=read, a=after, W=write). A RaR does not produce a race condition. Ensuring thread execution order at the processor level is not enough to avoid race conditions, because the local storage at the processor level (registers, caches, etc.) must be synchronized so that a consistent view of the variable in the memory hierarchy can be seen by the threads accessing the variable. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In this chapter, examples illustrate race conditions on access to variables with shared data-sharing attributes. A race condition can exist when two or more threads are involved in accessing a variable in which not all of the accesses are reads; that is, a WaR, RaW or WaW condition exists (R=read, a=after, W=write). A RaR does not produce a race condition. Ensuring thread execution order at the processor level is not enough to avoid race conditions, because the local storage at the processor level (registers, caches, etc.) must be synchronized so that a consistent view of the variable in the memory hierarchy can be seen by the threads accessing the variable. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " OpenMP provides a shared-memory model which allows all threads access to _memory_ (shared data). Each thread also has exclusive access to _threadprivate memory_ (private data). A private variable referenced in an OpenMP directive's structured block is a new version of the original variable (with the same name) for each task (or SIMD lane) within the code block. A private variable is initially undefined (except for variables in `firstprivate` and `linear` clauses), and the original variable value is unaltered by assignments to the private variable, (except for `reduction` , `lastprivate` and `linear` clauses). " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " OpenMP provides a shared-memory model which allows all threads access to _memory_ (shared data). Each thread also has exclusive access to _threadprivate memory_ (private data). A private variable referenced in an OpenMP directive's structured block is a new version of the original variable (with the same name) for each task (or SIMD lane) within the code block. A private variable is initially undefined (except for variables in `firstprivate` and `linear` clauses), and the original variable value is unaltered by assignments to the private variable, (except for `reduction` , `lastprivate` and `linear` clauses). " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Private variables in an outer `parallel` region can be shared by implicit tasks of an inner `parallel` region (with a `share` clause on the inner `parallel` directive). Likewise, a private variable may be shared in the region of an explicit `task` (through a `shared` clause). " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Private variables in an outer `parallel` region can be shared by implicit tasks of an inner `parallel` region (with a `share` clause on the inner `parallel` directive). Likewise, a private variable may be shared in the region of an explicit `task` (through a `shared` clause). " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `flush` directive forces a consistent view of local variables of the thread executing the `flush` . When a list is supplied on the directive, only the items (variables) in the list are guaranteed to be flushed. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `flush` directive forces a consistent view of local variables of the thread executing the `flush` . When a list is supplied on the directive, only the items (variables) in the list are guaranteed to be flushed. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Implied flushes exist at prescribed locations of certain constructs. For the complete list of these locations and associated constructs, please refer to the _flush Construct_ section of the OpenMP Specifications document. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Implied flushes exist at prescribed locations of certain constructs. For the complete list of these locations and associated constructs, please refer to the _flush Construct_ section of the OpenMP Specifications document. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", " The following table lists construct in which implied flushes exist, and the \n", " location of their execution. \n", " \n", @@ -114,18 +114,18 @@ " in _atomic Construct_ subsection of the OpenMP Specifications document). " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Examples 1-3 show the difficulty of synchronizing threads through `flush` and `atomic` directives. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Examples 1-3 show the difficulty of synchronizing threads through `flush` and `atomic` directives. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end--- " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Chap_parallel_execution.ipynb b/notebook/Chap_parallel_execution.ipynb index 29a7827..bd15050 100644 --- a/notebook/Chap_parallel_execution.ipynb +++ b/notebook/Chap_parallel_execution.ipynb @@ -1,150 +1,150 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ## Parallel Execution " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ## Parallel Execution " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " A single thread, the _initial thread_ , begins sequential execution of an OpenMP enabled program, as if the whole program is in an implicit parallel region consisting of an implicit task executed by the _initial thread_ . " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " A single thread, the _initial thread_ , begins sequential execution of an OpenMP enabled program, as if the whole program is in an implicit parallel region consisting of an implicit task executed by the _initial thread_ . " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " A `parallel` construct encloses code, forming a parallel region. An _initial thread_ encountering a `parallel` region forks (creates) a team of threads at the beginning of the `parallel` region, and joins them (removes from execution) at the end of the region. The initial thread becomes the master thread of the team in a `parallel` region with a _thread_ number equal to zero, the other threads are numbered from 1 to number of threads minus 1. A team may be comprised of just a single thread. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " A `parallel` construct encloses code, forming a parallel region. An _initial thread_ encountering a `parallel` region forks (creates) a team of threads at the beginning of the `parallel` region, and joins them (removes from execution) at the end of the region. The initial thread becomes the master thread of the team in a `parallel` region with a _thread_ number equal to zero, the other threads are numbered from 1 to number of threads minus 1. A team may be comprised of just a single thread. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Each thread of a team is assigned an implicit task consisting of code within the parallel region. The task that creates a parallel region is suspended while the tasks of the team are executed. A thread is tied to its task; that is, only the thread assigned to the task can execute that task. After completion of the `parallel` region, the master thread resumes execution of the generating task. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Each thread of a team is assigned an implicit task consisting of code within the parallel region. The task that creates a parallel region is suspended while the tasks of the team are executed. A thread is tied to its task; that is, only the thread assigned to the task can execute that task. After completion of the `parallel` region, the master thread resumes execution of the generating task. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", "After the `parallel` region the master thread becomes the initial \n", "thread again, and continues to execute the _sequential part_ . " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Any task within a `parallel` region is allowed to encounter another `parallel` region to form a nested `parallel` region. The parallelism of a nested `parallel` region (whether it forks additional threads, or is executed serially by the encountering task) can be controlled by the `OMP_NESTED` environment variable or the `omp_set_nested()` API routine with arguments indicating true or false. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Any task within a `parallel` region is allowed to encounter another `parallel` region to form a nested `parallel` region. The parallelism of a nested `parallel` region (whether it forks additional threads, or is executed serially by the encountering task) can be controlled by the `OMP_NESTED` environment variable or the `omp_set_nested()` API routine with arguments indicating true or false. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The number of threads of a `parallel` region can be set by the `OMP_NUM_THREADS` environment variable, the `omp_set_num_threads()` routine, or on the `parallel` directive with the `num_threads` clause. The routine overrides the environment variable, and the clause overrides all. Use the `OMP_DYNAMIC` or the `omp_set_dynamic()` function to specify that the OpenMP implementation dynamically adjust the number of threads for `parallel` regions. The default setting for dynamic adjustment is implementation defined. When dynamic adjustment is on and the number of threads is specified, the number of threads becomes an upper limit for the number of threads to be provided by the OpenMP runtime. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The number of threads of a `parallel` region can be set by the `OMP_NUM_THREADS` environment variable, the `omp_set_num_threads()` routine, or on the `parallel` directive with the `num_threads` clause. The routine overrides the environment variable, and the clause overrides all. Use the `OMP_DYNAMIC` or the `omp_set_dynamic()` function to specify that the OpenMP implementation dynamically adjust the number of threads for `parallel` regions. The default setting for dynamic adjustment is implementation defined. When dynamic adjustment is on and the number of threads is specified, the number of threads becomes an upper limit for the number of threads to be provided by the OpenMP runtime. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " WORKSHARING CONSTRUCTS " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " WORKSHARING CONSTRUCTS " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " A worksharing construct distributes the execution of the associated region among the members of the team that encounter it. There is an implied barrier at the end of the worksharing region (there is no barrier at the beginning). The worksharing constructs are: " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " A worksharing construct distributes the execution of the associated region among the members of the team that encounter it. There is an implied barrier at the end of the worksharing region (there is no barrier at the beginning). The worksharing constructs are: " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", "* loop constructs: { `for` and `do` } \n", "* `sections` \n", "* `single` \n", "* `workshare` " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `for` and `do` constructs (loop constructs) create a region consisting of a loop. A loop controlled by a loop construct is called an _associated_ loop. Nested loops can form a single region when the `collapse` clause (with an integer argument) designates the number of _associated_ loops to be executed in parallel, by forming a 'single iteration space' for the specified number of nested loops. The `ordered` clause can also control multiple associated loops. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `for` and `do` constructs (loop constructs) create a region consisting of a loop. A loop controlled by a loop construct is called an _associated_ loop. Nested loops can form a single region when the `collapse` clause (with an integer argument) designates the number of _associated_ loops to be executed in parallel, by forming a 'single iteration space' for the specified number of nested loops. The `ordered` clause can also control multiple associated loops. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " An associated loop must adhere to a 'canonical form' (specified in the _Canonical Loop Form_ of the OpenMP Specifications document) which allows the iteration count (of all associated loops) to be computed before the (outermost) loop is executed. \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " An associated loop must adhere to a 'canonical form' (specified in the _Canonical Loop Form_ of the OpenMP Specifications document) which allows the iteration count (of all associated loops) to be computed before the (outermost) loop is executed. \n", "[58:27-29]. Most common loops comply with the canonical form, including C++ iterators. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " A `single` construct forms a region in which only one thread (any one of the team) executes the region. The other threads wait at the implied barrier at the end, unless the `nowait` clause is specified. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " A `single` construct forms a region in which only one thread (any one of the team) executes the region. The other threads wait at the implied barrier at the end, unless the `nowait` clause is specified. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `sections` construct forms a region that contains one or more structured blocks. Each block of a `sections` directive is constructed with a `section` construct, and executed once by one of the threads (any one) in the team. (If only one block is formed in the region, the `section` construct, which is used to separate blocks, is not required.) The other threads wait at the implied barrier at the end, unless the `nowait` clause is specified. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `sections` construct forms a region that contains one or more structured blocks. Each block of a `sections` directive is constructed with a `section` construct, and executed once by one of the threads (any one) in the team. (If only one block is formed in the region, the `section` construct, which is used to separate blocks, is not required.) The other threads wait at the implied barrier at the end, unless the `nowait` clause is specified. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `workshare` construct is a Fortran feature that consists of a region with a single structure block (section of code). Statements in the `workshare` region are divided into units of work, and executed (once) by threads of the team. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `workshare` construct is a Fortran feature that consists of a region with a single structure block (section of code). Statements in the `workshare` region are divided into units of work, and executed (once) by threads of the team. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " bigskip MASTER CONSTRUCT " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " bigskip MASTER CONSTRUCT " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `master` construct is not a worksharing construct. The master region is is executed only by the master thread. There is no implicit barrier (and flush) at the end of the `master` region; hence the other threads of the team continue execution beyond code statements beyond the `master` region. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `master` construct is not a worksharing construct. The master region is is executed only by the master thread. There is no implicit barrier (and flush) at the end of the `master` region; hence the other threads of the team continue execution beyond code statements beyond the `master` region. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end--- " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Chap_program_control.ipynb b/notebook/Chap_program_control.ipynb index 0d89d7a..803704d 100644 --- a/notebook/Chap_program_control.ipynb +++ b/notebook/Chap_program_control.ipynb @@ -1,73 +1,73 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ## Program Control " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ## Program Control " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Some specific and elementary concepts of controlling program execution are illustrated in the examples of this chapter. Control can be directly managed with conditional control code (ifdef's with the `_OPENMP` macro, and the Fortran sentinel ( `!$` ) for conditionally compiling). The `if` clause on some constructs can direct the runtime to ignore or alter the behavior of the construct. Of course, the base-language `if` statements can be used to control the 'execution' of stand-alone directives (such as `flush` , `barrier` , `taskwait` , and `taskyield` ). However, the directives must appear in a block structure, and not as a substatement as shown in examples 1 and 2 of this chapter. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Some specific and elementary concepts of controlling program execution are illustrated in the examples of this chapter. Control can be directly managed with conditional control code (ifdef's with the `_OPENMP` macro, and the Fortran sentinel ( `!$` ) for conditionally compiling). The `if` clause on some constructs can direct the runtime to ignore or alter the behavior of the construct. Of course, the base-language `if` statements can be used to control the 'execution' of stand-alone directives (such as `flush` , `barrier` , `taskwait` , and `taskyield` ). However, the directives must appear in a block structure, and not as a substatement as shown in examples 1 and 2 of this chapter. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " bigskip CANCELLATION " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " bigskip CANCELLATION " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Cancellation (termination) of the normal sequence of execution for the threads in an OpenMP region can be accomplished with the `cancel` construct. The construct uses a _construct-type-clause_ to set the region-type to activate for the cancellation. That is, inclusion of one of the _construct-type-clause_ names `parallel` , `for` , `do` , `sections` or `taskgroup` on the directive line activates the corresponding region. The `cancel` construct is activated by the first encountering thread, and it continues execution at the end of the named region. The `cancel` construct is also a concellation point for any other thread of the team to also continue execution at the end of the named region. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Cancellation (termination) of the normal sequence of execution for the threads in an OpenMP region can be accomplished with the `cancel` construct. The construct uses a _construct-type-clause_ to set the region-type to activate for the cancellation. That is, inclusion of one of the _construct-type-clause_ names `parallel` , `for` , `do` , `sections` or `taskgroup` on the directive line activates the corresponding region. The `cancel` construct is activated by the first encountering thread, and it continues execution at the end of the named region. The `cancel` construct is also a concellation point for any other thread of the team to also continue execution at the end of the named region. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Also, once the specified region has been activated for cancellation any thread that encounnters a `cancellation point` construct with the same named region ( _construct-type-clause_ ), continues execution at the end of the region. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Also, once the specified region has been activated for cancellation any thread that encounnters a `cancellation point` construct with the same named region ( _construct-type-clause_ ), continues execution at the end of the region. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " For an activated `cancel taskgroup` construct, the tasks that belong to the taskgroup set of the innermost enclosing taskgroup region will be canceled. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " For an activated `cancel taskgroup` construct, the tasks that belong to the taskgroup set of the innermost enclosing taskgroup region will be canceled. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " A task that encounters the cancel taskgroup construct continues execution at the end of its task region. Any task of the taskgroup that has already begun execution will run to completion, unless it encounters a `cancellation point` ; tasks that have not begun execution 'may' be discarded as completed tasks. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " A task that encounters the cancel taskgroup construct continues execution at the end of its task region. Any task of the taskgroup that has already begun execution will run to completion, unless it encounters a `cancellation point` ; tasks that have not begun execution 'may' be discarded as completed tasks. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " bigskip CONTROL VARIABLES " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " bigskip CONTROL VARIABLES " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Internal control variables (ICV) are used by implementations to hold values which control the execution of OpenMP regions. Control (and hence the ICVs) may be set as implementation defaults, or set and adjusted through environment variables, clauses, and API functions. Many of the ICV control values are accessible through API function calls. Also, initial ICV values are reported by the runtime if the `OMP_DISPLAY_ENV` environment variable has been set to `TRUE` . " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Internal control variables (ICV) are used by implementations to hold values which control the execution of OpenMP regions. Control (and hence the ICVs) may be set as implementation defaults, or set and adjusted through environment variables, clauses, and API functions. Many of the ICV control values are accessible through API function calls. Also, initial ICV values are reported by the runtime if the `OMP_DISPLAY_ENV` environment variable has been set to `TRUE` . " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", "As an example, the _nthreads-var_ is the ICV that holds the number of threads \n", "to be used in a `parallel` region. It can be set with the `OMP_NUM_THREADS` environment variable, \n", "the `omp_set_num_threads()` API function, or the `num_threads` clause. The default _nthreads-var_ \n", @@ -77,27 +77,27 @@ "extent of the control. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " bigskip NESTED CONSTRUCTS " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " bigskip NESTED CONSTRUCTS " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Certain combinations of nested constructs are permitted, giving rise to a _combined_ construct consisting of two or more constructs. These can be used when the two (or several) constructs would be used immediately in succession (closely nested). A combined construct can use the clauses of the component constructs without restrictions. A _composite_ construct is a combined construct which has one or more clauses with (an often obviously) modified or restricted meaning, relative to when the constructs are uncombined. \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Certain combinations of nested constructs are permitted, giving rise to a _combined_ construct consisting of two or more constructs. These can be used when the two (or several) constructs would be used immediately in succession (closely nested). A combined construct can use the clauses of the component constructs without restrictions. A _composite_ construct is a combined construct which has one or more clauses with (an often obviously) modified or restricted meaning, relative to when the constructs are uncombined. \n", "\n", "[appear separately (singly). " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", "The combined `parallel do` and `parallel for` constructs are formed by combining the `parallel` \n", "construct with one of the loops constructs `do` or `for` . The \n", " `parallel do SIMD` and `parallel for SIMD` constructs are composite constructs (composed from \n", @@ -105,32 +105,32 @@ "explicitly address the ordering of loop chunking _and_ SIMD 'combined' execution. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Certain nestings are forbidden, and often the reasoning is obvious. Worksharing constructs cannot be nested, and the `barrier` construct cannot be nested inside a worksharing construct, or a `critical` construct. Also, `target` constructs cannot be nested. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Certain nestings are forbidden, and often the reasoning is obvious. Worksharing constructs cannot be nested, and the `barrier` construct cannot be nested inside a worksharing construct, or a `critical` construct. Also, `target` constructs cannot be nested. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `parallel` construct can be nested, as well as the `task` construct. The parallel execution in the nested `parallel` construct(s) is control by the `OMP_NESTED` and `OMP_MAX_ACTIVE_LEVELS` environment variables, and the `omp_set_nested()` and `omp_set_max_active_levels()` functions. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `parallel` construct can be nested, as well as the `task` construct. The parallel execution in the nested `parallel` construct(s) is control by the `OMP_NESTED` and `OMP_MAX_ACTIVE_LEVELS` environment variables, and the `omp_set_nested()` and `omp_set_max_active_levels()` functions. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " More details on nesting can be found in the _Nesting of Regions_ of the _Directives_ chapter in the OpenMP Specifications document. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " More details on nesting can be found in the _Nesting of Regions_ of the _Directives_ chapter in the OpenMP Specifications document. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end--- " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Chap_synchronization.ipynb b/notebook/Chap_synchronization.ipynb index 0c919ac..56cc212 100644 --- a/notebook/Chap_synchronization.ipynb +++ b/notebook/Chap_synchronization.ipynb @@ -1,75 +1,75 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ## Synchronization " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ## Synchronization " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `barrier` construct is a stand-alone directive that requires all threads of a team (within a contention group) to execute the barrier and complete execution of all tasks within the region, before continuing past the barrier. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `barrier` construct is a stand-alone directive that requires all threads of a team (within a contention group) to execute the barrier and complete execution of all tasks within the region, before continuing past the barrier. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `critical` construct is a directive that contains a structured block. The construct allows only a single thread at a time to execute the structured block (region). Multiple critical regions may exist in a parallel region, and may act cooperatively (only one thread at a time in all `critical` regions), or separately (only one thread at a time in each `critical` regions when a unique name is supplied on each `critical` construct). An optional (lock) `hint` clause may be specified on a named `critical` construct to provide the OpenMP runtime guidance in selection a locking mechanism. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `critical` construct is a directive that contains a structured block. The construct allows only a single thread at a time to execute the structured block (region). Multiple critical regions may exist in a parallel region, and may act cooperatively (only one thread at a time in all `critical` regions), or separately (only one thread at a time in each `critical` regions when a unique name is supplied on each `critical` construct). An optional (lock) `hint` clause may be specified on a named `critical` construct to provide the OpenMP runtime guidance in selection a locking mechanism. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " On a finer scale the `atomic` construct allows only a single thread at a time to have atomic access to a storage location involving a single read, write, update or capture statement, and a limited number of combinations when specifying the `capture` _atomic-clause_ clause. The _atomic-clause_ clause is required for some expression statements, but are not required for `update` statements. Please see the details in the _atomic Construct_ subsection of the _Directives_ chapter in the OpenMP Specifications document. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " On a finer scale the `atomic` construct allows only a single thread at a time to have atomic access to a storage location involving a single read, write, update or capture statement, and a limited number of combinations when specifying the `capture` _atomic-clause_ clause. The _atomic-clause_ clause is required for some expression statements, but are not required for `update` statements. Please see the details in the _atomic Construct_ subsection of the _Directives_ chapter in the OpenMP Specifications document. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", " The following three sentences were stolen from the spec. The `ordered` construct either specifies a structured block in a loop, simd, or loop SIMD region that will be executed in the order of the loop iterations. The ordered construct sequentializes and orders the execution of ordered regions while allowing code outside the region to run in parallel. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Since OpenMP 4.5 the `ordered` construct can also be a stand-alone directive that specifies cross-iteration dependences in a doacross loop nest. The `depend` clause uses a `sink` _dependence-type_ , along with a iteration vector argument (vec) to indicate the iteration that satisfies the dependence. The `depend` clause with a `source` _dependence-type_ specifies dependence satisfaction. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Since OpenMP 4.5 the `ordered` construct can also be a stand-alone directive that specifies cross-iteration dependences in a doacross loop nest. The `depend` clause uses a `sink` _dependence-type_ , along with a iteration vector argument (vec) to indicate the iteration that satisfies the dependence. The `depend` clause with a `source` _dependence-type_ specifies dependence satisfaction. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `flush` directive is a stand-alone construct that forces a thread's temporal local storage (view) of a variable to memory where a consistent view of the variable storage can be accesses. When the construct is used without a variable list, all the locally thread-visible data as defined by the base language are flushed. A construct with a list applies the flush operation only to the items in the list. The `flush` construct also effectively insures that no memory (load or store) operation for the variable set (list items, or default set) may be reordered across the `flush` directive. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `flush` directive is a stand-alone construct that forces a thread's temporal local storage (view) of a variable to memory where a consistent view of the variable storage can be accesses. When the construct is used without a variable list, all the locally thread-visible data as defined by the base language are flushed. A construct with a list applies the flush operation only to the items in the list. The `flush` construct also effectively insures that no memory (load or store) operation for the variable set (list items, or default set) may be reordered across the `flush` directive. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " General-purpose routines provide mutual exclusion semantics through locks, represented by lock variables. The semantics allows a task to _set_ , and hence _own_ a lock, until it is _unset_ by the task that set it. A _nestable_ lock can be set multiple times by a task, and is used when in code requires nested control of locks. A _simple lock_ can only be set once by the owning task. There are specific calls for the two types of locks, and the variable of a specific lock type cannot be used by the other lock type. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " General-purpose routines provide mutual exclusion semantics through locks, represented by lock variables. The semantics allows a task to _set_ , and hence _own_ a lock, until it is _unset_ by the task that set it. A _nestable_ lock can be set multiple times by a task, and is used when in code requires nested control of locks. A _simple lock_ can only be set once by the owning task. There are specific calls for the two types of locks, and the variable of a specific lock type cannot be used by the other lock type. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Any explicit task will observe the synchronization prescribed in a `barrier` construct and an implied barrier. Also, additional synchronizations are available for tasks. All children of a task will wait at a `taskwait` (for their siblings to complete). A `taskgroup` construct creates a region in which the current task is suspended at the end of the region until all sibling tasks, and their descendants, have completed. Scheduling constraints on task execution can be prescribed by the `depend` clause to enforce dependence on previously generated tasks. More details on controlling task executions can be found in the _Tasking_ Chapter in the OpenMP Specifications document. \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Any explicit task will observe the synchronization prescribed in a `barrier` construct and an implied barrier. Also, additional synchronizations are available for tasks. All children of a task will wait at a `taskwait` (for their siblings to complete). A `taskgroup` construct creates a region in which the current task is suspended at the end of the region until all sibling tasks, and their descendants, have completed. Scheduling constraints on task execution can be prescribed by the `depend` clause to enforce dependence on previously generated tasks. More details on controlling task executions can be found in the _Tasking_ Chapter in the OpenMP Specifications document. \n", "(DO REF. RIGHT.) " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end--- " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Chap_tasking.ipynb b/notebook/Chap_tasking.ipynb index 22c1f6e..bdfd1f1 100644 --- a/notebook/Chap_tasking.ipynb +++ b/notebook/Chap_tasking.ipynb @@ -1,60 +1,60 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ## Tasking " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ## Tasking " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Tasking constructs provide units of work to a thread for execution. Worksharing constructs do this, too (e.g. `for` , `do` , `sections` , and `singles` constructs); but the work units are tightly controlled by an iteration limit and limited scheduling, or a limited number of `sections` or `single` regions. Worksharing was designed with ' data parallel ' computing in mind. Tasking was designed for ' task parallel ' computing and often involves non-locality or irregularity in memory access. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Tasking constructs provide units of work to a thread for execution. Worksharing constructs do this, too (e.g. `for` , `do` , `sections` , and `singles` constructs); but the work units are tightly controlled by an iteration limit and limited scheduling, or a limited number of `sections` or `single` regions. Worksharing was designed with ' data parallel ' computing in mind. Tasking was designed for ' task parallel ' computing and often involves non-locality or irregularity in memory access. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `task` construct can be used to execute work chunks: in a while loop; while traversing nodes in a list; at nodes in a tree graph; or in a normal loop (with a `taskloop` construct). Unlike the statically scheduled loop iterations of worksharing, a task is often enqueued, and then dequeued for execution by any of the threads of the team within a parallel region. The generation of tasks can be from a single generating thread (creating sibling tasks), or from multiple generators in a recursive graph tree traversals. \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `task` construct can be used to execute work chunks: in a while loop; while traversing nodes in a list; at nodes in a tree graph; or in a normal loop (with a `taskloop` construct). Unlike the statically scheduled loop iterations of worksharing, a task is often enqueued, and then dequeued for execution by any of the threads of the team within a parallel region. The generation of tasks can be from a single generating thread (creating sibling tasks), or from multiple generators in a recursive graph tree traversals. \n", "(creating a parent-descendents hierarchy of tasks, see example 4 and 7 below). A `taskloop` construct bundles iterations of an associated loop into tasks, and provides similar controls found in the `task` construct. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Sibling tasks are synchronized by the `taskwait` construct, and tasks and their descendent tasks can be synchronized by containing them in a `taskgroup` region. Ordered execution is accomplished by specifying dependences with a `depend` clause. Also, priorities can be specified as hints to the scheduler through a `priority` clause. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Sibling tasks are synchronized by the `taskwait` construct, and tasks and their descendent tasks can be synchronized by containing them in a `taskgroup` region. Ordered execution is accomplished by specifying dependences with a `depend` clause. Also, priorities can be specified as hints to the scheduler through a `priority` clause. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Various clauses can be used to manage and optimize task generation, as well as reduce the overhead of execution and to relinquish control of threads for work balance and forward progress. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Various clauses can be used to manage and optimize task generation, as well as reduce the overhead of execution and to relinquish control of threads for work balance and forward progress. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Once a thread starts executing a task, it is the designated thread for executing the task to completion, even though it may leave the execution at a scheduling point and return later. The thread is tied to the task. Scheduling points can be introduced with the `taskyield` construct. With an `untied` clause any other thread is allowed to continue the task. An `if` clause with a _true_ expression allows the generating thread to immediately execute the task as an undeferred task. By including the data environment of the generating task into the generated task with the `mergeable` and `final` clauses, task generation overhead can be reduced. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Once a thread starts executing a task, it is the designated thread for executing the task to completion, even though it may leave the execution at a scheduling point and return later. The thread is tied to the task. Scheduling points can be introduced with the `taskyield` construct. With an `untied` clause any other thread is allowed to continue the task. An `if` clause with a _true_ expression allows the generating thread to immediately execute the task as an undeferred task. By including the data environment of the generating task into the generated task with the `mergeable` and `final` clauses, task generation overhead can be reduced. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " A complete list of the tasking constructs and details of their clauses can be found in the _Tasking Constructs_ chapter of the OpenMP Specifications, in the _OpenMP Application Programming Interface_ section. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " A complete list of the tasking constructs and details of their clauses can be found in the _Tasking Constructs_ chapter of the OpenMP Specifications, in the _OpenMP Application Programming Interface_ section. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end--- " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_Chapt.ipynb b/notebook/Examples_Chapt.ipynb index cf5ad42..c493b38 100644 --- a/notebook/Examples_Chapt.ipynb +++ b/notebook/Examples_Chapt.ipynb @@ -1,35 +1,35 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "chapter*{Examples} " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "chapter*{Examples} " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " addcontentsline{toc}{chapter}{protectnumberline{}Examples} The following are examples of the OpenMP API directives, constructs, and routines. ccppspecificstart A statement following a directive is compound only when necessary, and a non-compound statement is indented with respect to a directive preceding it. ccppspecificend " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " addcontentsline{toc}{chapter}{protectnumberline{}Examples} The following are examples of the OpenMP API directives, constructs, and routines. ccppspecificstart A statement following a directive is compound only when necessary, and a non-compound statement is indented with respect to a directive preceding it. ccppspecificend " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Each example is labeled as _ename.seqno.ext_ , where _ename_ is the example name, _seqno_ is the sequence number in a section, and _ext_ is the source file extension to indicate the code type and source form. _ext_ is one of the following: \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Each example is labeled as _ename.seqno.ext_ , where _ename_ is the example name, _seqno_ is the sequence number in a section, and _ext_ is the source file extension to indicate the code type and source form. _ext_ is one of the following: \n", "* _c_ -- C code, \n", "* _cpp_ -- C++ code, \n", "* _f_ -- Fortran code in fixed form, and \n", "* _f90_ -- Fortran code in free form. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end--- " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_SIMD.ipynb b/notebook/Examples_SIMD.ipynb index e930057..14fc55a 100644 --- a/notebook/Examples_SIMD.ipynb +++ b/notebook/Examples_SIMD.ipynb @@ -1,273 +1,273 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", " ### `simd` and `declare` `simd` Constructs " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example illustrates the basic use of the `simd` construct to assure the compiler that the loop can be vectorized. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example illustrates the basic use of the `simd` construct to assure the compiler that the loop can be vectorized. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_SIMD.1.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_SIMD.1.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_SIMD.1.f90 " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_SIMD.1.f90 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " When a function can be inlined within a loop the compiler has an opportunity to vectorize the loop. By guaranteeing SIMD behavior of a function's operations, characterizing the arguments of the function and privatizing temporary variables of the loop, the compiler can often create faster, vector code for the loop. In the examples below the `declare` `simd` construct is used on the _add1_ and _add2_ functions to enable creation of their corresponding SIMD function versions for execution within the associated SIMD loop. The functions characterize two different approaches of accessing data within the function: by a single variable and as an element in a data array, respectively. The _add3_ C function uses dereferencing. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " When a function can be inlined within a loop the compiler has an opportunity to vectorize the loop. By guaranteeing SIMD behavior of a function's operations, characterizing the arguments of the function and privatizing temporary variables of the loop, the compiler can often create faster, vector code for the loop. In the examples below the `declare` `simd` construct is used on the _add1_ and _add2_ functions to enable creation of their corresponding SIMD function versions for execution within the associated SIMD loop. The functions characterize two different approaches of accessing data within the function: by a single variable and as an element in a data array, respectively. The _add3_ C function uses dereferencing. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `declare` `simd` constructs also illustrate the use of `uniform` and `linear` clauses. The `uniform(fact)` clause indicates that the variable _fact_ is invariant across the SIMD lanes. In the _add2_ function _a_ and _b_ are included in the `unform` list because the C pointer and the Fortran array references are constant. The _i_ index used in the _add2_ function is included in a `linear` clause with a constant-linear-step of 1, to guarantee a unity increment of the associated loop. In the `declare` `simd` construct for the _add3_ C function the `linear(a,b:1)` clause instructs the compiler to generate unit-stride loads across the SIMD lanes; otherwise, costly emph{gather} instructions would be generated for the unknown sequence of access of the pointer dereferences. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `declare` `simd` constructs also illustrate the use of `uniform` and `linear` clauses. The `uniform(fact)` clause indicates that the variable _fact_ is invariant across the SIMD lanes. In the _add2_ function _a_ and _b_ are included in the `unform` list because the C pointer and the Fortran array references are constant. The _i_ index used in the _add2_ function is included in a `linear` clause with a constant-linear-step of 1, to guarantee a unity increment of the associated loop. In the `declare` `simd` construct for the _add3_ C function the `linear(a,b:1)` clause instructs the compiler to generate unit-stride loads across the SIMD lanes; otherwise, costly emph{gather} instructions would be generated for the unknown sequence of access of the pointer dereferences. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the `simd` constructs for the loops the `private(tmp)` clause is necessary to assure that the each vector operation has its own _tmp_ variable. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the `simd` constructs for the loops the `private(tmp)` clause is necessary to assure that the each vector operation has its own _tmp_ variable. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_SIMD.2.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_SIMD.2.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_SIMD.2.f90 " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_SIMD.2.f90 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " A thread that encounters a SIMD construct executes a vectorized code of the iterations. Similar to the concerns of a worksharing loop a loop vectorized with a SIMD construct must assure that temporary and reduction variables are privatized and declared as reductions with clauses. The example below illustrates the use of `private` and `reduction` clauses in a SIMD construct. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " A thread that encounters a SIMD construct executes a vectorized code of the iterations. Similar to the concerns of a worksharing loop a loop vectorized with a SIMD construct must assure that temporary and reduction variables are privatized and declared as reductions with clauses. The example below illustrates the use of `private` and `reduction` clauses in a SIMD construct. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_SIMD.3.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_SIMD.3.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_SIMD.3.f90 " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_SIMD.3.f90 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " A `safelen(N)` clause in a `simd` construct assures the compiler that there are no loop-carried dependencies for vectors of size _N_ or below. If the `safelen` clause is not specified, then the default safelen value is the number of loop iterations. The `safelen(16)` clause in the example below guarantees that the vector code is safe for vectors up to and including size 16. In the loop, _m_ can be 16 or greater, for correct code execution. If the value of _m_ is less than 16, the behavior is undefined. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_SIMD.4.c " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_SIMD.4.f90 " - ] + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " A `safelen(N)` clause in a `simd` construct assures the compiler that there are no loop-carried dependencies for vectors of size _N_ or below. If the `safelen` clause is not specified, then the default safelen value is the number of loop iterations. The `safelen(16)` clause in the example below guarantees that the vector code is safe for vectors up to and including size 16. In the loop, _m_ can be 16 or greater, for correct code execution. If the value of _m_ is less than 16, the behavior is undefined. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_SIMD.4.c " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_SIMD.4.f90 " + ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following SIMD construct instructs the compiler to collapse the _i_ and _j_ loops into a single SIMD loop in which SIMD chunks are executed by threads of the team. Within the workshared loop chunks of a thread, the SIMD chunks are executed in the lanes of the vector units. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_SIMD.5.c " - ] + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following SIMD construct instructs the compiler to collapse the _i_ and _j_ loops into a single SIMD loop in which SIMD chunks are executed by threads of the team. Within the workshared loop chunks of a thread, the SIMD chunks are executed in the lanes of the vector units. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_SIMD.5.c " + ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_SIMD.5.f90 " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_SIMD.5.f90 " ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", "\n", "\n", " section ### `inbranch` and `notinbranch` Clauses " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following examples illustrate the use of the `declare` `simd` construct with the `inbranch` and `notinbranch` clauses. The `notinbranch` clause informs the compiler that the function _foo_ is never called conditionally in the SIMD loop of the function _myaddint_ . On the other hand, the `inbranch` clause for the function goo indicates that the function is always called conditionally in the SIMD loop inside the function _myaddfloat_ . " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following examples illustrate the use of the `declare` `simd` construct with the `inbranch` and `notinbranch` clauses. The `notinbranch` clause informs the compiler that the function _foo_ is never called conditionally in the SIMD loop of the function _myaddint_ . On the other hand, the `inbranch` clause for the function goo indicates that the function is always called conditionally in the SIMD loop inside the function _myaddfloat_ . " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_SIMD.6.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_SIMD.6.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_SIMD.6.f90 " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_SIMD.6.f90 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the code below, the function _fib()_ is called in the main program and also recursively called in the function _fib()_ within an `if` condition. The compiler creates a masked vector version and a non-masked vector version for the function _fib()_ while retaining the original scalar version of the _fib()_ function. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the code below, the function _fib()_ is called in the main program and also recursively called in the function _fib()_ within an `if` condition. The compiler creates a masked vector version and a non-masked vector version for the function _fib()_ while retaining the original scalar version of the _fib()_ function. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_SIMD.7.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_SIMD.7.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_SIMD.7.f90 " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_SIMD.7.f90 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", "\n", "\n", " section ### Loop-Carried Lexical Forward Dependence " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example tests the restriction on an SIMD loop with the loop-carried lexical forward-dependence. This dependence must be preserved for the correct execution of SIMD loops. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example tests the restriction on an SIMD loop with the loop-carried lexical forward-dependence. This dependence must be preserved for the correct execution of SIMD loops. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " A loop can be vectorized even though the iterations are not completely independent when it has loop-carried dependences that are forward lexical dependences, indicated in the code below by the read of _A[j+1]_ and the write to _A[j]_ in C/C++ code (or _A(j+1)_ and _A(j)_ in Fortran). That is, the read of _A[j+1]_ (or _A(j+1)_ in Fortran) before the write to _A[j]_ (or _A(j)_ in Fortran) ordering must be preserved for each iteration in _j_ for valid SIMD code generation. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " A loop can be vectorized even though the iterations are not completely independent when it has loop-carried dependences that are forward lexical dependences, indicated in the code below by the read of _A[j+1]_ and the write to _A[j]_ in C/C++ code (or _A(j+1)_ and _A(j)_ in Fortran). That is, the read of _A[j+1]_ (or _A(j+1)_ in Fortran) before the write to _A[j]_ (or _A(j)_ in Fortran) ordering must be preserved for each iteration in _j_ for valid SIMD code generation. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " This test assures that the compiler preserves the loop carried lexical forward-dependence for generating a correct SIMD code. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " This test assures that the compiler preserves the loop carried lexical forward-dependence for generating a correct SIMD code. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_SIMD.8.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_SIMD.8.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_SIMD.8.f90 " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_SIMD.8.f90 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end--- " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_affinity.ipynb b/notebook/Examples_affinity.ipynb index 9353da4..d6b97a0 100644 --- a/notebook/Examples_affinity.ipynb +++ b/notebook/Examples_affinity.ipynb @@ -1,690 +1,690 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### The `proc_bind` Clause " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### The `proc_bind` Clause " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following examples demonstrate how to use the `proc_bind` clause to control the thread binding for a team of threads in a `parallel` region. The machine architecture is depicted in the figure below. It consists of two sockets, each equipped with a quad-core processor and configured to execute two hardware threads simultaneously on each core. These examples assume a contiguous core numbering starting from 0, such that the hardware threads 0,1 form the first physical core. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following examples demonstrate how to use the `proc_bind` clause to control the thread binding for a team of threads in a `parallel` region. The machine architecture is depicted in the figure below. It consists of two sockets, each equipped with a quad-core processor and configured to execute two hardware threads simultaneously on each core. These examples assume a contiguous core numbering starting from 0, such that the hardware threads 0,1 form the first physical core. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " {figs/proc_bind_fig.pdf}} \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " {figs/proc_bind_fig.pdf}} \n", " fi " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following equivalent place list declarations consist of eight places (which we designate as p0 to p7): " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following equivalent place list declarations consist of eight places (which we designate as p0 to p7): " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " `OMP_PLACES= ' {0,1},{2,3},{4,5},{6,7},{8,9},{10,11},{12,13},{14,15} ' ` " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " `OMP_PLACES= ' {0,1},{2,3},{4,5},{6,7},{8,9},{10,11},{12,13},{14,15} ' ` " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " or " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " or " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " `OMP_PLACES= ' {0:2}:8:2 ' ` " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " `OMP_PLACES= ' {0:2}:8:2 ' ` " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### Spread Affinity Policy " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### Spread Affinity Policy " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows the result of the `spread` affinity policy on the partition list when the number of threads is less than or equal to the number of places in the parent's place partition, for the machine architecture depicted above. Note that the threads are bound to the first place of each subpartition. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows the result of the `spread` affinity policy on the partition list when the number of threads is less than or equal to the number of places in the parent's place partition, for the machine architecture depicted above. Note that the threads are bound to the first place of each subpartition. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_affinity.1.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_affinity.1.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_affinity.1.f " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_affinity.1.f " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " It is unspecified on which place the master thread is initially started. If the master thread is initially started on p0, the following placement of threads will be applied in the parallel region: " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " It is unspecified on which place the master thread is initially started. If the master thread is initially started on p0, the following placement of threads will be applied in the parallel region: " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", "* thread 0 executes on p0 with the place partition p0,p1 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", "* thread 1 executes on p2 with the place partition p2,p3 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", "* thread 2 executes on p4 with the place partition p4,p5 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", "* thread 3 executes on p6 with the place partition p6,p7 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " If the master thread would initially be started on p2, the placement of threads and distribution of the place partition would be as follows: " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " If the master thread would initially be started on p2, the placement of threads and distribution of the place partition would be as follows: " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", "* thread 0 executes on p2 with the place partition p2,p3 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", "* thread 1 executes on p4 with the place partition p4,p5 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", "* thread 2 executes on p6 with the place partition p6,p7 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", "* thread 3 executes on p0 with the place partition p0,p1 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example illustrates the `spread` thread affinity policy when the number of threads is greater than the number of places in the parent's place partition. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example illustrates the `spread` thread affinity policy when the number of threads is greater than the number of places in the parent's place partition. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Let _T_ be the number of threads in the team, and _P_ be the number of places in the parent's place partition. The first _T/P_ threads of the team (including the master thread) execute on the parent's place. The next _T/P_ threads execute on the next place in the place partition, and so on, with wrap around. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Let _T_ be the number of threads in the team, and _P_ be the number of places in the parent's place partition. The first _T/P_ threads of the team (including the master thread) execute on the parent's place. The next _T/P_ threads execute on the next place in the place partition, and so on, with wrap around. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_affinity.2.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_affinity.2.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_affinity.2.f90 " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_affinity.2.f90 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " It is unspecified on which place the master thread is initially started. If the master thread is initially started on p0, the following placement of threads will be applied in the parallel region: " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " It is unspecified on which place the master thread is initially started. If the master thread is initially started on p0, the following placement of threads will be applied in the parallel region: " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", "* threads 0,1 execute on p0 with the place partition p0 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", "* threads 2,3 execute on p1 with the place partition p1 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", "* threads 4,5 execute on p2 with the place partition p2 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", "* threads 6,7 execute on p3 with the place partition p3 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", "* threads 8,9 execute on p4 with the place partition p4 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", "* threads 10,11 execute on p5 with the place partition p5 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", "* threads 12,13 execute on p6 with the place partition p6 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", "* threads 14,15 execute on p7 with the place partition p7 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " If the master thread would initially be started on p2, the placement of threads and distribution of the place partition would be as follows: " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " If the master thread would initially be started on p2, the placement of threads and distribution of the place partition would be as follows: " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", "* threads 0,1 execute on p2 with the place partition p2 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", "* threads 2,3 execute on p3 with the place partition p3 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", "* threads 4,5 execute on p4 with the place partition p4 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", "* threads 6,7 execute on p5 with the place partition p5 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", "* threads 8,9 execute on p6 with the place partition p6 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", "* threads 10,11 execute on p7 with the place partition p7 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", "* threads 12,13 execute on p0 with the place partition p0 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", "* threads 14,15 execute on p1 with the place partition p1 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### Close Affinity Policy " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### Close Affinity Policy " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows the result of the `close` affinity policy on the partition list when the number of threads is less than or equal to the number of places in parent's place partition, for the machine architecture depicted above. The place partition is not changed by the `close` policy. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows the result of the `close` affinity policy on the partition list when the number of threads is less than or equal to the number of places in parent's place partition, for the machine architecture depicted above. The place partition is not changed by the `close` policy. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_affinity.3.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_affinity.3.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_affinity.3.f " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_affinity.3.f " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " It is unspecified on which place the master thread is initially started. If the master thread is initially started on p0, the following placement of threads will be applied in the `parallel` region: " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " It is unspecified on which place the master thread is initially started. If the master thread is initially started on p0, the following placement of threads will be applied in the `parallel` region: " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", "* thread 0 executes on p0 with the place partition p0-p7 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", "* thread 1 executes on p1 with the place partition p0-p7 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", "* thread 2 executes on p2 with the place partition p0-p7 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", "* thread 3 executes on p3 with the place partition p0-p7 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " If the master thread would initially be started on p2, the placement of threads and distribution of the place partition would be as follows: " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " If the master thread would initially be started on p2, the placement of threads and distribution of the place partition would be as follows: " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", "* thread 0 executes on p2 with the place partition p0-p7 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", "* thread 1 executes on p3 with the place partition p0-p7 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", "* thread 2 executes on p4 with the place partition p0-p7 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", "* thread 3 executes on p5 with the place partition p0-p7 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example illustrates the `close` thread affinity policy when the number of threads is greater than the number of places in the parent's place partition. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example illustrates the `close` thread affinity policy when the number of threads is greater than the number of places in the parent's place partition. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Let _T_ be the number of threads in the team, and _P_ be the number of places in the parent's place partition. The first _T/P_ threads of the team (including the master thread) execute on the parent's place. The next _T/P_ threads execute on the next place in the place partition, and so on, with wrap around. The place partition is not changed by the `close` policy. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Let _T_ be the number of threads in the team, and _P_ be the number of places in the parent's place partition. The first _T/P_ threads of the team (including the master thread) execute on the parent's place. The next _T/P_ threads execute on the next place in the place partition, and so on, with wrap around. The place partition is not changed by the `close` policy. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_affinity.4.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_affinity.4.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_affinity.4.f90 " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_affinity.4.f90 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " It is unspecified on which place the master thread is initially started. If the master thread is initially running on p0, the following placement of threads will be applied in the parallel region: " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " It is unspecified on which place the master thread is initially started. If the master thread is initially running on p0, the following placement of threads will be applied in the parallel region: " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", "* threads 0,1 execute on p0 with the place partition p0-p7 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", "* threads 2,3 execute on p1 with the place partition p0-p7 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", "* threads 4,5 execute on p2 with the place partition p0-p7 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", "* threads 6,7 execute on p3 with the place partition p0-p7 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", "* threads 8,9 execute on p4 with the place partition p0-p7 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", "* threads 10,11 execute on p5 with the place partition p0-p7 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", "* threads 12,13 execute on p6 with the place partition p0-p7 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", "* threads 14,15 execute on p7 with the place partition p0-p7 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " If the master thread would initially be started on p2, the placement of threads and distribution of the place partition would be as follows: " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " If the master thread would initially be started on p2, the placement of threads and distribution of the place partition would be as follows: " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", "* threads 0,1 execute on p2 with the place partition p0-p7 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", "* threads 2,3 execute on p3 with the place partition p0-p7 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", "* threads 4,5 execute on p4 with the place partition p0-p7 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", "* threads 6,7 execute on p5 with the place partition p0-p7 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", "* threads 8,9 execute on p6 with the place partition p0-p7 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", "* threads 10,11 execute on p7 with the place partition p0-p7 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", "* threads 12,13 execute on p0 with the place partition p0-p7 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", "* threads 14,15 execute on p1 with the place partition p0-p7 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### Master Affinity Policy " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### Master Affinity Policy " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows the result of the `master` affinity policy on the partition list for the machine architecture depicted above. The place partition is not changed by the master policy. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows the result of the `master` affinity policy on the partition list for the machine architecture depicted above. The place partition is not changed by the master policy. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_affinity.5.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_affinity.5.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_affinity.5.f " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_affinity.5.f " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " It is unspecified on which place the master thread is initially started. If the master thread is initially running on p0, the following placement of threads will be applied in the parallel region: " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " It is unspecified on which place the master thread is initially started. If the master thread is initially running on p0, the following placement of threads will be applied in the parallel region: " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", "* threads 0-3 execute on p0 with the place partition p0-p7 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " If the master thread would initially be started on p2, the placement of threads and distribution of the place partition would be as follows: " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " If the master thread would initially be started on p2, the placement of threads and distribution of the place partition would be as follows: " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", "* threads 0-3 execute on p2 with the place partition p0-p7 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end--- " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_affinity_query.ipynb b/notebook/Examples_affinity_query.ipynb index f93f00d..d9db016 100644 --- a/notebook/Examples_affinity_query.ipynb +++ b/notebook/Examples_affinity_query.ipynb @@ -1,70 +1,70 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Affinity Query Functions " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Affinity Query Functions " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the example below a team of threads is generated on each socket of the system, using nested parallelism. Several query functions are used to gather information to support the creation of the teams and to obtain socket and thread numbers. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the example below a team of threads is generated on each socket of the system, using nested parallelism. Several query functions are used to gather information to support the creation of the teams and to obtain socket and thread numbers. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " For proper execution of the code, the user must create a place partition, such that each place is a listing of the core numbers for a socket. For example, in a 2 socket system with 8 cores in each socket, and sequential numbering in the socket for the core numbers, the `OMP_PLACES` variable would be set to '{0:8},{8:8}', using the place syntax { _lower_bound_ : _length_ : _stride_ }, and the default stride of 1. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " For proper execution of the code, the user must create a place partition, such that each place is a listing of the core numbers for a socket. For example, in a 2 socket system with 8 cores in each socket, and sequential numbering in the socket for the core numbers, the `OMP_PLACES` variable would be set to '{0:8},{8:8}', using the place syntax { _lower_bound_ : _length_ : _stride_ }, and the default stride of 1. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The code determines the number of sockets ( _n_sockets_ ) using the `omp_get_num_places()` query function. In this example each place is constructed with a list of each socket's core numbers, hence the number of places is equal to the number of sockets. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The code determines the number of sockets ( _n_sockets_ ) using the `omp_get_num_places()` query function. In this example each place is constructed with a list of each socket's core numbers, hence the number of places is equal to the number of sockets. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The outer parallel region forms a team of threads, and each thread executes on a socket (place) because the `proc_bind` clause uses `spread` in the outer `parallel` construct. Next, in the _socket_init_ function, an inner parallel region creates a team of threads equal to the number of elements (core numbers) from the place of the parent thread. Because the outer `parallel` construct uses a `spread` affinity policy, each of its threads inherits a subpartition of the original partition. Hence, the `omp_get_place_num_procs` query function returns the number of elements (here procs = cores) in the subpartition of the thread. After each parent thread creates its nested parallel region on the section, the socket number and thread number are reported. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The outer parallel region forms a team of threads, and each thread executes on a socket (place) because the `proc_bind` clause uses `spread` in the outer `parallel` construct. Next, in the _socket_init_ function, an inner parallel region creates a team of threads equal to the number of elements (core numbers) from the place of the parent thread. Because the outer `parallel` construct uses a `spread` affinity policy, each of its threads inherits a subpartition of the original partition. Hence, the `omp_get_place_num_procs` query function returns the number of elements (here procs = cores) in the subpartition of the thread. After each parent thread creates its nested parallel region on the section, the socket number and thread number are reported. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Note: Portable tools like hwloc (Portable HardWare LOCality package), which support many common operating systems, can be used to determine the configuration of a system. On some systems there are utilities, files or user guides that provide configuration information. For instance, the socket number and proc_id's for a socket can be found in the /proc/cpuinfo text file on Linux systems. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Note: Portable tools like hwloc (Portable HardWare LOCality package), which support many common operating systems, can be used to determine the configuration of a system. On some systems there are utilities, files or user guides that provide configuration information. For instance, the socket number and proc_id's for a socket can be found in the /proc/cpuinfo text file on Linux systems. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_affinity.6.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_affinity.6.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_affinity.6.f90 " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_affinity.6.f90 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end--- " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_array_sections.ipynb b/notebook/Examples_array_sections.ipynb index 032262a..2e8ef95 100644 --- a/notebook/Examples_array_sections.ipynb +++ b/notebook/Examples_array_sections.ipynb @@ -1,124 +1,124 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Array Sections in Device Constructs " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Array Sections in Device Constructs " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following examples show the usage of array sections in `map` clauses on `target` and `target` `data` constructs. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following examples show the usage of array sections in `map` clauses on `target` and `target` `data` constructs. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " This example shows the invalid usage of two seperate sections of the same array inside of a `target` construct. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " This example shows the invalid usage of two seperate sections of the same array inside of a `target` construct. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_array_sections.1.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_array_sections.1.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_array_sections.1.f90 " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_array_sections.1.f90 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " This example shows the invalid usage of two separate sections of the same array inside of a `target` construct. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " This example shows the invalid usage of two separate sections of the same array inside of a `target` construct. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_array_sections.2.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_array_sections.2.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_array_sections.2.f90 " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_array_sections.2.f90 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " This example shows the valid usage of two separate sections of the same array inside of a `target` construct. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " This example shows the valid usage of two separate sections of the same array inside of a `target` construct. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_array_sections.3.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_array_sections.3.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_array_sections.3.f90 " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_array_sections.3.f90 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " This example shows the valid usage of a wholly contained array section of an already mapped array section inside of a `target` construct. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " This example shows the valid usage of a wholly contained array section of an already mapped array section inside of a `target` construct. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_array_sections.4.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_array_sections.4.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_array_sections.4.f90 " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_array_sections.4.f90 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end--- " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_associate.ipynb b/notebook/Examples_associate.ipynb index 276f4f1..edb6209 100644 --- a/notebook/Examples_associate.ipynb +++ b/notebook/Examples_associate.ipynb @@ -1,79 +1,79 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Fortran `ASSOCIATE` Construct " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Fortran `ASSOCIATE` Construct " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " fortranspecificstart " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " fortranspecificstart " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following is an invalid example of specifying an associate name on a data-sharing attribute clause. The constraint in the Data Sharing Attribute Rules section in the OpenMP 4.0 API Specifications states that an associate name preserves the association with the selector established at the `ASSOCIATE` statement. The associate name _b_ is associated with the shared variable _a_ . With the predetermined data-sharing attribute rule, the associate name _b_ is not allowed to be specified on the `private` clause. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following is an invalid example of specifying an associate name on a data-sharing attribute clause. The constraint in the Data Sharing Attribute Rules section in the OpenMP 4.0 API Specifications states that an associate name preserves the association with the selector established at the `ASSOCIATE` statement. The associate name _b_ is associated with the shared variable _a_ . With the predetermined data-sharing attribute rule, the associate name _b_ is not allowed to be specified on the `private` clause. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_associate.1.f " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_associate.1.f " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In next example, within the `parallel` construct, the association name _thread_id_ is associated with the private copy of _i_ . The print statement should output the unique thread number. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In next example, within the `parallel` construct, the association name _thread_id_ is associated with the private copy of _i_ . The print statement should output the unique thread number. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_associate.2.f " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_associate.2.f " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example illustrates the effect of specifying a selector name on a data-sharing attribute clause. The associate name _u_ is associated with _v_ and the variable _v_ is specified on the `private` clause of the `parallel` construct. The construct association is established prior to the `parallel` region. The association between _u_ and the original _v_ is retained (see the Data Sharing Attribute Rules section in the OpenMP 4.0 API Specifications). Inside the `parallel` region, _v_ has the value of -1 and _u_ has the value of the original _v_ . " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example illustrates the effect of specifying a selector name on a data-sharing attribute clause. The associate name _u_ is associated with _v_ and the variable _v_ is specified on the `private` clause of the `parallel` construct. The construct association is established prior to the `parallel` region. The association between _u_ and the original _v_ is retained (see the Data Sharing Attribute Rules section in the OpenMP 4.0 API Specifications). Inside the `parallel` region, _v_ has the value of -1 and _u_ has the value of the original _v_ . " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_ffreenexampleassociate3 " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_ffreenexampleassociate3 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " fortranspecificend " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " fortranspecificend " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end--- " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_async_target_depend.ipynb b/notebook/Examples_async_target_depend.ipynb index 3e34389..e154e3d 100644 --- a/notebook/Examples_async_target_depend.ipynb +++ b/notebook/Examples_async_target_depend.ipynb @@ -1,38 +1,38 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Asynchronous `target` Execution and Dependences " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Asynchronous `target` Execution and Dependences " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Asynchronous execution of a `target` region can be accomplished by creating an explicit task around the `target` region. Examples with explicit tasks are shown at the beginning of this section. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Asynchronous execution of a `target` region can be accomplished by creating an explicit task around the `target` region. Examples with explicit tasks are shown at the beginning of this section. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " As of OpenMP 4.5 and beyond the `nowait` clause can be used on the `target` directive for asynchronous execution. Examples with `nowait` clauses follow the explicit `task` examples. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " As of OpenMP 4.5 and beyond the `nowait` clause can be used on the `target` directive for asynchronous execution. Examples with `nowait` clauses follow the explicit `task` examples. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " This section also shows the use of `depend` clauses to order executions through dependences. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " This section also shows the use of `depend` clauses to order executions through dependences. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end--- " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_async_target_nowait.ipynb b/notebook/Examples_async_target_nowait.ipynb index 45974c6..85ba1dd 100644 --- a/notebook/Examples_async_target_nowait.ipynb +++ b/notebook/Examples_async_target_nowait.ipynb @@ -1,63 +1,63 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### `nowait` Clause on `target` Construct " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### `nowait` Clause on `target` Construct " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows how to execute code asynchronously on a device without an explicit task. The `nowait` clause on a `target` construct allows the thread of the _target task_ to perform other work while waiting for the `target` region execution to complete. Hence, the the `target` region can execute asynchronously on the device (without requiring a host thread to idle while waiting for the _target task_ execution to complete). " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows how to execute code asynchronously on a device without an explicit task. The `nowait` clause on a `target` construct allows the thread of the _target task_ to perform other work while waiting for the `target` region execution to complete. Hence, the the `target` region can execute asynchronously on the device (without requiring a host thread to idle while waiting for the _target task_ execution to complete). " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In this example the product of two vectors (arrays), _v1_ and _v2_ , is formed. One half of the operations is performed on the device, and the last half on the host, concurrently. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In this example the product of two vectors (arrays), _v1_ and _v2_ , is formed. One half of the operations is performed on the device, and the last half on the host, concurrently. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " After a team of threads is formed the master thread generates the _target task_ while the other threads can continue on, without a barrier, to the execution of the host portion of the vector product. The completion of the _target task_ (asynchronous target execution) is guaranteed by the synchronization in the implicit barrier at the end of the host vector-product worksharing loop region. See the `barrier` glossary entry in the OpenMP specification for details. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " After a team of threads is formed the master thread generates the _target task_ while the other threads can continue on, without a barrier, to the execution of the host portion of the vector product. The completion of the _target task_ (asynchronous target execution) is guaranteed by the synchronization in the implicit barrier at the end of the host vector-product worksharing loop region. See the `barrier` glossary entry in the OpenMP specification for details. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The host loop scheduling is `dynamic` , to balance the host thread executions, since one thread is being used for offload generation. In the situation where little time is spent by the _target task_ in setting up and tearing down the the target execution, `static` scheduling may be desired. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The host loop scheduling is `dynamic` , to balance the host thread executions, since one thread is being used for offload generation. In the situation where little time is spent by the _target task_ in setting up and tearing down the the target execution, `static` scheduling may be desired. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_async_target.3.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_async_target.3.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_async_target.3.f90 " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_async_target.3.f90 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end--- " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_async_target_nowait_depend.ipynb b/notebook/Examples_async_target_nowait_depend.ipynb index aa85679..edf777b 100644 --- a/notebook/Examples_async_target_nowait_depend.ipynb +++ b/notebook/Examples_async_target_nowait_depend.ipynb @@ -1,65 +1,65 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", "begin #### Asynchronous `target` with `nowait` and `depend` Clauses " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " More details on dependences can be found in , Task Dependences. In this example, there are three flow dependences. In the first two dependences the target task does not execute until the preceding explicit tasks have finished. These dependences are produced by arrays _v1_ and _v2_ with the `out` dependence type in the first two tasks, and the `in` dependence type in the target task. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " More details on dependences can be found in , Task Dependences. In this example, there are three flow dependences. In the first two dependences the target task does not execute until the preceding explicit tasks have finished. These dependences are produced by arrays _v1_ and _v2_ with the `out` dependence type in the first two tasks, and the `in` dependence type in the target task. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The last dependence is produced by array _p_ with the `out` dependence type in the target task, and the `in` dependence type in the last task. The last task does not execute until the target task finishes. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The last dependence is produced by array _p_ with the `out` dependence type in the target task, and the `in` dependence type in the last task. The last task does not execute until the target task finishes. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `nowait` clause on the `target` construct creates a deferrable _target task_ , allowing the encountering task to continue execution without waiting for the completion of the _target task_ . " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `nowait` clause on the `target` construct creates a deferrable _target task_ , allowing the encountering task to continue execution without waiting for the completion of the _target task_ . " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_async_target.4.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_async_target.4.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_async_target.4.f90 " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_async_target.4.f90 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", "end " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end--- " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_async_target_with_tasks.ipynb b/notebook/Examples_async_target_with_tasks.ipynb index 824bde1..bd43a1b 100644 --- a/notebook/Examples_async_target_with_tasks.ipynb +++ b/notebook/Examples_async_target_with_tasks.ipynb @@ -1,109 +1,109 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### Asynchronous `target` with Tasks " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### Asynchronous `target` with Tasks " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows how the `task` and `target` constructs are used to execute multiple `target` regions asynchronously. The task that encounters the `task` construct generates an explicit task that contains a `target` region. The thread executing the explicit task encounters a task scheduling point while waiting for the execution of the `target` region to complete, allowing the thread to switch back to the execution of the encountering task or one of the previously generated explicit tasks. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows how the `task` and `target` constructs are used to execute multiple `target` regions asynchronously. The task that encounters the `task` construct generates an explicit task that contains a `target` region. The thread executing the explicit task encounters a task scheduling point while waiting for the execution of the `target` region to complete, allowing the thread to switch back to the execution of the encountering task or one of the previously generated explicit tasks. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_async_target.1.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_async_target.1.c " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The Fortran version has an interface block that contains the `declare` `target` . An identical statement exists in the function declaration (not shown here). " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The Fortran version has an interface block that contains the `declare` `target` . An identical statement exists in the function declaration (not shown here). " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_async_target.1.f90 " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_async_target.1.f90 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows how the `task` and `target` constructs are used to execute multiple `target` regions asynchronously. The task dependence ensures that the storage is allocated and initialized on the device before it is accessed. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows how the `task` and `target` constructs are used to execute multiple `target` regions asynchronously. The task dependence ensures that the storage is allocated and initialized on the device before it is accessed. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_async_target.2.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_async_target.2.c " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The Fortran example below is similar to the C version above. Instead of pointers, though, it uses the convenience of Fortran allocatable arrays on the device. In order to preserve the arrays allocated on the device across multiple `target` regions, a `target` ~ `data` region is used in this case. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The Fortran example below is similar to the C version above. Instead of pointers, though, it uses the convenience of Fortran allocatable arrays on the device. In order to preserve the arrays allocated on the device across multiple `target` regions, a `target` ~ `data` region is used in this case. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " If there is no shape specified for an allocatable array in a `map` clause, only the array descriptor (also called a dope vector) is mapped. That is, device space is created for the descriptor, and it is initially populated with host values. In this case, the _v1_ and _v2_ arrays will be in a non-associated state on the device. When space for _v1_ and _v2_ is allocated on the device in the first `target` region the addresses to the space will be included in their descriptors. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " If there is no shape specified for an allocatable array in a `map` clause, only the array descriptor (also called a dope vector) is mapped. That is, device space is created for the descriptor, and it is initially populated with host values. In this case, the _v1_ and _v2_ arrays will be in a non-associated state on the device. When space for _v1_ and _v2_ is allocated on the device in the first `target` region the addresses to the space will be included in their descriptors. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " At the end of the first `target` region, the arrays _v1_ and _v2_ are preserved on the device for access in the second `target` region. At the end of the second `target` region, the data in array _p_ is copied back, the arrays _v1_ and _v2_ are not. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " At the end of the first `target` region, the arrays _v1_ and _v2_ are preserved on the device for access in the second `target` region. At the end of the second `target` region, the data in array _p_ is copied back, the arrays _v1_ and _v2_ are not. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " A `depend` clause is used in the `task` directive to provide a wait at the beginning of the second `target` region, to insure that there is no race condition with _v1_ and _v2_ in the two tasks. It would be noncompliant to use _v1_ and/or _v2_ in lieu of _N_ in the `depend` clauses, because the use of non-allocated allocatable arrays as list items in a `depend` clause would lead to unspecified behavior. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " A `depend` clause is used in the `task` directive to provide a wait at the beginning of the second `target` region, to insure that there is no race condition with _v1_ and _v2_ in the two tasks. It would be noncompliant to use _v1_ and/or _v2_ in lieu of _N_ in the `depend` clauses, because the use of non-allocated allocatable arrays as list items in a `depend` clause would lead to unspecified behavior. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " noteheader{--} This example is not strictly compliant with the OpenMP 4.5 specification since the allocation status of allocatable arrays _v1_ and _v2_ is changed inside the `target` region, which is not allowed. (See the restrictions for the `map` clause in the _Data-mapping Attribute Rules and Clauses_ section of the specification.) However, the intention is to relax the restrictions on mapping of allocatable variables in the next release of the specification so that the example will be compliant. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " noteheader{--} This example is not strictly compliant with the OpenMP 4.5 specification since the allocation status of allocatable arrays _v1_ and _v2_ is changed inside the `target` region, which is not allowed. (See the restrictions for the `map` clause in the _Data-mapping Attribute Rules and Clauses_ section of the specification.) However, the intention is to relax the restrictions on mapping of allocatable variables in the next release of the specification so that the example will be compliant. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_async_target.2.f90 " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_async_target.2.f90 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end--- " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_atomic.ipynb b/notebook/Examples_atomic.ipynb index 1965683..9bdccbf 100644 --- a/notebook/Examples_atomic.ipynb +++ b/notebook/Examples_atomic.ipynb @@ -1,106 +1,106 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### The `atomic` Construct " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### The `atomic` Construct " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example avoids race conditions (simultaneous updates of an element of _x_ by multiple threads) by using the `atomic` construct . " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example avoids race conditions (simultaneous updates of an element of _x_ by multiple threads) by using the `atomic` construct . " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The advantage of using the `atomic` construct in this example is that it allows updates of two different elements of _x_ to occur in parallel. If a `critical` construct were used instead, then all updates to elements of _x_ would be executed serially (though not in any guaranteed order). " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The advantage of using the `atomic` construct in this example is that it allows updates of two different elements of _x_ to occur in parallel. If a `critical` construct were used instead, then all updates to elements of _x_ would be executed serially (though not in any guaranteed order). " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Note that the `atomic` directive applies only to the statement immediately following it. As a result, elements of _y_ are not updated atomically in this example. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Note that the `atomic` directive applies only to the statement immediately following it. As a result, elements of _y_ are not updated atomically in this example. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_atomic.1.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_atomic.1.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_atomic.1.f " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_atomic.1.f " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example illustrates the `read` and `write` clauses for the `atomic` directive. These clauses ensure that the given variable is read or written, respectively, as a whole. Otherwise, some other thread might read or write part of the variable while the current thread was reading or writing another part of the variable. Note that most hardware provides atomic reads and writes for some set of properly aligned variables of specific sizes, but not necessarily for all the variable types supported by the OpenMP API. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example illustrates the `read` and `write` clauses for the `atomic` directive. These clauses ensure that the given variable is read or written, respectively, as a whole. Otherwise, some other thread might read or write part of the variable while the current thread was reading or writing another part of the variable. Note that most hardware provides atomic reads and writes for some set of properly aligned variables of specific sizes, but not necessarily for all the variable types supported by the OpenMP API. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_atomic.2.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_atomic.2.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_atomic.2.f " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_atomic.2.f " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example illustrates the `capture` clause for the `atomic` directive. In this case the value of a variable is captured, and then the variable is incremented. These operations occur atomically. This particular example could be implemented using the fetch-and-add instruction available on many kinds of hardware. The example also shows a way to implement a spin lock using the `capture` and `read` clauses. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example illustrates the `capture` clause for the `atomic` directive. In this case the value of a variable is captured, and then the variable is incremented. These operations occur atomically. This particular example could be implemented using the fetch-and-add instruction available on many kinds of hardware. The example also shows a way to implement a spin lock using the `capture` and `read` clauses. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_atomic.3.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_atomic.3.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_atomic.3.f " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_atomic.3.f " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end--- " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_atomic_restrict.ipynb b/notebook/Examples_atomic_restrict.ipynb index 3433d4a..df3bfd2 100644 --- a/notebook/Examples_atomic_restrict.ipynb +++ b/notebook/Examples_atomic_restrict.ipynb @@ -1,90 +1,90 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Restrictions on the `atomic` Construct " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Restrictions on the `atomic` Construct " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following non-conforming examples illustrate the restrictions on the `atomic` construct. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following non-conforming examples illustrate the restrictions on the `atomic` construct. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_atomic_restrict.1.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_atomic_restrict.1.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_atomic_restrict.1.f " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_atomic_restrict.1.f " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_atomic_restrict.2.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_atomic_restrict.2.c " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " fortranspecificstart The following example is non-conforming because `I` and `R` reference the same location but have different types. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " fortranspecificstart The following example is non-conforming because `I` and `R` reference the same location but have different types. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_atomic_restrict.2.f " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_atomic_restrict.2.f " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Although the following example might work on some implementations, this is also non-conforming: " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Although the following example might work on some implementations, this is also non-conforming: " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_atomic_restrict.3.f " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_atomic_restrict.3.f " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " fortranspecificend " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " fortranspecificend " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end--- " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_barrier_regions.ipynb b/notebook/Examples_barrier_regions.ipynb index fd71495..edd0364 100644 --- a/notebook/Examples_barrier_regions.ipynb +++ b/notebook/Examples_barrier_regions.ipynb @@ -1,56 +1,56 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Binding of `barrier` Regions " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Binding of `barrier` Regions " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The binding rules call for a `barrier` region to bind to the closest enclosing `parallel` region. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The binding rules call for a `barrier` region to bind to the closest enclosing `parallel` region. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the following example, the call from the main program to _sub2_ is conforming because the `barrier` region (in _sub3_ ) binds to the `parallel` region in _sub2_ . The call from the main program to _sub1_ is conforming because the `barrier` region binds to the `parallel` region in subroutine _sub2_ . " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the following example, the call from the main program to _sub2_ is conforming because the `barrier` region (in _sub3_ ) binds to the `parallel` region in _sub2_ . The call from the main program to _sub1_ is conforming because the `barrier` region binds to the `parallel` region in subroutine _sub2_ . " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The call from the main program to _sub3_ is conforming because the `barrier` region binds to the implicit inactive `parallel` region enclosing the sequential part. Also note that the `barrier` region in _sub3_ when called from _sub2_ only synchronizes the team of threads in the enclosing `parallel` region and not all the threads created in _sub1_ . " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The call from the main program to _sub3_ is conforming because the `barrier` region binds to the implicit inactive `parallel` region enclosing the sequential part. Also note that the `barrier` region in _sub3_ when called from _sub2_ only synchronizes the team of threads in the enclosing `parallel` region and not all the threads created in _sub1_ . " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_barrier_regions.1.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_barrier_regions.1.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_barrier_regions.1.f " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_barrier_regions.1.f " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end--- " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_cancellation.ipynb b/notebook/Examples_cancellation.ipynb index d15353b..2e3a4dd 100644 --- a/notebook/Examples_cancellation.ipynb +++ b/notebook/Examples_cancellation.ipynb @@ -1,81 +1,81 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Cancellation Constructs " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Cancellation Constructs " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows how the `cancel` directive can be used to terminate an OpenMP region. Although the `cancel` construct terminates the OpenMP worksharing region, programmers must still track the exception through the pointer ex and issue a cancellation for the `parallel` region if an exception has been raised. The master thread checks the exception pointer to make sure that the exception is properly handled in the sequential part. If cancellation of the `parallel` region has been requested, some threads might have executed `phase_1()` . However, it is guaranteed that none of the threads executed `phase_2()` . " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows how the `cancel` directive can be used to terminate an OpenMP region. Although the `cancel` construct terminates the OpenMP worksharing region, programmers must still track the exception through the pointer ex and issue a cancellation for the `parallel` region if an exception has been raised. The master thread checks the exception pointer to make sure that the exception is properly handled in the sequential part. If cancellation of the `parallel` region has been requested, some threads might have executed `phase_1()` . However, it is guaranteed that none of the threads executed `phase_2()` . " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_cancellation.1.cpp " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_cancellation.1.cpp " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example illustrates the use of the `cancel` construct in error handling. If there is an error condition from the `allocate` statement, the cancellation is activated. The encountering thread sets the shared variable `err` and other threads of the binding thread set proceed to the end of the worksharing construct after the cancellation has been activated. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example illustrates the use of the `cancel` construct in error handling. If there is an error condition from the `allocate` statement, the cancellation is activated. The encountering thread sets the shared variable `err` and other threads of the binding thread set proceed to the end of the worksharing construct after the cancellation has been activated. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_cancellation.1.f90 " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_cancellation.1.f90 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows how to cancel a parallel search on a binary tree as soon as the search value has been detected. The code creates a task to descend into the child nodes of the current tree node. If the search value has been found, the code remembers the tree node with the found value through an `atomic` write to the result variable and then cancels execution of all search tasks. The function `search_tree_parallel` groups all search tasks into a single task group to control the effect of the `cancel taskgroup` directive. The _level_ argument is used to create undeferred tasks after the first ten levels of the tree. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows how to cancel a parallel search on a binary tree as soon as the search value has been detected. The code creates a task to descend into the child nodes of the current tree node. If the search value has been found, the code remembers the tree node with the found value through an `atomic` write to the result variable and then cancels execution of all search tasks. The function `search_tree_parallel` groups all search tasks into a single task group to control the effect of the `cancel taskgroup` directive. The _level_ argument is used to create undeferred tasks after the first ten levels of the tree. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_cancellation.2.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_cancellation.2.c " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following is the equivalent parallel search example in Fortran. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following is the equivalent parallel search example in Fortran. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_cancellation.2.f90 " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_cancellation.2.f90 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end--- " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_carrays_fpriv.ipynb b/notebook/Examples_carrays_fpriv.ipynb index 1e1c079..9422073 100644 --- a/notebook/Examples_carrays_fpriv.ipynb +++ b/notebook/Examples_carrays_fpriv.ipynb @@ -1,109 +1,109 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### C/C++ Arrays in a `firstprivate` Clause " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### C/C++ Arrays in a `firstprivate` Clause " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ccppspecificstart " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ccppspecificstart " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example illustrates the size and value of list items of array or pointer type in a `firstprivate` clause . The size of new list items is based on the type of the corresponding original list item, as determined by the base language. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example illustrates the size and value of list items of array or pointer type in a `firstprivate` clause . The size of new list items is based on the type of the corresponding original list item, as determined by the base language. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In this example: " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In this example: " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", "* The type of `A` is array of two arrays of two ints. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", "* The type of `B` is adjusted to pointer to array of `n` ints, because it is a function parameter. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", "* The type of `C` is adjusted to pointer to int, because it is a function parameter. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", "* The type of `D` is array of two arrays of two ints. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", "* The type of `E` is array of `n` arrays of `n` ints. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Note that `B` and `E` involve variable length array types. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Note that `B` and `E` involve variable length array types. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The new items of array type are initialized as if each integer element of the original array is assigned to the corresponding element of the new array. Those of pointer type are initialized as if by assignment from the original \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The new items of array type are initialized as if each integer element of the original array is assigned to the corresponding element of the new array. Those of pointer type are initialized as if by assignment from the original \n", "* to the new item. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_carrays_fpriv.1.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_carrays_fpriv.1.c " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ccppspecificend " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ccppspecificend " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end--- " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_collapse.ipynb b/notebook/Examples_collapse.ipynb index 54a8931..6d142f6 100644 --- a/notebook/Examples_collapse.ipynb +++ b/notebook/Examples_collapse.ipynb @@ -1,134 +1,134 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### The `collapse` Clause " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### The `collapse` Clause " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the following example, the `k` and `j` loops are associated with the loop construct. So the iterations of the `k` and `j` loops are collapsed into one loop with a larger iteration space, and that loop is then divided among the threads in the current team. Since the `i` loop is not associated with the loop construct, it is not collapsed, and the `i` loop is executed sequentially in its entirety in every iteration of the collapsed `k` and `j` loop. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the following example, the `k` and `j` loops are associated with the loop construct. So the iterations of the `k` and `j` loops are collapsed into one loop with a larger iteration space, and that loop is then divided among the threads in the current team. Since the `i` loop is not associated with the loop construct, it is not collapsed, and the `i` loop is executed sequentially in its entirety in every iteration of the collapsed `k` and `j` loop. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The variable `j` can be omitted from the `private` clause when the `collapse` clause is used since it is implicitly private. However, if the `collapse` clause is omitted then `j` will be shared if it is omitted from the `private` clause. In either case, `k` is implicitly private and could be omitted from the `private` clause. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The variable `j` can be omitted from the `private` clause when the `collapse` clause is used since it is implicitly private. However, if the `collapse` clause is omitted then `j` will be shared if it is omitted from the `private` clause. In either case, `k` is implicitly private and could be omitted from the `private` clause. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_collapse.1.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_collapse.1.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_collapse.1.f " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_collapse.1.f " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the next example, the `k` and `j` loops are associated with the loop construct. So the iterations of the `k` and `j` loops are collapsed into one loop with a larger iteration space, and that loop is then divided among the threads in the current team. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the next example, the `k` and `j` loops are associated with the loop construct. So the iterations of the `k` and `j` loops are collapsed into one loop with a larger iteration space, and that loop is then divided among the threads in the current team. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The sequential execution of the iterations in the `k` and `j` loops determines the order of the iterations in the collapsed iteration space. This implies that in the sequentially last iteration of the collapsed iteration space, `k` will have the value `2` and `j` will have the value `3` . Since `klast` and `jlast` are `lastprivate` , their values are assigned by the sequentially last iteration of the collapsed `k` and `j` loop. This example prints: `2 3` . " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The sequential execution of the iterations in the `k` and `j` loops determines the order of the iterations in the collapsed iteration space. This implies that in the sequentially last iteration of the collapsed iteration space, `k` will have the value `2` and `j` will have the value `3` . Since `klast` and `jlast` are `lastprivate` , their values are assigned by the sequentially last iteration of the collapsed `k` and `j` loop. This example prints: `2 3` . " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_collapse.2.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_collapse.2.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_collapse.2.f " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_collapse.2.f " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The next example illustrates the interaction of the `collapse` and `ordered` clauses. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The next example illustrates the interaction of the `collapse` and `ordered` clauses. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the example, the loop construct has both a `collapse` clause and an `ordered` clause. The `collapse` clause causes the iterations of the `k` and `j` loops to be collapsed into one loop with a larger iteration space, and that loop is divided among the threads in the current team. An `ordered` clause is added to the loop construct, because an ordered region binds to the loop region arising from the loop construct. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the example, the loop construct has both a `collapse` clause and an `ordered` clause. The `collapse` clause causes the iterations of the `k` and `j` loops to be collapsed into one loop with a larger iteration space, and that loop is divided among the threads in the current team. An `ordered` clause is added to the loop construct, because an ordered region binds to the loop region arising from the loop construct. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " According to Section 2.12.8 of the OpenMP 4.0 specification, a thread must not execute more than one ordered region that binds to the same loop region. So the `collapse` clause is required for the example to be conforming. With the `collapse` clause, the iterations of the `k` and `j` loops are collapsed into one loop, and therefore only one ordered region will bind to the collapsed `k` and `j` loop. Without the `collapse` clause, there would be two ordered regions that bind to each iteration of the `k` loop (one arising from the first iteration of the `j` loop, and the other arising from the second iteration of the `j` loop). " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " According to Section 2.12.8 of the OpenMP 4.0 specification, a thread must not execute more than one ordered region that binds to the same loop region. So the `collapse` clause is required for the example to be conforming. With the `collapse` clause, the iterations of the `k` and `j` loops are collapsed into one loop, and therefore only one ordered region will bind to the collapsed `k` and `j` loop. Without the `collapse` clause, there would be two ordered regions that bind to each iteration of the `k` loop (one arising from the first iteration of the `j` loop, and the other arising from the second iteration of the `j` loop). " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The code prints " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The code prints " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " `0 1 1` `0 1 2` `0 2 1` `1 2 2` `1 3 1` `1 3 2` " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " `0 1 1` `0 1 2` `0 2 1` `1 2 2` `1 3 1` `1 3 2` " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_collapse.3.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_collapse.3.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_collapse.3.f " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_collapse.3.f " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end--- " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_cond_comp.ipynb b/notebook/Examples_cond_comp.ipynb index 1b7479c..b3ba559 100644 --- a/notebook/Examples_cond_comp.ipynb +++ b/notebook/Examples_cond_comp.ipynb @@ -1,63 +1,63 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Conditional Compilation " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Conditional Compilation " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ccppspecificstart The following example illustrates the use of conditional compilation using the OpenMP macro `_OPENMP` . With OpenMP compilation, the `_OPENMP` macro becomes defined. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ccppspecificstart The following example illustrates the use of conditional compilation using the OpenMP macro `_OPENMP` . With OpenMP compilation, the `_OPENMP` macro becomes defined. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_cond_comp.1.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_cond_comp.1.c " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ccppspecificend " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ccppspecificend " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " fortranspecificstart The following example illustrates the use of the conditional compilation sentinel. With OpenMP compilation, the conditional compilation sentinel `!$` is recognized and treated as two spaces. In fixed form source, statements guarded by the sentinel must start after column 6. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " fortranspecificstart The following example illustrates the use of the conditional compilation sentinel. With OpenMP compilation, the conditional compilation sentinel `!$` is recognized and treated as two spaces. In fixed form source, statements guarded by the sentinel must start after column 6. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_cond_comp.1.f " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_cond_comp.1.f " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " fortranspecificend " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " fortranspecificend " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end--- " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_copyin.ipynb b/notebook/Examples_copyin.ipynb index f975163..cc7d288 100644 --- a/notebook/Examples_copyin.ipynb +++ b/notebook/Examples_copyin.ipynb @@ -1,42 +1,42 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### The `copyin` Clause " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### The `copyin` Clause " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `copyin` clause is used to initialize threadprivate data upon entry to a `parallel` region. The value of the threadprivate variable in the master thread is copied to the threadprivate variable of each other team member. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `copyin` clause is used to initialize threadprivate data upon entry to a `parallel` region. The value of the threadprivate variable in the master thread is copied to the threadprivate variable of each other team member. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_copyin.1.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_copyin.1.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_copyin.1.f " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_copyin.1.f " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end--- " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_copyprivate.ipynb b/notebook/Examples_copyprivate.ipynb index 0b16465..f109074 100644 --- a/notebook/Examples_copyprivate.ipynb +++ b/notebook/Examples_copyprivate.ipynb @@ -1,120 +1,120 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### The `copyprivate` Clause " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### The `copyprivate` Clause " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `copyprivate` clause can be used to broadcast values acquired by a single thread directly to all instances of the private variables in the other threads. In this example, if the routine is called from the sequential part, its behavior is not affected by the presence of the directives. If it is called from a `parallel` region, then the actual arguments with which `a` and `b` are associated must be private. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `copyprivate` clause can be used to broadcast values acquired by a single thread directly to all instances of the private variables in the other threads. In this example, if the routine is called from the sequential part, its behavior is not affected by the presence of the directives. If it is called from a `parallel` region, then the actual arguments with which `a` and `b` are associated must be private. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The thread that executes the structured block associated with the `single` construct broadcasts the values of the private variables `a` , `b` , `x` , and `y` from its implicit task's data environment to the data environments of the other implicit tasks in the thread team. The broadcast completes before any of the threads have left the barrier at the end of the construct. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The thread that executes the structured block associated with the `single` construct broadcasts the values of the private variables `a` , `b` , `x` , and `y` from its implicit task's data environment to the data environments of the other implicit tasks in the thread team. The broadcast completes before any of the threads have left the barrier at the end of the construct. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_copyprivate.1.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_copyprivate.1.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_copyprivate.1.f " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_copyprivate.1.f " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In this example, assume that the input must be performed by the master thread. Since the `master` construct does not support the `copyprivate` clause, it cannot broadcast the input value that is read. However, `copyprivate` is used to broadcast an address where the input value is stored. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In this example, assume that the input must be performed by the master thread. Since the `master` construct does not support the `copyprivate` clause, it cannot broadcast the input value that is read. However, `copyprivate` is used to broadcast an address where the input value is stored. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_copyprivate.2.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_copyprivate.2.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_copyprivate.2.f " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_copyprivate.2.f " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Suppose that the number of lock variables required within a `parallel` region cannot easily be determined prior to entering it. The `copyprivate` clause can be used to provide access to shared lock variables that are allocated within that `parallel` region. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Suppose that the number of lock variables required within a `parallel` region cannot easily be determined prior to entering it. The `copyprivate` clause can be used to provide access to shared lock variables that are allocated within that `parallel` region. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_copyprivate.3.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_copyprivate.3.c " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " fortranspecificstartfnexample{copyprivate}{3} " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " fortranspecificstartfnexample{copyprivate}{3} " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Note that the effect of the `copyprivate` clause on a variable with the `allocatable` attribute is different than on a variable with the `pointer` attribute. The value of `A` is copied (as if by intrinsic assignment) and the pointer `B` is copied (as if by pointer assignment) to the corresponding list items in the other implicit tasks belonging to the `parallel` region. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Note that the effect of the `copyprivate` clause on a variable with the `allocatable` attribute is different than on a variable with the `pointer` attribute. The value of `A` is copied (as if by intrinsic assignment) and the pointer `B` is copied (as if by pointer assignment) to the corresponding list items in the other implicit tasks belonging to the `parallel` region. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_copyprivate.4.f " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_copyprivate.4.f " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " fortranspecificend " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " fortranspecificend " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end--- " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_cpp_reference.ipynb b/notebook/Examples_cpp_reference.ipynb index 244460d..edad052 100644 --- a/notebook/Examples_cpp_reference.ipynb +++ b/notebook/Examples_cpp_reference.ipynb @@ -1,51 +1,51 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### C++ Reference in Data-Sharing Clauses " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### C++ Reference in Data-Sharing Clauses " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_cppspecificstart " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_cppspecificstart " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " C++ reference types are allowed in data-sharing attribute clauses as of OpenMP 4.5, except for the `threadprivate` , `copyin` and `copyprivate` clauses. (See the Data-Sharing Attribute Clauses Section of the 4.5 OpenMP specification.) When a variable with C++ reference type is privatized, the object the reference refers to is privatized in addition to the reference itself. The following example shows the use of reference types in data-sharing clauses in the usual way. Additionally it shows how the data-sharing of formal arguments with a C++ reference type on an orphaned task generating construct is determined implicitly. (See the Data-sharing Attribute Rules for Variables Referenced in a Construct Section of the 4.5 OpenMP specification.) " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " C++ reference types are allowed in data-sharing attribute clauses as of OpenMP 4.5, except for the `threadprivate` , `copyin` and `copyprivate` clauses. (See the Data-Sharing Attribute Clauses Section of the 4.5 OpenMP specification.) When a variable with C++ reference type is privatized, the object the reference refers to is privatized in addition to the reference itself. The following example shows the use of reference types in data-sharing clauses in the usual way. Additionally it shows how the data-sharing of formal arguments with a C++ reference type on an orphaned task generating construct is determined implicitly. (See the Data-sharing Attribute Rules for Variables Referenced in a Construct Section of the 4.5 OpenMP specification.) " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_cppnexamplecpp_reference1 " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_cppnexamplecpp_reference1 " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_cppspecificend " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_cppspecificend " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end--- " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_critical.ipynb b/notebook/Examples_critical.ipynb index 73871ee..02c30d3 100644 --- a/notebook/Examples_critical.ipynb +++ b/notebook/Examples_critical.ipynb @@ -1,67 +1,67 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### The `critical` Construct " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### The `critical` Construct " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example includes several `critical` constructs. The example illustrates a queuing model in which a task is dequeued and worked on. To guard against multiple threads dequeuing the same task, the dequeuing operation must be in a `critical` region. Because the two queues in this example are independent, they are protected by `critical` constructs with different names, _xaxis_ and _yaxis_ . " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example includes several `critical` constructs. The example illustrates a queuing model in which a task is dequeued and worked on. To guard against multiple threads dequeuing the same task, the dequeuing operation must be in a `critical` region. Because the two queues in this example are independent, they are protected by `critical` constructs with different names, _xaxis_ and _yaxis_ . " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_critical.1.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_critical.1.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_critical.1.f " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_critical.1.f " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example extends the previous example by adding the `hint` clause to the `critical` constructs. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example extends the previous example by adding the `hint` clause to the `critical` constructs. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_critical.2.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_critical.2.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_critical.2.f " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_critical.2.f " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end--- " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_declare_target.ipynb b/notebook/Examples_declare_target.ipynb index e68bf30..2a7dce7 100644 --- a/notebook/Examples_declare_target.ipynb +++ b/notebook/Examples_declare_target.ipynb @@ -1,311 +1,311 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### `declare` `target` Construct " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### `declare` `target` Construct " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### `declare` `target` and `end` `declare` `target` for a Function " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### `declare` `target` and `end` `declare` `target` for a Function " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows how the `declare` `target` directive is used to indicate that the corresponding call inside a `target` region is to a `fib` function that can execute on the default target device. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows how the `declare` `target` directive is used to indicate that the corresponding call inside a `target` region is to a `fib` function that can execute on the default target device. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " A version of the function is also available on the host device. When the `if` clause conditional expression on the `target` construct evaluates to _false_ , the `target` region (thus `fib` ) will execute on the host device. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " A version of the function is also available on the host device. When the `if` clause conditional expression on the `target` construct evaluates to _false_ , the `target` region (thus `fib` ) will execute on the host device. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " For C/C++ codes the declaration of the function `fib` appears between the `declare` `target` and `end` `declare` `target` directives. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " For C/C++ codes the declaration of the function `fib` appears between the `declare` `target` and `end` `declare` `target` directives. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_declare_target.1.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_declare_target.1.c " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The Fortran `fib` subroutine contains a `declare` `target` declaration to indicate to the compiler to create an device executable version of the procedure. The subroutine name has not been included on the `declare` `target` directive and is, therefore, implicitly assumed. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The Fortran `fib` subroutine contains a `declare` `target` declaration to indicate to the compiler to create an device executable version of the procedure. The subroutine name has not been included on the `declare` `target` directive and is, therefore, implicitly assumed. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The program uses the `module_fib` module, which presents an explicit interface to the compiler with the `declare` `target` declarations for processing the `fib` call. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The program uses the `module_fib` module, which presents an explicit interface to the compiler with the `declare` `target` declarations for processing the `fib` call. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_declare_target.1.f90 " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_declare_target.1.f90 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The next Fortran example shows the use of an external subroutine. Without an explicit interface (through module use or an interface block) the `declare` `target` declarations within a external subroutine are unknown to the main program unit; therefore, a `declare` `target` must be provided within the program scope for the compiler to determine that a target binary should be available. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The next Fortran example shows the use of an external subroutine. Without an explicit interface (through module use or an interface block) the `declare` `target` declarations within a external subroutine are unknown to the main program unit; therefore, a `declare` `target` must be provided within the program scope for the compiler to determine that a target binary should be available. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_declare_target.2.f90 " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_declare_target.2.f90 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### `declare` `target` Construct for Class Type " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### `declare` `target` Construct for Class Type " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_cppspecificstart " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_cppspecificstart " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows how the `declare` `target` and `end` `declare` `target` directives are used to enclose the declaration of a variable _varY_ with a class type `typeY` . The member function `typeY::foo()` cannot be accessed on a target device because its declaration did not appear between `declare` `target` and `end` `declare` `target` directives. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows how the `declare` `target` and `end` `declare` `target` directives are used to enclose the declaration of a variable _varY_ with a class type `typeY` . The member function `typeY::foo()` cannot be accessed on a target device because its declaration did not appear between `declare` `target` and `end` `declare` `target` directives. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_cppnexampledeclare_target2 " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_cppnexampledeclare_target2 " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_cppspecificend " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_cppspecificend " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### `declare` `target` and `end` `declare` `target` for Variables " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### `declare` `target` and `end` `declare` `target` for Variables " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following examples show how the `declare` `target` and `end` `declare` `target` directives are used to indicate that global variables are mapped to the implicit device data environment of each target device. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following examples show how the `declare` `target` and `end` `declare` `target` directives are used to indicate that global variables are mapped to the implicit device data environment of each target device. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the following example, the declarations of the variables _p_ , _v1_ , and _v2_ appear between `declare` `target` and `end` `declare` `target` directives indicating that the variables are mapped to the implicit device data environment of each target device. The `target` `update` directive is then used to manage the consistency of the variables _p_ , _v1_ , and _v2_ between the data environment of the encountering host device task and the implicit device data environment of the default target device. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the following example, the declarations of the variables _p_ , _v1_ , and _v2_ appear between `declare` `target` and `end` `declare` `target` directives indicating that the variables are mapped to the implicit device data environment of each target device. The `target` `update` directive is then used to manage the consistency of the variables _p_ , _v1_ , and _v2_ between the data environment of the encountering host device task and the implicit device data environment of the default target device. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_declare_target.3.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_declare_target.3.c " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The Fortran version of the above C code uses a different syntax. Fortran modules use a list syntax on the `declare` `target` directive to declare mapped variables. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The Fortran version of the above C code uses a different syntax. Fortran modules use a list syntax on the `declare` `target` directive to declare mapped variables. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_declare_target.3.f90 " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_declare_target.3.f90 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example also indicates that the function `Pfun()` is available on the target device, as well as the variable _Q_ , which is mapped to the implicit device data environment of each target device. The `target` `update` directive is then used to manage the consistency of the variable _Q_ between the data environment of the encountering host device task and the implicit device data environment of the default target device. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example also indicates that the function `Pfun()` is available on the target device, as well as the variable _Q_ , which is mapped to the implicit device data environment of each target device. The `target` `update` directive is then used to manage the consistency of the variable _Q_ between the data environment of the encountering host device task and the implicit device data environment of the default target device. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the following example, the function and variable declarations appear between the `declare` `target` and `end` `declare` `target` directives. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the following example, the function and variable declarations appear between the `declare` `target` and `end` `declare` `target` directives. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_declare_target.4.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_declare_target.4.c " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The Fortran version of the above C code uses a different syntax. In Fortran modules a list syntax on the `declare` `target` directive is used to declare mapped variables and procedures. The _N_ and _Q_ variables are declared as a comma separated list. When the `declare` `target` directive is used to declare just the procedure, the procedure name need not be listed -- it is implicitly assumed, as illustrated in the `Pfun()` function. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The Fortran version of the above C code uses a different syntax. In Fortran modules a list syntax on the `declare` `target` directive is used to declare mapped variables and procedures. The _N_ and _Q_ variables are declared as a comma separated list. When the `declare` `target` directive is used to declare just the procedure, the procedure name need not be listed -- it is implicitly assumed, as illustrated in the `Pfun()` function. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_declare_target.4.f90 " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_declare_target.4.f90 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### `declare` `target` and `end` `declare` `target` with `declare` `simd` " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### `declare` `target` and `end` `declare` `target` with `declare` `simd` " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows how the `declare` `target` and `end` `declare` `target` directives are used to indicate that a function is available on a target device. The `declare` `simd` directive indicates that there is a SIMD version of the function `P()` that is available on the target device as well as one that is available on the host device. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows how the `declare` `target` and `end` `declare` `target` directives are used to indicate that a function is available on a target device. The `declare` `simd` directive indicates that there is a SIMD version of the function `P()` that is available on the target device as well as one that is available on the host device. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_declare_target.5.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_declare_target.5.c " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The Fortran version of the above C code uses a different syntax. Fortran modules use a list syntax of the `declare` `target` declaration for the mapping. Here the _N_ and _Q_ variables are declared in the list form as a comma separated list. The function declaration does not use a list and implicitly assumes the function name. In this Fortran example row and column indices are reversed relative to the C/C++ example, as is usual for codes optimized for memory access. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The Fortran version of the above C code uses a different syntax. Fortran modules use a list syntax of the `declare` `target` declaration for the mapping. Here the _N_ and _Q_ variables are declared in the list form as a comma separated list. The function declaration does not use a list and implicitly assumes the function name. In this Fortran example row and column indices are reversed relative to the C/C++ example, as is usual for codes optimized for memory access. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_declare_target.5.f90 " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_declare_target.5.f90 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### `declare` ~ `target` Directive with `link` Clause " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### `declare` ~ `target` Directive with `link` Clause " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the OpenMP 4.5 standard the `declare` ~ `target` directive was extended to allow static data to be mapped, emph{when needed}, through a `link` clause. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the OpenMP 4.5 standard the `declare` ~ `target` directive was extended to allow static data to be mapped, emph{when needed}, through a `link` clause. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Data storage for items listed in the `link` clause becomes available on the device when it is mapped implicitly or explicitly in a `map` clause, and it persists for the scope of the mapping (as specified by a `target` construct, a `target` ~ `data` construct, or `target` ~ `enter/exit` ~ `data` constructs). " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Data storage for items listed in the `link` clause becomes available on the device when it is mapped implicitly or explicitly in a `map` clause, and it persists for the scope of the mapping (as specified by a `target` construct, a `target` ~ `data` construct, or `target` ~ `enter/exit` ~ `data` constructs). " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Tip: When all the global data items will not fit on a device and are not needed simultaneously, use the `link` clause and map the data only when it is needed. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Tip: When all the global data items will not fit on a device and are not needed simultaneously, use the `link` clause and map the data only when it is needed. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following C and Fortran examples show two sets of data (single precision and double precision) that are global on the host for the entire execution on the host; but are only used globally on the device for part of the program execution. The single precision data are allocated and persist only for the first `target` region. Similarly, the double precision data are in scope on the device only for the second `target` region. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following C and Fortran examples show two sets of data (single precision and double precision) that are global on the host for the entire execution on the host; but are only used globally on the device for part of the program execution. The single precision data are allocated and persist only for the first `target` region. Similarly, the double precision data are in scope on the device only for the second `target` region. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_declare_target.6.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_declare_target.6.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_declare_target.6.f90 " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_declare_target.6.f90 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end--- " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_default_none.ipynb b/notebook/Examples_default_none.ipynb index e231f3d..ef2552e 100644 --- a/notebook/Examples_default_none.ipynb +++ b/notebook/Examples_default_none.ipynb @@ -1,56 +1,56 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### The `default(none)` Clause " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### The `default(none)` Clause " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example distinguishes the variables that are affected by the `default(none)` clause from those that are not. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example distinguishes the variables that are affected by the `default(none)` clause from those that are not. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ccppspecificstart Beginning with OpenMP 4.0, variables with `const` -qualified type and no mutable member are no longer predetermined shared. Thus, these variables (variable _c_ in the example) need to be explicitly listed in data-sharing attribute clauses when the `default(none)` clause is specified. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ccppspecificstart Beginning with OpenMP 4.0, variables with `const` -qualified type and no mutable member are no longer predetermined shared. Thus, these variables (variable _c_ in the example) need to be explicitly listed in data-sharing attribute clauses when the `default(none)` clause is specified. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_default_none.1.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_default_none.1.c " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ccppspecificend " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ccppspecificend " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_default_none.1.f " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_default_none.1.f " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end--- " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_device.ipynb b/notebook/Examples_device.ipynb index 9d0341f..de2cdc1 100644 --- a/notebook/Examples_device.ipynb +++ b/notebook/Examples_device.ipynb @@ -1,157 +1,157 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Device Routines " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Device Routines " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### `omp_is_initial_device` Routine " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### `omp_is_initial_device` Routine " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows how the `omp_is_initial_device` runtime library routine can be used to query if a code is executing on the initial host device or on a target device. The example then sets the number of threads in the `parallel` region based on where the code is executing. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows how the `omp_is_initial_device` runtime library routine can be used to query if a code is executing on the initial host device or on a target device. The example then sets the number of threads in the `parallel` region based on where the code is executing. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_device.1.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_device.1.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_device.1.f90 " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_device.1.f90 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### `omp_get_num_devices` Routine " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### `omp_get_num_devices` Routine " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows how the `omp_get_num_devices` runtime library routine can be used to determine the number of devices. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows how the `omp_get_num_devices` runtime library routine can be used to determine the number of devices. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_device.2.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_device.2.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_device.2.f90 " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_device.2.f90 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "subsection{ `omp_set_default_device` and " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "subsection{ `omp_set_default_device` and " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " `omp_get_default_device` Routines} " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " `omp_get_default_device` Routines} " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows how the `omp_set_default_device` and `omp_get_default_device` runtime library routines can be used to set the default device and determine the default device respectively. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows how the `omp_set_default_device` and `omp_get_default_device` runtime library routines can be used to set the default device and determine the default device respectively. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_device.3.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_device.3.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_device.3.f90 " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_device.3.f90 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### Target Memory and Device Pointers Routines " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### Target Memory and Device Pointers Routines " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows how to create space on a device, transfer data to and from that space, and free the space, using API calls. The API calls directly execute allocation, copy and free operations on the device, without invoking any mapping through a `target` directive. The `omp_target_alloc` routine allocates space and returns a device pointer for referencing the space in the `omp_target_memcpy` API routine on the host. The `omp_target_free` routine frees the space on the device. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows how to create space on a device, transfer data to and from that space, and free the space, using API calls. The API calls directly execute allocation, copy and free operations on the device, without invoking any mapping through a `target` directive. The `omp_target_alloc` routine allocates space and returns a device pointer for referencing the space in the `omp_target_memcpy` API routine on the host. The `omp_target_free` routine frees the space on the device. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The example also illustrates how to access that space in a `target` region by exposing the device pointer in an `is_device_ptr` clause. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The example also illustrates how to access that space in a `target` region by exposing the device pointer in an `is_device_ptr` clause. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The example creates an array of cosine values on the default device, to be used on the host device. The function fails if a default device is not available. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The example creates an array of cosine values on the default device, to be used on the host device. The function fails if a default device is not available. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_device.4.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_device.4.c " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end--- " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_doacross.ipynb b/notebook/Examples_doacross.ipynb index 3f97240..2016b86 100644 --- a/notebook/Examples_doacross.ipynb +++ b/notebook/Examples_doacross.ipynb @@ -1,124 +1,124 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Doacross Loop Nest " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Doacross Loop Nest " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " An `ordered` clause can be used on a loop construct with an integer parameter argument to define the number of associated loops within a _doacross loop nest_ where cross-iteration dependences exist. A `depend` clause on an `ordered` construct within an ordered loop describes the dependences of the _doacross_ loops. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " An `ordered` clause can be used on a loop construct with an integer parameter argument to define the number of associated loops within a _doacross loop nest_ where cross-iteration dependences exist. A `depend` clause on an `ordered` construct within an ordered loop describes the dependences of the _doacross_ loops. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the code below, the `depend(sink:i-1)` clause defines an _i-1_ to _i_ cross-iteration dependence that specifies a wait point for the completion of computation from iteration _i-1_ before proceeding to the subsequent statements. The `depend(source)` clause indicates the completion of computation from the current iteration ( _i_ ) to satisfy the cross-iteration dependence that arises from the iteration. For this example the same sequential ordering could have been achieved with an `ordered` clause without a parameter, on the loop directive, and a single `ordered` directive without the `depend` clause specified for the statement executing the _bar_ function. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the code below, the `depend(sink:i-1)` clause defines an _i-1_ to _i_ cross-iteration dependence that specifies a wait point for the completion of computation from iteration _i-1_ before proceeding to the subsequent statements. The `depend(source)` clause indicates the completion of computation from the current iteration ( _i_ ) to satisfy the cross-iteration dependence that arises from the iteration. For this example the same sequential ordering could have been achieved with an `ordered` clause without a parameter, on the loop directive, and a single `ordered` directive without the `depend` clause specified for the statement executing the _bar_ function. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_doacross.1.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_doacross.1.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_doacross.1.f90 " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_doacross.1.f90 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following code is similar to the previous example but with _doacross loop nest_ extended to two nested loops, _i_ and _j_ , as specified by the `ordered(2)` clause on the loop directive. In the C/C++ code, the _i_ and _j_ loops are the first and second associated loops, respectively, whereas in the Fortran code, the _j_ and _i_ loops are the first and second associated loops, respectively. The `depend(sink:i-1,j)` and `depend(sink:i,j-1)` clauses in the C/C++ code define cross-iteration dependences in two dimensions from iterations ( _i-1, j_ ) and ( _i, j-1_ ) to iteration ( _i, j_ ). Likewise, the `depend(sink:j-1,i)` and `depend(sink:j,i-1)` clauses in the Fortran code define cross-iteration dependences from iterations ( _j-1, i_ ) and ( _j, i-1_ ) to iteration ( _j, i_ ). " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following code is similar to the previous example but with _doacross loop nest_ extended to two nested loops, _i_ and _j_ , as specified by the `ordered(2)` clause on the loop directive. In the C/C++ code, the _i_ and _j_ loops are the first and second associated loops, respectively, whereas in the Fortran code, the _j_ and _i_ loops are the first and second associated loops, respectively. The `depend(sink:i-1,j)` and `depend(sink:i,j-1)` clauses in the C/C++ code define cross-iteration dependences in two dimensions from iterations ( _i-1, j_ ) and ( _i, j-1_ ) to iteration ( _i, j_ ). Likewise, the `depend(sink:j-1,i)` and `depend(sink:j,i-1)` clauses in the Fortran code define cross-iteration dependences from iterations ( _j-1, i_ ) and ( _j, i-1_ ) to iteration ( _j, i_ ). " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_doacross.2.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_doacross.2.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_doacross.2.f90 " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_doacross.2.f90 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows the incorrect use of the `ordered` directive with a `depend` clause. There are two issues with the code. The first issue is a missing `ordered` ~ `depend(source)` directive, which could cause a deadlock. The second issue is the `depend(sink:i+1,j)` and `depend(sink:i,j+1)` clauses define dependences on lexicographically later source iterations ( _i+1, j_ ) and ( _i, j+1_ ), which could cause a deadlock as well since they may not start to execute until the current iteration completes. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows the incorrect use of the `ordered` directive with a `depend` clause. There are two issues with the code. The first issue is a missing `ordered` ~ `depend(source)` directive, which could cause a deadlock. The second issue is the `depend(sink:i+1,j)` and `depend(sink:i,j+1)` clauses define dependences on lexicographically later source iterations ( _i+1, j_ ) and ( _i, j+1_ ), which could cause a deadlock as well since they may not start to execute until the current iteration completes. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_doacross.3.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_doacross.3.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_doacross.3.f90 " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_doacross.3.f90 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example illustrates the use of the `collapse` clause for a _doacross loop nest_ . The _i_ and _j_ loops are the associated loops for the collapsed loop as well as for the _doacross loop nest_ . The example also shows a compliant usage of the dependence source directive placed before the corresponding sink directive. Checking the completion of computation from previous iterations at the sink point can occur after the source statement. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example illustrates the use of the `collapse` clause for a _doacross loop nest_ . The _i_ and _j_ loops are the associated loops for the collapsed loop as well as for the _doacross loop nest_ . The example also shows a compliant usage of the dependence source directive placed before the corresponding sink directive. Checking the completion of computation from previous iterations at the sink point can occur after the source statement. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_doacross.4.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_doacross.4.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_doacross.4.f90 " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_doacross.4.f90 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end--- " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_flush_nolist.ipynb b/notebook/Examples_flush_nolist.ipynb index 7ea5d65..871bb0a 100644 --- a/notebook/Examples_flush_nolist.ipynb +++ b/notebook/Examples_flush_nolist.ipynb @@ -1,42 +1,42 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### The `flush` Construct without a List " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### The `flush` Construct without a List " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example distinguishes the shared variables affected by a `flush` construct with no list from the shared objects that are not affected: " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example distinguishes the shared variables affected by a `flush` construct with no list from the shared objects that are not affected: " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_flush_nolist.1.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_flush_nolist.1.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_flush_nolist.1.f " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_flush_nolist.1.f " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end--- " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_fort_do.ipynb b/notebook/Examples_fort_do.ipynb index 3d2e603..1c2615b 100644 --- a/notebook/Examples_fort_do.ipynb +++ b/notebook/Examples_fort_do.ipynb @@ -1,63 +1,63 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Fortran Restrictions on the `do` Construct " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Fortran Restrictions on the `do` Construct " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " fortranspecificstart " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " fortranspecificstart " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " If an `end do` directive follows a _do-construct_ in which several `DO` statements share a `DO` termination statement, then a `do` directive can only be specified for the outermost of these `DO` statements. The following example contains correct usages of loop constructs: " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " If an `end do` directive follows a _do-construct_ in which several `DO` statements share a `DO` termination statement, then a `do` directive can only be specified for the outermost of these `DO` statements. The following example contains correct usages of loop constructs: " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_fort_do.1.f " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_fort_do.1.f " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example is non-conforming because the matching `do` directive for the `end do` does not precede the outermost loop: " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example is non-conforming because the matching `do` directive for the `end do` does not precede the outermost loop: " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_fort_do.2.f " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_fort_do.2.f " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " fortranspecificend " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " fortranspecificend " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end--- " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_fort_loopvar.ipynb b/notebook/Examples_fort_loopvar.ipynb index 29fbf9c..329cd1a 100644 --- a/notebook/Examples_fort_loopvar.ipynb +++ b/notebook/Examples_fort_loopvar.ipynb @@ -1,63 +1,63 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Fortran Private Loop Iteration Variables " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Fortran Private Loop Iteration Variables " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " fortranspecificstart " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " fortranspecificstart " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In general loop iteration variables will be private, when used in the _do-loop_ of a `do` and `parallel do` construct or in sequential loops in a `parallel` construct (see Section 2.7.1 and Section 2.14.1 of the OpenMP 4.0 specification). In the following example of a sequential loop in a `parallel` construct the loop iteration variable _I_ will be private. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In general loop iteration variables will be private, when used in the _do-loop_ of a `do` and `parallel do` construct or in sequential loops in a `parallel` construct (see Section 2.7.1 and Section 2.14.1 of the OpenMP 4.0 specification). In the following example of a sequential loop in a `parallel` construct the loop iteration variable _I_ will be private. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_ffreenexamplefort_loopvar1 " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_ffreenexamplefort_loopvar1 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In exceptional cases, loop iteration variables can be made shared, as in the following example: " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In exceptional cases, loop iteration variables can be made shared, as in the following example: " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_ffreenexamplefort_loopvar2 " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_ffreenexamplefort_loopvar2 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Note however that the use of shared loop iteration variables can easily lead to race conditions. fortranspecificend " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Note however that the use of shared loop iteration variables can easily lead to race conditions. fortranspecificend " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end--- " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_fort_race.ipynb b/notebook/Examples_fort_race.ipynb index fe60c43..d457dd3 100644 --- a/notebook/Examples_fort_race.ipynb +++ b/notebook/Examples_fort_race.ipynb @@ -1,47 +1,47 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Race Conditions Caused by Implied Copies of Shared Variables in Fortran " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Race Conditions Caused by Implied Copies of Shared Variables in Fortran " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " fortranspecificstart " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " fortranspecificstart " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example contains a race condition, because the shared variable, which is an array section, is passed as an actual argument to a routine that has an assumed-size array as its dummy argument. The subroutine call passing an array section argument may cause the compiler to copy the argument into a temporary location prior to the call and copy from the temporary location into the original variable when the subroutine returns. This copying would cause races in the `parallel` region. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example contains a race condition, because the shared variable, which is an array section, is passed as an actual argument to a routine that has an assumed-size array as its dummy argument. The subroutine call passing an array section argument may cause the compiler to copy the argument into a temporary location prior to the call and copy from the temporary location into the original variable when the subroutine returns. This copying would cause races in the `parallel` region. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_ffreenexamplefort_race1 " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_ffreenexamplefort_race1 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " fortranspecificend " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " fortranspecificend " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end--- " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_fort_sa_private.ipynb b/notebook/Examples_fort_sa_private.ipynb index de0583b..c329b6e 100644 --- a/notebook/Examples_fort_sa_private.ipynb +++ b/notebook/Examples_fort_sa_private.ipynb @@ -1,91 +1,91 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Fortran Restrictions on Storage Association with the `private` Clause " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Fortran Restrictions on Storage Association with the `private` Clause " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " fortranspecificstart " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " fortranspecificstart " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following non-conforming examples illustrate the implications of the `private` clause rules with regard to storage association. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following non-conforming examples illustrate the implications of the `private` clause rules with regard to storage association. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_fort_sa_private.1.f " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_fort_sa_private.1.f " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_fort_sa_private.2.f " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_fort_sa_private.2.f " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_fort_sa_private.3.f " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_fort_sa_private.3.f " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", " blue line floater at top of this page for 'Fortran, cont.' [t!] linewitharrows{-1}{dashed}{Fortran (cont.)}{8em} " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_fort_sa_private.4.f " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_fort_sa_private.4.f " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_fort_sa_private.5.f " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_fort_sa_private.5.f " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " fortranspecificend " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " fortranspecificend " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end--- " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_fort_sp_common.ipynb b/notebook/Examples_fort_sp_common.ipynb index ec9a9a4..7947994 100644 --- a/notebook/Examples_fort_sp_common.ipynb +++ b/notebook/Examples_fort_sp_common.ipynb @@ -1,126 +1,126 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Fortran Restrictions on `shared` and `private` Clauses with Common Blocks " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Fortran Restrictions on `shared` and `private` Clauses with Common Blocks " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " fortranspecificstart " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " fortranspecificstart " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " When a named common block is specified in a `private` , `firstprivate` , or `lastprivate` clause of a construct, none of its members may be declared in another data-sharing attribute clause on that construct. The following examples illustrate this point. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " When a named common block is specified in a `private` , `firstprivate` , or `lastprivate` clause of a construct, none of its members may be declared in another data-sharing attribute clause on that construct. The following examples illustrate this point. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example is conforming: " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example is conforming: " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_fort_sp_common.1.f " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_fort_sp_common.1.f " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example is also conforming: " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example is also conforming: " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_fort_sp_common.2.f " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_fort_sp_common.2.f " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", " blue line floater at top of this page for 'Fortran, cont.' [t!] linewitharrows{-1}{dashed}{Fortran (cont.)}{8em} " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example is conforming: " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example is conforming: " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_fort_sp_common.3.f " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_fort_sp_common.3.f " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example is non-conforming because `x` is a constituent element of `c` : " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example is non-conforming because `x` is a constituent element of `c` : " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_fort_sp_common.4.f " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_fort_sp_common.4.f " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example is non-conforming because a common block may not be declared both shared and private: " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example is non-conforming because a common block may not be declared both shared and private: " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_fort_sp_common.5.f " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_fort_sp_common.5.f " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " fortranspecificend " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " fortranspecificend " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end--- " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_fpriv_sections.ipynb b/notebook/Examples_fpriv_sections.ipynb index df5eed6..5f5f985 100644 --- a/notebook/Examples_fpriv_sections.ipynb +++ b/notebook/Examples_fpriv_sections.ipynb @@ -1,42 +1,42 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### The `firstprivate` Clause and the `sections` Construct " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### The `firstprivate` Clause and the `sections` Construct " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the following example of the `sections` construct the `firstprivate` clause is used to initialize the private copy of `section_count` of each thread. The problem is that the `section` constructs modify `section_count` , which breaks the independence of the `section` constructs. When different threads execute each section, both sections will print the value 1. When the same thread executes the two sections, one section will print the value 1 and the other will print the value 2. Since the order of execution of the two sections in this case is unspecified, it is unspecified which section prints which value. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the following example of the `sections` construct the `firstprivate` clause is used to initialize the private copy of `section_count` of each thread. The problem is that the `section` constructs modify `section_count` , which breaks the independence of the `section` constructs. When different threads execute each section, both sections will print the value 1. When the same thread executes the two sections, one section will print the value 1 and the other will print the value 2. Since the order of execution of the two sections in this case is unspecified, it is unspecified which section prints which value. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_fpriv_sections.1.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_fpriv_sections.1.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_fpriv_sections.1.f90 " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_fpriv_sections.1.f90 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end--- " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_get_nthrs.ipynb b/notebook/Examples_get_nthrs.ipynb index 5aa7991..e42cdec 100644 --- a/notebook/Examples_get_nthrs.ipynb +++ b/notebook/Examples_get_nthrs.ipynb @@ -1,67 +1,67 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### The `omp_get_num_threads` Routine " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### The `omp_get_num_threads` Routine " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the following example, the `omp_get_num_threads` call returns 1 in the sequential part of the code, so `np` will always be equal to 1. To determine the number of threads that will be deployed for the `parallel` region, the call should be inside the `parallel` region. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the following example, the `omp_get_num_threads` call returns 1 in the sequential part of the code, so `np` will always be equal to 1. To determine the number of threads that will be deployed for the `parallel` region, the call should be inside the `parallel` region. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_get_nthrs.1.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_get_nthrs.1.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_get_nthrs.1.f " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_get_nthrs.1.f " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows how to rewrite this program without including a query for the number of threads: " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows how to rewrite this program without including a query for the number of threads: " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_get_nthrs.2.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_get_nthrs.2.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_get_nthrs.2.f " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_get_nthrs.2.f " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end--- " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_icv.ipynb b/notebook/Examples_icv.ipynb index 64611d5..e09d706 100644 --- a/notebook/Examples_icv.ipynb +++ b/notebook/Examples_icv.ipynb @@ -1,98 +1,98 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Internal Control Variables (ICVs) " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Internal Control Variables (ICVs) " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " According to Section 2.3 of the OpenMP 4.0 specification, an OpenMP implementation must act as if there are ICVs that control the behavior of the program. This example illustrates two ICVs, _nthreads-var_ and _max-active-levels-var_ . The _nthreads-var_ ICV controls the number of threads requested for encountered parallel regions; there is one copy of this ICV per task. The _max-active-levels-var_ ICV controls the maximum number of nested active parallel regions; there is one copy of this ICV for the whole program. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " According to Section 2.3 of the OpenMP 4.0 specification, an OpenMP implementation must act as if there are ICVs that control the behavior of the program. This example illustrates two ICVs, _nthreads-var_ and _max-active-levels-var_ . The _nthreads-var_ ICV controls the number of threads requested for encountered parallel regions; there is one copy of this ICV per task. The _max-active-levels-var_ ICV controls the maximum number of nested active parallel regions; there is one copy of this ICV for the whole program. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the following example, the _nest-var_ , _max-active-levels-var_ , _dyn-var_ , and _nthreads-var_ ICVs are modified through calls to the runtime library routines `omp_set_nested` , `omp_set_max_active_levels` , ` omp_set_dynamic` , and `omp_set_num_threads` respectively. These ICVs affect the operation of `parallel` regions. Each implicit task generated by a `parallel` region has its own copy of the _nest-var, dyn-var_ , and _nthreads-var_ ICVs. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the following example, the _nest-var_ , _max-active-levels-var_ , _dyn-var_ , and _nthreads-var_ ICVs are modified through calls to the runtime library routines `omp_set_nested` , `omp_set_max_active_levels` , ` omp_set_dynamic` , and `omp_set_num_threads` respectively. These ICVs affect the operation of `parallel` regions. Each implicit task generated by a `parallel` region has its own copy of the _nest-var, dyn-var_ , and _nthreads-var_ ICVs. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the following example, the new value of _nthreads-var_ applies only to the implicit tasks that execute the call to `omp_set_num_threads` . There is one copy of the _max-active-levels-var_ ICV for the whole program and its value is the same for all tasks. This example assumes that nested parallelism is supported. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the following example, the new value of _nthreads-var_ applies only to the implicit tasks that execute the call to `omp_set_num_threads` . There is one copy of the _max-active-levels-var_ ICV for the whole program and its value is the same for all tasks. This example assumes that nested parallelism is supported. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The outer `parallel` region creates a team of two threads; each of the threads will execute one of the two implicit tasks generated by the outer `parallel` region. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The outer `parallel` region creates a team of two threads; each of the threads will execute one of the two implicit tasks generated by the outer `parallel` region. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Each implicit task generated by the outer `parallel` region calls `omp_set_num_threads(3)` , assigning the value 3 to its respective copy of _nthreads-var_ . Then each implicit task encounters an inner `parallel` region that creates a team of three threads; each of the threads will execute one of the three implicit tasks generated by that inner `parallel` region. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Each implicit task generated by the outer `parallel` region calls `omp_set_num_threads(3)` , assigning the value 3 to its respective copy of _nthreads-var_ . Then each implicit task encounters an inner `parallel` region that creates a team of three threads; each of the threads will execute one of the three implicit tasks generated by that inner `parallel` region. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Since the outer `parallel` region is executed by 2 threads, and the inner by 3, there will be a total of 6 implicit tasks generated by the two inner `parallel` regions. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Since the outer `parallel` region is executed by 2 threads, and the inner by 3, there will be a total of 6 implicit tasks generated by the two inner `parallel` regions. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Each implicit task generated by an inner `parallel` region will execute the call to `omp_set_num_threads(4)` , assigning the value 4 to its respective copy of _nthreads-var_ . " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Each implicit task generated by an inner `parallel` region will execute the call to `omp_set_num_threads(4)` , assigning the value 4 to its respective copy of _nthreads-var_ . " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The print statement in the outer `parallel` region is executed by only one of the threads in the team. So it will be executed only once. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The print statement in the outer `parallel` region is executed by only one of the threads in the team. So it will be executed only once. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The print statement in an inner `parallel` region is also executed by only one of the threads in the team. Since we have a total of two inner `parallel` regions, the print statement will be executed twice -- once per inner `parallel` region. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The print statement in an inner `parallel` region is also executed by only one of the threads in the team. Since we have a total of two inner `parallel` regions, the print statement will be executed twice -- once per inner `parallel` region. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_icv.1.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_icv.1.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_icv.1.f " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_icv.1.f " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end--- " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_init_lock.ipynb b/notebook/Examples_init_lock.ipynb index 4f87cbb..416f7ae 100644 --- a/notebook/Examples_init_lock.ipynb +++ b/notebook/Examples_init_lock.ipynb @@ -1,42 +1,42 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### The `omp_init_lock` Routine " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### The `omp_init_lock` Routine " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example demonstrates how to initialize an array of locks in a `parallel` region by using `omp_init_lock` . " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example demonstrates how to initialize an array of locks in a `parallel` region by using `omp_init_lock` . " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_init_lock.1.cpp " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_init_lock.1.cpp " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_init_lock.1.f " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_init_lock.1.f " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end--- " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_init_lock_with_hint.ipynb b/notebook/Examples_init_lock_with_hint.ipynb index 5326a89..919c418 100644 --- a/notebook/Examples_init_lock_with_hint.ipynb +++ b/notebook/Examples_init_lock_with_hint.ipynb @@ -1,43 +1,43 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", " #### The `omp_init_lock_with_hint` Routine " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example demonstrates how to initialize an array of locks in a `parallel` region by using `omp_init_lock_with_hint` . Note, hints are combined with an `|` or `+` operator in C/C++ and a `+` operator in Fortran. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example demonstrates how to initialize an array of locks in a `parallel` region by using `omp_init_lock_with_hint` . Note, hints are combined with an `|` or `+` operator in C/C++ and a `+` operator in Fortran. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_init_lock_with_hint.1.cpp " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_init_lock_with_hint.1.cpp " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_init_lock_with_hint.1.f " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_init_lock_with_hint.1.f " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end--- " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_lastprivate.ipynb b/notebook/Examples_lastprivate.ipynb index bf7e62f..339f446 100644 --- a/notebook/Examples_lastprivate.ipynb +++ b/notebook/Examples_lastprivate.ipynb @@ -1,42 +1,42 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### The `lastprivate` Clause " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### The `lastprivate` Clause " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Correct execution sometimes depends on the value that the last iteration of a loop assigns to a variable. Such programs must list all such variables in a `lastprivate` clause so that the values of the variables are the same as when the loop is executed sequentially. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Correct execution sometimes depends on the value that the last iteration of a loop assigns to a variable. Such programs must list all such variables in a `lastprivate` clause so that the values of the variables are the same as when the loop is executed sequentially. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_lastprivate.1.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_lastprivate.1.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_lastprivate.1.f " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_lastprivate.1.f " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end--- " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_linear_in_loop.ipynb b/notebook/Examples_linear_in_loop.ipynb index f838186..05fc557 100644 --- a/notebook/Examples_linear_in_loop.ipynb +++ b/notebook/Examples_linear_in_loop.ipynb @@ -1,42 +1,42 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### `linear` Clause in Loop Constructs " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### `linear` Clause in Loop Constructs " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows the use of the `linear` clause in a loop construct to allow the proper parallelization of a loop that contains an induction variable ( _j_ ). At the end of the execution of the loop construct, the original variable _j_ is updated with the value _N/2_ from the last iteration of the loop. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows the use of the `linear` clause in a loop construct to allow the proper parallelization of a loop that contains an induction variable ( _j_ ). At the end of the execution of the loop construct, the original variable _j_ is updated with the value _N/2_ from the last iteration of the loop. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_linear_in_loop.1.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_linear_in_loop.1.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_linear_in_loop.1.f90 " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_linear_in_loop.1.f90 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end--- " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_lock_owner.ipynb b/notebook/Examples_lock_owner.ipynb index e18505a..16ff0b9 100644 --- a/notebook/Examples_lock_owner.ipynb +++ b/notebook/Examples_lock_owner.ipynb @@ -1,49 +1,49 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### Ownership of Locks " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### Ownership of Locks " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Ownership of locks has changed since OpenMP 2.5. In OpenMP 2.5, locks are owned by threads; so a lock released by the `omp_unset_lock` routine must be owned by the same thread executing the routine. Beginning with OpenMP 3.0, locks are owned by task regions; so a lock released by the `omp_unset_lock` routine in a task region must be owned by the same task region. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Ownership of locks has changed since OpenMP 2.5. In OpenMP 2.5, locks are owned by threads; so a lock released by the `omp_unset_lock` routine must be owned by the same thread executing the routine. Beginning with OpenMP 3.0, locks are owned by task regions; so a lock released by the `omp_unset_lock` routine in a task region must be owned by the same task region. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " This change in ownership requires extra care when using locks. The following program is conforming in OpenMP 2.5 because the thread that releases the lock `lck` in the parallel region is the same thread that acquired the lock in the sequential part of the program (master thread of parallel region and the initial thread are the same). However, it is not conforming beginning with OpenMP 3.0, because the task region that releases the lock `lck` is different from the task region that acquires the lock. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " This change in ownership requires extra care when using locks. The following program is conforming in OpenMP 2.5 because the thread that releases the lock `lck` in the parallel region is the same thread that acquired the lock in the sequential part of the program (master thread of parallel region and the initial thread are the same). However, it is not conforming beginning with OpenMP 3.0, because the task region that releases the lock `lck` is different from the task region that acquires the lock. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_lock_owner.1.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_lock_owner.1.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_lock_owner.1.f " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_lock_owner.1.f " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end--- " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_locks.ipynb b/notebook/Examples_locks.ipynb index c8cab0a..d1aeef6 100644 --- a/notebook/Examples_locks.ipynb +++ b/notebook/Examples_locks.ipynb @@ -1,24 +1,24 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Lock Routines " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Lock Routines " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " This section is about the use of lock routines for synchronization. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " This section is about the use of lock routines for synchronization. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end--- " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_master.ipynb b/notebook/Examples_master.ipynb index 71c2112..2e3d800 100644 --- a/notebook/Examples_master.ipynb +++ b/notebook/Examples_master.ipynb @@ -1,42 +1,42 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### The `master` Construct " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### The `master` Construct " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example demonstrates the master construct . In the example, the master keeps track of how many iterations have been executed and prints out a progress report. The other threads skip the master region without waiting. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example demonstrates the master construct . In the example, the master keeps track of how many iterations have been executed and prints out a progress report. The other threads skip the master region without waiting. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_master.1.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_master.1.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_master.1.f " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_master.1.f " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end--- " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_mem_model.ipynb b/notebook/Examples_mem_model.ipynb index 0050170..6b0a0ab 100644 --- a/notebook/Examples_mem_model.ipynb +++ b/notebook/Examples_mem_model.ipynb @@ -1,99 +1,99 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### The OpenMP Memory Model " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### The OpenMP Memory Model " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the following example, at Print 1, the value of _x_ could be either 2 or 5, depending on the timing of the threads, and the implementation of the assignment to _x_ . There are two reasons that the value at Print 1 might not be 5. First, Print 1 might be executed before the assignment to _x_ is executed. Second, even if Print 1 is executed after the assignment, the value 5 is not guaranteed to be seen by thread 1 because a flush may not have been executed by thread 0 since the assignment. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the following example, at Print 1, the value of _x_ could be either 2 or 5, depending on the timing of the threads, and the implementation of the assignment to _x_ . There are two reasons that the value at Print 1 might not be 5. First, Print 1 might be executed before the assignment to _x_ is executed. Second, even if Print 1 is executed after the assignment, the value 5 is not guaranteed to be seen by thread 1 because a flush may not have been executed by thread 0 since the assignment. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The barrier after Print 1 contains implicit flushes on all threads, as well as a thread synchronization, so the programmer is guaranteed that the value 5 will be printed by both Print 2 and Print 3. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The barrier after Print 1 contains implicit flushes on all threads, as well as a thread synchronization, so the programmer is guaranteed that the value 5 will be printed by both Print 2 and Print 3. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_mem_model.1.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_mem_model.1.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_mem_model.1.f90 " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_mem_model.1.f90 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example demonstrates why synchronization is difficult to perform correctly through variables. The value of flag is undefined in both prints on thread 1 and the value of data is only well-defined in the second print. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example demonstrates why synchronization is difficult to perform correctly through variables. The value of flag is undefined in both prints on thread 1 and the value of data is only well-defined in the second print. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_mem_model.2.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_mem_model.2.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_mem_model.2.f " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_mem_model.2.f " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The next example demonstrates why synchronization is difficult to perform correctly through variables. Because the _write_ (1)- _flush_ (1)- _flush_ (2)- _read_ (2) sequence cannot be guaranteed in the example, the statements on thread 0 and thread 1 may execute in either order. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The next example demonstrates why synchronization is difficult to perform correctly through variables. Because the _write_ (1)- _flush_ (1)- _flush_ (2)- _read_ (2) sequence cannot be guaranteed in the example, the statements on thread 0 and thread 1 may execute in either order. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_mem_model.3.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_mem_model.3.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_mem_model.3.f " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_mem_model.3.f " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end--- " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_nestable_lock.ipynb b/notebook/Examples_nestable_lock.ipynb index 68b19be..daa2965 100644 --- a/notebook/Examples_nestable_lock.ipynb +++ b/notebook/Examples_nestable_lock.ipynb @@ -1,42 +1,42 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### Nestable Lock Routines " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### Nestable Lock Routines " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example demonstrates how a nestable lock can be used to synchronize updates both to a whole structure and to one of its members. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example demonstrates how a nestable lock can be used to synchronize updates both to a whole structure and to one of its members. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_nestable_lock.1.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_nestable_lock.1.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_nestable_lock.1.f " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_nestable_lock.1.f " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end--- " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_nested_loop.ipynb b/notebook/Examples_nested_loop.ipynb index 82e9c05..9e9e29a 100644 --- a/notebook/Examples_nested_loop.ipynb +++ b/notebook/Examples_nested_loop.ipynb @@ -1,67 +1,67 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Nested Loop Constructs " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Nested Loop Constructs " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example of loop construct nesting is conforming because the inner and outer loop regions bind to different `parallel` regions: " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example of loop construct nesting is conforming because the inner and outer loop regions bind to different `parallel` regions: " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_nested_loop.1.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_nested_loop.1.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_nested_loop.1.f " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_nested_loop.1.f " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following variation of the preceding example is also conforming: " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following variation of the preceding example is also conforming: " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_nested_loop.2.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_nested_loop.2.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_nested_loop.2.f " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_nested_loop.2.f " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end--- " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_nesting_restrict.ipynb b/notebook/Examples_nesting_restrict.ipynb index 7666764..41d29b5 100644 --- a/notebook/Examples_nesting_restrict.ipynb +++ b/notebook/Examples_nesting_restrict.ipynb @@ -1,174 +1,174 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Restrictions on Nesting of Regions " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Restrictions on Nesting of Regions " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The examples in this section illustrate the region nesting rules. " - ] + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The examples in this section illustrate the region nesting rules. " + ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example is non-conforming because the inner and outer loop regions are closely nested: " - ] + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example is non-conforming because the inner and outer loop regions are closely nested: " + ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_nesting_restrict.1.c " - ] + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_nesting_restrict.1.c " + ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_nesting_restrict.1.f " - ] + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_nesting_restrict.1.f " + ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following orphaned version of the preceding example is also non-conforming: " - ] + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following orphaned version of the preceding example is also non-conforming: " + ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_nesting_restrict.2.c " - ] + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_nesting_restrict.2.c " + ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_nesting_restrict.2.f " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example is non-conforming because the loop and `single` regions are closely nested: " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_nesting_restrict.3.c " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_nesting_restrict.3.f " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example is non-conforming because a `barrier` region cannot be closely nested inside a loop region: " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_nesting_restrict.4.c " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_nesting_restrict.4.f " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example is non-conforming because the `barrier` region cannot be closely nested inside the `critical` region. If this were permitted, it would result in deadlock due to the fact that only one thread at a time can enter the `critical` region: " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_nesting_restrict.5.c " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_nesting_restrict.5.f " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example is non-conforming because the `barrier` region cannot be closely nested inside the `single` region. If this were permitted, it would result in deadlock due to the fact that only one thread executes the `single` region: " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_nesting_restrict.6.c " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_nesting_restrict.6.f " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_nesting_restrict.2.f " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example is non-conforming because the loop and `single` regions are closely nested: " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_nesting_restrict.3.c " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_nesting_restrict.3.f " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example is non-conforming because a `barrier` region cannot be closely nested inside a loop region: " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_nesting_restrict.4.c " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_nesting_restrict.4.f " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example is non-conforming because the `barrier` region cannot be closely nested inside the `critical` region. If this were permitted, it would result in deadlock due to the fact that only one thread at a time can enter the `critical` region: " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_nesting_restrict.5.c " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_nesting_restrict.5.f " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example is non-conforming because the `barrier` region cannot be closely nested inside the `single` region. If this were permitted, it would result in deadlock due to the fact that only one thread executes the `single` region: " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_nesting_restrict.6.c " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_nesting_restrict.6.f " ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end--- " + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_nowait.ipynb b/notebook/Examples_nowait.ipynb index 1347094..7902e82 100644 --- a/notebook/Examples_nowait.ipynb +++ b/notebook/Examples_nowait.ipynb @@ -1,74 +1,74 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### The `nowait` Clause " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### The `nowait` Clause " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " If there are multiple independent loops within a `parallel` region, you can use the `nowait` clause to avoid the implied barrier at the end of the loop construct, as follows: " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " If there are multiple independent loops within a `parallel` region, you can use the `nowait` clause to avoid the implied barrier at the end of the loop construct, as follows: " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_nowait.1.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_nowait.1.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_nowait.1.f " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_nowait.1.f " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the following example, static scheduling distributes the same logical iteration numbers to the threads that execute the three loop regions. This allows the `nowait` clause to be used, even though there is a data dependence between the loops. The dependence is satisfied as long the same thread executes the same logical iteration numbers in each loop. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the following example, static scheduling distributes the same logical iteration numbers to the threads that execute the three loop regions. This allows the `nowait` clause to be used, even though there is a data dependence between the loops. The dependence is satisfied as long the same thread executes the same logical iteration numbers in each loop. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Note that the iteration count of the loops must be the same. The example satisfies this requirement, since the iteration space of the first two loops is from `0` to `n-1` (from `1` to `N` in the Fortran version), while the iteration space of the last loop is from `1` to `n` ( `2` to `N+1` in the Fortran version). " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Note that the iteration count of the loops must be the same. The example satisfies this requirement, since the iteration space of the first two loops is from `0` to `n-1` (from `1` to `N` in the Fortran version), while the iteration space of the last loop is from `1` to `n` ( `2` to `N+1` in the Fortran version). " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_nowait.2.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_nowait.2.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_nowait.2.f90 " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_nowait.2.f90 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end--- " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_nthrs_dynamic.ipynb b/notebook/Examples_nthrs_dynamic.ipynb index a1541ff..d5d4852 100644 --- a/notebook/Examples_nthrs_dynamic.ipynb +++ b/notebook/Examples_nthrs_dynamic.ipynb @@ -1,81 +1,81 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Interaction Between the `num_threads` Clause and `omp_set_dynamic` " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Interaction Between the `num_threads` Clause and `omp_set_dynamic` " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example demonstrates the `num_threads` clause and the effect of the `omp_set_dynamic` routine on it. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example demonstrates the `num_threads` clause and the effect of the `omp_set_dynamic` routine on it. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The call to the `omp_set_dynamic` routine with argument `0` in C/C++, or `.FALSE.` in Fortran, disables the dynamic adjustment of the number of threads in OpenMP implementations that support it. In this case, 10 threads are provided. Note that in case of an error the OpenMP implementation is free to abort the program or to supply any number of threads available. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The call to the `omp_set_dynamic` routine with argument `0` in C/C++, or `.FALSE.` in Fortran, disables the dynamic adjustment of the number of threads in OpenMP implementations that support it. In this case, 10 threads are provided. Note that in case of an error the OpenMP implementation is free to abort the program or to supply any number of threads available. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_nthrs_dynamic.1.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_nthrs_dynamic.1.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_nthrs_dynamic.1.f " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_nthrs_dynamic.1.f " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The call to the `omp_set_dynamic` routine with a non-zero argument in C/C++, or `.TRUE.` in Fortran, allows the OpenMP implementation to choose any number of threads between 1 and 10. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The call to the `omp_set_dynamic` routine with a non-zero argument in C/C++, or `.TRUE.` in Fortran, allows the OpenMP implementation to choose any number of threads between 1 and 10. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_nthrs_dynamic.2.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_nthrs_dynamic.2.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_nthrs_dynamic.2.f " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_nthrs_dynamic.2.f " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " It is good practice to set the _dyn-var_ ICV explicitly by calling the `omp_set_dynamic` routine, as its default setting is implementation defined. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " It is good practice to set the _dyn-var_ ICV explicitly by calling the `omp_set_dynamic` routine, as its default setting is implementation defined. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end--- " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_nthrs_nesting.ipynb b/notebook/Examples_nthrs_nesting.ipynb index ce4a796..6f1e2d8 100644 --- a/notebook/Examples_nthrs_nesting.ipynb +++ b/notebook/Examples_nthrs_nesting.ipynb @@ -1,42 +1,42 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Controlling the Number of Threads on Multiple Nesting Levels " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Controlling the Number of Threads on Multiple Nesting Levels " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following examples demonstrate how to use the `OMP_NUM_THREADS` environment variable to control the number of threads on multiple nesting levels: " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following examples demonstrate how to use the `OMP_NUM_THREADS` environment variable to control the number of threads on multiple nesting levels: " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_nthrs_nesting.1.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_nthrs_nesting.1.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_nthrs_nesting.1.f " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_nthrs_nesting.1.f " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end--- " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_ordered.ipynb b/notebook/Examples_ordered.ipynb index 972fa00..c702067 100644 --- a/notebook/Examples_ordered.ipynb +++ b/notebook/Examples_ordered.ipynb @@ -1,92 +1,92 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### The `ordered` Clause and the `ordered` Construct " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### The `ordered` Clause and the `ordered` Construct " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Ordered constructs are useful for sequentially ordering the output from work that is done in parallel. The following program prints out the indices in sequential order: " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Ordered constructs are useful for sequentially ordering the output from work that is done in parallel. The following program prints out the indices in sequential order: " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_ordered.1.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_ordered.1.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_ordered.1.f " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_ordered.1.f " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " It is possible to have multiple `ordered` constructs within a loop region with the `ordered` clause specified. The first example is non-conforming because all iterations execute two `ordered` regions. An iteration of a loop must not execute more than one `ordered` region: " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " It is possible to have multiple `ordered` constructs within a loop region with the `ordered` clause specified. The first example is non-conforming because all iterations execute two `ordered` regions. An iteration of a loop must not execute more than one `ordered` region: " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_ordered.2.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_ordered.2.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_ordered.2.f " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_ordered.2.f " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following is a conforming example with more than one `ordered` construct. Each iteration will execute only one `ordered` region: " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following is a conforming example with more than one `ordered` construct. Each iteration will execute only one `ordered` region: " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_ordered.3.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_ordered.3.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_ordered.3.f " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_ordered.3.f " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end--- " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_parallel.ipynb b/notebook/Examples_parallel.ipynb index 47a5c3b..645bc65 100644 --- a/notebook/Examples_parallel.ipynb +++ b/notebook/Examples_parallel.ipynb @@ -1,42 +1,42 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### The `parallel` Construct " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### The `parallel` Construct " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `parallel` construct can be used in coarse-grain parallel programs. In the following example, each thread in the `parallel` region decides what part of the global array _x_ to work on, based on the thread number: " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `parallel` construct can be used in coarse-grain parallel programs. In the following example, each thread in the `parallel` region decides what part of the global array _x_ to work on, based on the thread number: " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_parallel.1.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_parallel.1.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_parallel.1.f " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_parallel.1.f " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end--- " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_ploop.ipynb b/notebook/Examples_ploop.ipynb index b21ade4..211ce4c 100644 --- a/notebook/Examples_ploop.ipynb +++ b/notebook/Examples_ploop.ipynb @@ -1,42 +1,42 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### A Simple Parallel Loop " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### A Simple Parallel Loop " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example demonstrates how to parallelize a simple loop using the parallel loop construct. The loop iteration variable is private by default, so it is not necessary to specify it explicitly in a `private` clause. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example demonstrates how to parallelize a simple loop using the parallel loop construct. The loop iteration variable is private by default, so it is not necessary to specify it explicitly in a `private` clause. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_ploop.1.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_ploop.1.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_ploop.1.f " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_ploop.1.f " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end--- " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_pra_iterator.ipynb b/notebook/Examples_pra_iterator.ipynb index 29c9a62..6e1a8d3 100644 --- a/notebook/Examples_pra_iterator.ipynb +++ b/notebook/Examples_pra_iterator.ipynb @@ -1,51 +1,51 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Parallel Random Access Iterator Loop " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Parallel Random Access Iterator Loop " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_cppspecificstart " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_cppspecificstart " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows a parallel random access iterator loop. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows a parallel random access iterator loop. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_cppnexamplepra_iterator1 " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_cppnexamplepra_iterator1 " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_cppspecificend " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_cppspecificend " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end--- " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_private.ipynb b/notebook/Examples_private.ipynb index 3b1fe5e..4af810c 100644 --- a/notebook/Examples_private.ipynb +++ b/notebook/Examples_private.ipynb @@ -1,95 +1,95 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### The `private` Clause " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### The `private` Clause " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the following example, the values of original list items _i_ and _j_ are retained on exit from the `parallel` region, while the private list items _i_ and _j_ are modified within the `parallel` construct. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the following example, the values of original list items _i_ and _j_ are retained on exit from the `parallel` region, while the private list items _i_ and _j_ are modified within the `parallel` construct. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_private.1.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_private.1.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_private.1.f " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_private.1.f " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the following example, all uses of the variable _a_ within the loop construct in the routine _f_ refer to a private list \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the following example, all uses of the variable _a_ within the loop construct in the routine _f_ refer to a private list \n", "* _a_ , while it is unspecified whether references to _a_ in the routine _g_ are to a private list \n", "* or the original list item. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_private.2.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_private.2.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_private.2.f " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_private.2.f " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example demonstrates that a list \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example demonstrates that a list \n", "* that appears in a `private` clause in a `parallel` construct may also appear in a `private` clause in an enclosed worksharing construct, which results in an additional private copy. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_private.3.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_private.3.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_private.3.f " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_private.3.f " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end--- " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_psections.ipynb b/notebook/Examples_psections.ipynb index 0a689f1..ce59625 100644 --- a/notebook/Examples_psections.ipynb +++ b/notebook/Examples_psections.ipynb @@ -1,42 +1,42 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### The `parallel` `sections` Construct " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### The `parallel` `sections` Construct " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the following example routines `XAXIS` , `YAXIS` , and `ZAXIS` can be executed concurrently. The first `section` directive is optional. Note that all `section` directives need to appear in the `parallel sections` construct. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the following example routines `XAXIS` , `YAXIS` , and `ZAXIS` can be executed concurrently. The first `section` directive is optional. Note that all `section` directives need to appear in the `parallel sections` construct. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_psections.1.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_psections.1.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_psections.1.f " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_psections.1.f " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end--- " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_reduction.ipynb b/notebook/Examples_reduction.ipynb index 1007d2d..d53a7fb 100644 --- a/notebook/Examples_reduction.ipynb +++ b/notebook/Examples_reduction.ipynb @@ -1,187 +1,187 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### The `reduction` Clause " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example demonstrates the `reduction` clause ; note that some reductions can be expressed in the loop in several ways, as shown for the `max` and `min` reductions below: " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_reduction.1.c " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_reduction.1.f90 " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " A common implementation of the preceding example is to treat it as if it had been written as follows: " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_reduction.2.c " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " fortranspecificstartffreenexample{reduction}{2} " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following program is non-conforming because the reduction is on the emph{intrinsic procedure name} `MAX` but that name has been redefined to be the variable named `MAX` . " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_ffreenexamplereduction3 " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### The `reduction` Clause " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example demonstrates the `reduction` clause ; note that some reductions can be expressed in the loop in several ways, as shown for the `max` and `min` reductions below: " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_reduction.1.c " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_reduction.1.f90 " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " A common implementation of the preceding example is to treat it as if it had been written as follows: " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_reduction.2.c " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " fortranspecificstartffreenexample{reduction}{2} " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following program is non-conforming because the reduction is on the emph{intrinsic procedure name} `MAX` but that name has been redefined to be the variable named `MAX` . " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_ffreenexamplereduction3 " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", " blue line floater at top of this page for 'Fortran, cont.' [t!] linewitharrows{-1}{dashed}{Fortran (cont.)}{8em} " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following conforming program performs the reduction using the emph{intrinsic procedure name} `MAX` even though the intrinsic `MAX` has been renamed to `REN` . " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following conforming program performs the reduction using the emph{intrinsic procedure name} `MAX` even though the intrinsic `MAX` has been renamed to `REN` . " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_ffreenexamplereduction4 " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_ffreenexamplereduction4 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following conforming program performs the reduction using _intrinsic procedure name_ `MAX` even though the intrinsic `MAX` has been renamed to `MIN` . " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following conforming program performs the reduction using _intrinsic procedure name_ `MAX` even though the intrinsic `MAX` has been renamed to `MIN` . " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_ffreenexamplereduction5 " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_ffreenexamplereduction5 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " fortranspecificend " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " fortranspecificend " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example is non-conforming because the initialization ( `a = 0` ) of the original list \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example is non-conforming because the initialization ( `a = 0` ) of the original list \n", "* `a` is not synchronized with the update of `a` as a result of the reduction computation in the `for` loop. Therefore, the example may print an incorrect value for `a` . " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " To avoid this problem, the initialization of the original list \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " To avoid this problem, the initialization of the original list \n", "* `a` should complete before any update of `a` as a result of the `reduction` clause. This can be achieved by adding an explicit barrier after the assignment `a = 0` , or by enclosing the assignment `a = 0` in a `single` directive (which has an implied barrier), or by initializing `a` before the start of the `parallel` region. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_reduction.6.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_reduction.6.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_reduction.6.f " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_reduction.6.f " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example demonstrates the reduction of array _a_ . In C/C++ this is illustrated by the explicit use of an array section _a[0:N]_ in the `reduction` clause. The corresponding Fortran example uses array syntax supported in the base language. As of the OpenMP 4.5 specification the explicit use of array section in the `reduction` clause in Fortran is not permitted. But this oversight will be fixed in the next release of the specification. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example demonstrates the reduction of array _a_ . In C/C++ this is illustrated by the explicit use of an array section _a[0:N]_ in the `reduction` clause. The corresponding Fortran example uses array syntax supported in the base language. As of the OpenMP 4.5 specification the explicit use of array section in the `reduction` clause in Fortran is not permitted. But this oversight will be fixed in the next release of the specification. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_reduction.7.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_reduction.7.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_reduction.7.f90 " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_reduction.7.f90 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end--- " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_set_dynamic_nthrs.ipynb b/notebook/Examples_set_dynamic_nthrs.ipynb index 99e62cc..7be90ea 100644 --- a/notebook/Examples_set_dynamic_nthrs.ipynb +++ b/notebook/Examples_set_dynamic_nthrs.ipynb @@ -1,56 +1,56 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "section{The `omp_set_dynamic` and " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "section{The `omp_set_dynamic` and " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " `omp_set_num_threads` Routines} " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " `omp_set_num_threads` Routines} " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Some programs rely on a fixed, prespecified number of threads to execute correctly. Because the default setting for the dynamic adjustment of the number of threads is implementation defined, such programs can choose to turn off the dynamic threads capability and set the number of threads explicitly to ensure portability. The following example shows how to do this using `omp_set_dynamic` , and `omp_set_num_threads` . " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Some programs rely on a fixed, prespecified number of threads to execute correctly. Because the default setting for the dynamic adjustment of the number of threads is implementation defined, such programs can choose to turn off the dynamic threads capability and set the number of threads explicitly to ensure portability. The following example shows how to do this using `omp_set_dynamic` , and `omp_set_num_threads` . " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In this example, the program executes correctly only if it is executed by 16 threads. If the implementation is not capable of supporting 16 threads, the behavior of this example is implementation defined. Note that the number of threads executing a `parallel` region remains constant during the region, regardless of the dynamic threads setting. The dynamic threads mechanism determines the number of threads to use at the start of the `parallel` region and keeps it constant for the duration of the region. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In this example, the program executes correctly only if it is executed by 16 threads. If the implementation is not capable of supporting 16 threads, the behavior of this example is implementation defined. Note that the number of threads executing a `parallel` region remains constant during the region, regardless of the dynamic threads setting. The dynamic threads mechanism determines the number of threads to use at the start of the `parallel` region and keeps it constant for the duration of the region. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_set_dynamic_nthrs.1.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_set_dynamic_nthrs.1.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_set_dynamic_nthrs.1.f " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_set_dynamic_nthrs.1.f " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end--- " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_simple_lock.ipynb b/notebook/Examples_simple_lock.ipynb index b0700d3..b57b5fd 100644 --- a/notebook/Examples_simple_lock.ipynb +++ b/notebook/Examples_simple_lock.ipynb @@ -1,56 +1,56 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### Simple Lock Routines " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### Simple Lock Routines " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the following example, the lock routines cause the threads to be idle while waiting for entry to the first critical section, but to do other work while waiting for entry to the second. The `omp_set_lock` function blocks, but the `omp_test_lock` function does not, allowing the work in `skip` to be done. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the following example, the lock routines cause the threads to be idle while waiting for entry to the first critical section, but to do other work while waiting for entry to the second. The `omp_set_lock` function blocks, but the `omp_test_lock` function does not, allowing the work in `skip` to be done. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Note that the argument to the lock routines should have type `omp_lock_t` , and that there is no need to flush it. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Note that the argument to the lock routines should have type `omp_lock_t` , and that there is no need to flush it. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_simple_lock.1.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_simple_lock.1.c " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Note that there is no need to flush the lock variable. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Note that there is no need to flush the lock variable. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_simple_lock.1.f " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_simple_lock.1.f " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end--- " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_single.ipynb b/notebook/Examples_single.ipynb index 99f86ac..fe4c761 100644 --- a/notebook/Examples_single.ipynb +++ b/notebook/Examples_single.ipynb @@ -1,42 +1,42 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### The `single` Construct " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### The `single` Construct " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example demonstrates the `single` construct. In the example, only one thread prints each of the progress messages. All other threads will skip the `single` region and stop at the barrier at the end of the `single` construct until all threads in the team have reached the barrier. If other threads can proceed without waiting for the thread executing the `single` region, a `nowait` clause can be specified, as is done in the third `single` construct in this example. The user must not make any assumptions as to which thread will execute a `single` region. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example demonstrates the `single` construct. In the example, only one thread prints each of the progress messages. All other threads will skip the `single` region and stop at the barrier at the end of the `single` construct until all threads in the team have reached the barrier. If other threads can proceed without waiting for the thread executing the `single` region, a `nowait` clause can be specified, as is done in the third `single` construct in this example. The user must not make any assumptions as to which thread will execute a `single` region. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_single.1.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_single.1.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_single.1.f " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_single.1.f " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end--- " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_standalone.ipynb b/notebook/Examples_standalone.ipynb index 49a6cee..a9b1087 100644 --- a/notebook/Examples_standalone.ipynb +++ b/notebook/Examples_standalone.ipynb @@ -1,88 +1,88 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "section{Placement of `flush` , `barrier` , `taskwait` " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "section{Placement of `flush` , `barrier` , `taskwait` " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " and `taskyield` Directives} " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " and `taskyield` Directives} " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example is non-conforming, because the `flush` , `barrier` , `taskwait` , and `taskyield` directives are stand-alone directives and cannot be the immediate substatement of an `if` statement. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example is non-conforming, because the `flush` , `barrier` , `taskwait` , and `taskyield` directives are stand-alone directives and cannot be the immediate substatement of an `if` statement. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_standalone.1.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_standalone.1.c " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example is non-conforming, because the `flush` , `barrier` , `taskwait` , and `taskyield` directives are stand-alone directives and cannot be the action statement of an `if` statement or a labeled branch target. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example is non-conforming, because the `flush` , `barrier` , `taskwait` , and `taskyield` directives are stand-alone directives and cannot be the action statement of an `if` statement or a labeled branch target. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_standalone.1.f90 " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_standalone.1.f90 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following version of the above example is conforming because the `flush` , `barrier` , `taskwait` , and `taskyield` directives are enclosed in a compound statement. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following version of the above example is conforming because the `flush` , `barrier` , `taskwait` , and `taskyield` directives are enclosed in a compound statement. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_standalone.2.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_standalone.2.c " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example is conforming because the `flush` , `barrier` , `taskwait` , and `taskyield` directives are enclosed in an `if` construct or follow the labeled branch target. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example is conforming because the `flush` , `barrier` , `taskwait` , and `taskyield` directives are enclosed in an `if` construct or follow the labeled branch target. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_standalone.2.f90 " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_standalone.2.f90 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end--- " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_target.ipynb b/notebook/Examples_target.ipynb index 2d2dcef..f8c034e 100644 --- a/notebook/Examples_target.ipynb +++ b/notebook/Examples_target.ipynb @@ -1,267 +1,267 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### `target` Construct " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### `target` Construct " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### `target` Construct on `parallel` Construct " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### `target` Construct on `parallel` Construct " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " This following example shows how the `target` construct offloads a code region to a target device. The variables _p_ , _v1_ , _v2_ , and _N_ are implicitly mapped to the target device. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " This following example shows how the `target` construct offloads a code region to a target device. The variables _p_ , _v1_ , _v2_ , and _N_ are implicitly mapped to the target device. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target.1.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target.1.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target.1.f90 " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target.1.f90 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### `target` Construct with `map` Clause " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### `target` Construct with `map` Clause " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " This following example shows how the `target` construct offloads a code region to a target device. The variables _p_ , _v1_ and _v2_ are explicitly mapped to the target device using the `map` clause. The variable _N_ is implicitly mapped to the target device. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " This following example shows how the `target` construct offloads a code region to a target device. The variables _p_ , _v1_ and _v2_ are explicitly mapped to the target device using the `map` clause. The variable _N_ is implicitly mapped to the target device. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target.2.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target.2.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target.2.f90 " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target.2.f90 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### `map` Clause with `to` / `from` map-types " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### `map` Clause with `to` / `from` map-types " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows how the `target` construct offloads a code region to a target device. In the `map` clause, the `to` and `from` map-types define the mapping between the original (host) data and the target (device) data. The `to` map-type specifies that the data will only be read on the device, and the `from` map-type specifies that the data will only be written to on the device. By specifying a guaranteed access on the device, data transfers can be reduced for the `target` region. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows how the `target` construct offloads a code region to a target device. In the `map` clause, the `to` and `from` map-types define the mapping between the original (host) data and the target (device) data. The `to` map-type specifies that the data will only be read on the device, and the `from` map-type specifies that the data will only be written to on the device. By specifying a guaranteed access on the device, data transfers can be reduced for the `target` region. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `to` map-type indicates that at the start of the `target` region the variables _v1_ and _v2_ are initialized with the values of the corresponding variables on the host device, and at the end of the `target` region the variables _v1_ and _v2_ are not assigned to their corresponding variables on the host device. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `to` map-type indicates that at the start of the `target` region the variables _v1_ and _v2_ are initialized with the values of the corresponding variables on the host device, and at the end of the `target` region the variables _v1_ and _v2_ are not assigned to their corresponding variables on the host device. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `from` map-type indicates that at the start of the `target` region the variable _p_ is not initialized with the value of the corresponding variable on the host device, and at the end of the `target` region the variable _p_ is assigned to the corresponding variable on the host device. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `from` map-type indicates that at the start of the `target` region the variable _p_ is not initialized with the value of the corresponding variable on the host device, and at the end of the `target` region the variable _p_ is assigned to the corresponding variable on the host device. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target.3.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target.3.c " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `to` and `from` map-types allow programmers to optimize data motion. Since data for the _v_ arrays are not returned, and data for the _p_ array are not transferred to the device, only one-half of the data is moved, compared to the default behavior of an implicit mapping. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `to` and `from` map-types allow programmers to optimize data motion. Since data for the _v_ arrays are not returned, and data for the _p_ array are not transferred to the device, only one-half of the data is moved, compared to the default behavior of an implicit mapping. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target.3.f90 " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target.3.f90 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### `map` Clause with Array Sections " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### `map` Clause with Array Sections " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows how the `target` construct offloads a code region to a target device. In the `map` clause, map-types are used to optimize the mapping of variables to the target device. Because variables _p_ , _v1_ and _v2_ are pointers, array section notation must be used to map the arrays. The notation `:N` is equivalent to `0:N` . " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows how the `target` construct offloads a code region to a target device. In the `map` clause, map-types are used to optimize the mapping of variables to the target device. Because variables _p_ , _v1_ and _v2_ are pointers, array section notation must be used to map the arrays. The notation `:N` is equivalent to `0:N` . " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target.4.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target.4.c " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In C, the length of the pointed-to array must be specified. In Fortran the extent of the array is known and the length need not be specified. A section of the array can be specified with the usual Fortran syntax, as shown in the following example. The value 1 is assumed for the lower bound for array section _v2(:N)_ . " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In C, the length of the pointed-to array must be specified. In Fortran the extent of the array is known and the length need not be specified. A section of the array can be specified with the usual Fortran syntax, as shown in the following example. The value 1 is assumed for the lower bound for array section _v2(:N)_ . " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target.4.f90 " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target.4.f90 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " A more realistic situation in which an assumed-size array is passed to `vec_mult` requires that the length of the arrays be specified, because the compiler does not know the size of the storage. A section of the array must be specified with the usual Fortran syntax, as shown in the following example. The value 1 is assumed for the lower bound for array section _v2(:N)_ . " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " A more realistic situation in which an assumed-size array is passed to `vec_mult` requires that the length of the arrays be specified, because the compiler does not know the size of the storage. A section of the array must be specified with the usual Fortran syntax, as shown in the following example. The value 1 is assumed for the lower bound for array section _v2(:N)_ . " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target.4b.f90 " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target.4b.f90 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### `target` Construct with `if` Clause " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### `target` Construct with `if` Clause " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows how the `target` construct offloads a code region to a target device. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows how the `target` construct offloads a code region to a target device. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `if` clause on the `target` construct indicates that if the variable _N_ is smaller than a given threshold, then the `target` region will be executed by the host device. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `if` clause on the `target` construct indicates that if the variable _N_ is smaller than a given threshold, then the `target` region will be executed by the host device. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `if` clause on the `parallel` construct indicates that if the variable _N_ is smaller than a second threshold then the `parallel` region is inactive. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `if` clause on the `parallel` construct indicates that if the variable _N_ is smaller than a second threshold then the `parallel` region is inactive. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target.5.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target.5.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target.5.f90 " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target.5.f90 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example is a modification of the above _target.5_ code to show the combined `target` and parallel loop directives. It uses the _directive-name_ modifier in multiple `if` clauses to specify the component directive to which it applies. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example is a modification of the above _target.5_ code to show the combined `target` and parallel loop directives. It uses the _directive-name_ modifier in multiple `if` clauses to specify the component directive to which it applies. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `if` clause with the `target` modifier applies to the `target` component of the combined directive, and the `if` clause with the `parallel` modifier applies to the `parallel` component of the combined directive. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `if` clause with the `target` modifier applies to the `target` component of the combined directive, and the `if` clause with the `parallel` modifier applies to the `parallel` component of the combined directive. " ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target.6.c " + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target.6.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target.6.f90 " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target.6.f90 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end--- " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_target_data.ipynb b/notebook/Examples_target_data.ipynb index 6dd2515..dbb090e 100644 --- a/notebook/Examples_target_data.ipynb +++ b/notebook/Examples_target_data.ipynb @@ -1,325 +1,325 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### `target` `data` Construct " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### `target` `data` Construct " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### Simple `target` `data` Construct " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### Simple `target` `data` Construct " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " This example shows how the `target` `data` construct maps variables to a device data environment. The `target` `data` construct creates a new device data environment and maps the variables _v1_ , _v2_ , and _p_ to the new device data environment. The `target` construct enclosed in the `target` `data` region creates a new device data environment, which inherits the variables _v1_ , _v2_ , and _p_ from the enclosing device data environment. The variable _N_ is mapped into the new device data environment from the encountering task's data environment. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " This example shows how the `target` `data` construct maps variables to a device data environment. The `target` `data` construct creates a new device data environment and maps the variables _v1_ , _v2_ , and _p_ to the new device data environment. The `target` construct enclosed in the `target` `data` region creates a new device data environment, which inherits the variables _v1_ , _v2_ , and _p_ from the enclosing device data environment. The variable _N_ is mapped into the new device data environment from the encountering task's data environment. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target_data.1.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target_data.1.c " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The Fortran code passes a reference and specifies the extent of the arrays in the declaration. No length information is necessary in the map clause, as is required with C/C++ pointers. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The Fortran code passes a reference and specifies the extent of the arrays in the declaration. No length information is necessary in the map clause, as is required with C/C++ pointers. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target_data.1.f90 " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target_data.1.f90 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### `target` `data` Region Enclosing Multiple `target` Regions " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### `target` `data` Region Enclosing Multiple `target` Regions " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following examples show how the `target` `data` construct maps variables to a device data environment of a `target` region. The `target` `data` construct creates a device data environment and encloses `target` regions, which have their own device data environments. The device data environment of the `target` `data` region is inherited by the device data environment of an enclosed `target` region. The `target` `data` construct is used to create variables that will persist throughout the `target` `data` region. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following examples show how the `target` `data` construct maps variables to a device data environment of a `target` region. The `target` `data` construct creates a device data environment and encloses `target` regions, which have their own device data environments. The device data environment of the `target` `data` region is inherited by the device data environment of an enclosed `target` region. The `target` `data` construct is used to create variables that will persist throughout the `target` `data` region. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the following example the variables _v1_ and _v2_ are mapped at each `target` construct. Instead of mapping the variable _p_ twice, once at each `target` construct, _p_ is mapped once by the `target` `data` construct. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the following example the variables _v1_ and _v2_ are mapped at each `target` construct. Instead of mapping the variable _p_ twice, once at each `target` construct, _p_ is mapped once by the `target` `data` construct. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target_data.2.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target_data.2.c " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The Fortran code uses reference and specifies the extent of the _p_ , _v1_ and _v2_ arrays. No length information is necessary in the `map` clause, as is required with C/C++ pointers. The arrays _v1_ and _v2_ are mapped at each `target` construct. Instead of mapping the array _p_ twice, once at each target construct, _p_ is mapped once by the `target` `data` construct. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The Fortran code uses reference and specifies the extent of the _p_ , _v1_ and _v2_ arrays. No length information is necessary in the `map` clause, as is required with C/C++ pointers. The arrays _v1_ and _v2_ are mapped at each `target` construct. Instead of mapping the array _p_ twice, once at each target construct, _p_ is mapped once by the `target` `data` construct. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target_data.2.f90 " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target_data.2.f90 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the following example, the variable tmp defaults to `tofrom` map-type and is mapped at each `target` construct. The array _Q_ is mapped once at the enclosing `target` `data` region instead of at each `target` construct. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the following example, the variable tmp defaults to `tofrom` map-type and is mapped at each `target` construct. The array _Q_ is mapped once at the enclosing `target` `data` region instead of at each `target` construct. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target_data.3.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target_data.3.c " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the following example the arrays _v1_ and _v2_ are mapped at each `target` construct. Instead of mapping the array _Q_ twice at each `target` construct, _Q_ is mapped once by the `target` `data` construct. Note, the _tmp_ variable is implicitly remapped for each `target` region, mapping the value from the device to the host at the end of the first `target` region, and from the host to the device for the second `target` region. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the following example the arrays _v1_ and _v2_ are mapped at each `target` construct. Instead of mapping the array _Q_ twice at each `target` construct, _Q_ is mapped once by the `target` `data` construct. Note, the _tmp_ variable is implicitly remapped for each `target` region, mapping the value from the device to the host at the end of the first `target` region, and from the host to the device for the second `target` region. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target_data.3.f90 " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target_data.3.f90 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### `target` `data` Construct with Orphaned Call " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### `target` `data` Construct with Orphaned Call " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following two examples show how the `target` `data` construct maps variables to a device data environment. The `target` `data` construct's device data environment encloses the `target` construct's device data environment in the function `vec_mult()` . " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following two examples show how the `target` `data` construct maps variables to a device data environment. The `target` `data` construct's device data environment encloses the `target` construct's device data environment in the function `vec_mult()` . " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " When the type of the variable appearing in an array section is pointer, the pointer variable and the storage location of the corresponding array section are mapped to the device data environment. The pointer variable is treated as if it had appeared in a `map` clause with a map-type of `alloc` . The array section's storage location is mapped according to the map-type in the `map` clause (the default map-type is `tofrom` ). " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " When the type of the variable appearing in an array section is pointer, the pointer variable and the storage location of the corresponding array section are mapped to the device data environment. The pointer variable is treated as if it had appeared in a `map` clause with a map-type of `alloc` . The array section's storage location is mapped according to the map-type in the `map` clause (the default map-type is `tofrom` ). " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `target` construct's device data environment inherits the storage locations of the array sections _v1[0:N]_ , _v2[:n]_ , and _p0[0:N]_ from the enclosing target data construct's device data environment. Neither initialization nor assignment is performed for the array sections in the new device data environment. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `target` construct's device data environment inherits the storage locations of the array sections _v1[0:N]_ , _v2[:n]_ , and _p0[0:N]_ from the enclosing target data construct's device data environment. Neither initialization nor assignment is performed for the array sections in the new device data environment. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The pointer variables _p1_ , _v3_ , and _v4_ are mapped into the target construct's device data environment with an implicit map-type of alloc and they are assigned the address of the storage location associated with their corresponding array sections. Note that the following pairs of array section storage locations are equivalent ( _p0[:N]_ , _p1[:N]_ ), ( _v1[:N]_ , _v3[:N]_ ), and ( _v2[:N]_ , _v4[:N]_ ). " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The pointer variables _p1_ , _v3_ , and _v4_ are mapped into the target construct's device data environment with an implicit map-type of alloc and they are assigned the address of the storage location associated with their corresponding array sections. Note that the following pairs of array section storage locations are equivalent ( _p0[:N]_ , _p1[:N]_ ), ( _v1[:N]_ , _v3[:N]_ ), and ( _v2[:N]_ , _v4[:N]_ ). " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target_data.4.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target_data.4.c " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The Fortran code maps the pointers and storage in an identical manner (same extent, but uses indices from 1 to _N_ ). " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The Fortran code maps the pointers and storage in an identical manner (same extent, but uses indices from 1 to _N_ ). " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `target` construct's device data environment inherits the storage locations of the arrays _v1_ , _v2_ and _p0_ from the enclosing `target` `data` constructs's device data environment. However, in Fortran the associated data of the pointer is known, and the shape is not required. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `target` construct's device data environment inherits the storage locations of the arrays _v1_ , _v2_ and _p0_ from the enclosing `target` `data` constructs's device data environment. However, in Fortran the associated data of the pointer is known, and the shape is not required. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The pointer variables _p1_ , _v3_ , and _v4_ are mapped into the `target` construct's device data environment with an implicit map-type of `alloc` and they are assigned the address of the storage location associated with their corresponding array sections. Note that the following pair of array storage locations are equivalent ( _p0_ , _p1_ ), ( _v1_ , _v3_ ), and ( _v2_ , _v4_ ). " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The pointer variables _p1_ , _v3_ , and _v4_ are mapped into the `target` construct's device data environment with an implicit map-type of `alloc` and they are assigned the address of the storage location associated with their corresponding array sections. Note that the following pair of array storage locations are equivalent ( _p0_ , _p1_ ), ( _v1_ , _v3_ ), and ( _v2_ , _v4_ ). " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target_data.4.f90 " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target_data.4.f90 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the following example, the variables _p1_ , _v3_ , and _v4_ are references to the pointer variables _p0_ , _v1_ and _v2_ respectively. The `target` construct's device data environment inherits the pointer variables _p0_ , _v1_ , and _v2_ from the enclosing `target` `data` construct's device data environment. Thus, _p1_ , _v3_ , and _v4_ are already present in the device data environment. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the following example, the variables _p1_ , _v3_ , and _v4_ are references to the pointer variables _p0_ , _v1_ and _v2_ respectively. The `target` construct's device data environment inherits the pointer variables _p0_ , _v1_ , and _v2_ from the enclosing `target` `data` construct's device data environment. Thus, _p1_ , _v3_ , and _v4_ are already present in the device data environment. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target_data.5.cpp " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target_data.5.cpp " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the following example, the usual Fortran approach is used for dynamic memory. The _p0_ , _v1_ , and _v2_ arrays are allocated in the main program and passed as references from one routine to another. In `vec_mult` , _p1_ , _v3_ and _v4_ are references to the _p0_ , _v1_ , and _v2_ arrays, respectively. The `target` construct's device data environment inherits the arrays _p0_ , _v1_ , and _v2_ from the enclosing target data construct's device data environment. Thus, _p1_ , _v3_ , and _v4_ are already present in the device data environment. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the following example, the usual Fortran approach is used for dynamic memory. The _p0_ , _v1_ , and _v2_ arrays are allocated in the main program and passed as references from one routine to another. In `vec_mult` , _p1_ , _v3_ and _v4_ are references to the _p0_ , _v1_ , and _v2_ arrays, respectively. The `target` construct's device data environment inherits the arrays _p0_ , _v1_ , and _v2_ from the enclosing target data construct's device data environment. Thus, _p1_ , _v3_ , and _v4_ are already present in the device data environment. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target_data.5.f90 " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target_data.5.f90 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### `target` `data` Construct with `if` Clause " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### `target` `data` Construct with `if` Clause " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following two examples show how the `target` `data` construct maps variables to a device data environment. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following two examples show how the `target` `data` construct maps variables to a device data environment. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the following example, the if clause on the `target` `data` construct indicates that if the variable _N_ is smaller than a given threshold, then the `target` `data` construct will not create a device data environment. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the following example, the if clause on the `target` `data` construct indicates that if the variable _N_ is smaller than a given threshold, then the `target` `data` construct will not create a device data environment. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `target` constructs enclosed in the `target` `data` region must also use an `if` clause on the same condition, otherwise the pointer variable _p_ is implicitly mapped with a map-type of `tofrom` , but the storage location for the array section _p[0:N]_ will not be mapped in the device data environments of the `target` constructs. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `target` constructs enclosed in the `target` `data` region must also use an `if` clause on the same condition, otherwise the pointer variable _p_ is implicitly mapped with a map-type of `tofrom` , but the storage location for the array section _p[0:N]_ will not be mapped in the device data environments of the `target` constructs. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target_data.6.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target_data.6.c " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `if` clauses work the same way for the following Fortran code. The `target` constructs enclosed in the `target` `data` region should also use an `if` clause with the same condition, so that the `target` `data` region and the `target` region are either both created for the device, or are both ignored. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `if` clauses work the same way for the following Fortran code. The `target` constructs enclosed in the `target` `data` region should also use an `if` clause with the same condition, so that the `target` `data` region and the `target` region are either both created for the device, or are both ignored. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target_data.6.f90 " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target_data.6.f90 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the following example, when the `if` clause conditional expression on the `target` construct evaluates to _false_ , the target region will execute on the host device. However, the `target` `data` construct created an enclosing device data environment that mapped _p[0:N]_ to a device data environment on the default device. At the end of the `target` `data` region the array section _p[0:N]_ will be assigned from the device data environment to the corresponding variable in the data environment of the task that encountered the `target` `data` construct, resulting in undefined values in _p[0:N]_ . " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the following example, when the `if` clause conditional expression on the `target` construct evaluates to _false_ , the target region will execute on the host device. However, the `target` `data` construct created an enclosing device data environment that mapped _p[0:N]_ to a device data environment on the default device. At the end of the `target` `data` region the array section _p[0:N]_ will be assigned from the device data environment to the corresponding variable in the data environment of the task that encountered the `target` `data` construct, resulting in undefined values in _p[0:N]_ . " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target_data.7.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target_data.7.c " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `if` clauses work the same way for the following Fortran code. When the `if` clause conditional expression on the `target` construct evaluates to _false_ , the `target` region will execute on the host device. However, the `target` `data` construct created an enclosing device data environment that mapped the _p_ array (and _v1_ and _v2_ ) to a device data environment on the default target device. At the end of the `target` `data` region the _p_ array will be assigned from the device data environment to the corresponding variable in the data environment of the task that encountered the `target` `data` construct, resulting in undefined values in _p_ . " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `if` clauses work the same way for the following Fortran code. When the `if` clause conditional expression on the `target` construct evaluates to _false_ , the `target` region will execute on the host device. However, the `target` `data` construct created an enclosing device data environment that mapped the _p_ array (and _v1_ and _v2_ ) to a device data environment on the default target device. At the end of the `target` `data` region the _p_ array will be assigned from the device data environment to the corresponding variable in the data environment of the task that encountered the `target` `data` construct, resulting in undefined values in _p_ . " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target_data.7.f90 " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target_data.7.f90 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end--- " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_target_unstructured_data.ipynb b/notebook/Examples_target_unstructured_data.ipynb index 3010091..f28f0ce 100644 --- a/notebook/Examples_target_unstructured_data.ipynb +++ b/notebook/Examples_target_unstructured_data.ipynb @@ -1,103 +1,103 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", "begin " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### `target` `enter` `data` and `target` `exit` `data` Constructs " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### `target` `enter` `data` and `target` `exit` `data` Constructs " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", " ### Simple target enter data and target exit data Constructs " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The structured data construct ( `target` ~ `data` ) provides persistent data on a device for subsequent `target` constructs as shown in the `target` ~ `data` examples above. This is accomplished by creating a single `target` ~ `data` region containing `target` constructs. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The structured data construct ( `target` ~ `data` ) provides persistent data on a device for subsequent `target` constructs as shown in the `target` ~ `data` examples above. This is accomplished by creating a single `target` ~ `data` region containing `target` constructs. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The unstructured data constructs allow the creation and deletion of data on the device at any appropriate point within the host code, as shown below with the `target` ~ `enter` ~ `data` and `target` ~ `exit` ~ `data` constructs. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The unstructured data constructs allow the creation and deletion of data on the device at any appropriate point within the host code, as shown below with the `target` ~ `enter` ~ `data` and `target` ~ `exit` ~ `data` constructs. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following C++ code creates/deletes a vector in a constructor/destructor of a class. The constructor creates a vector with `target` ~ `enter` ~ `data` and uses an `alloc` modifier in the `map` clause to avoid copying values to the device. The destructor deletes the data ( `target` ~ `exit` ~ `data` ) and uses the `delete` modifier in the `map` clause to avoid copying data back to the host. Note, the stand-alone `target` ~ `enter` ~ `data` occurs after the host vector is created, and the `target` ~ `exit` ~ `data` construct occurs before the host data is deleted. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following C++ code creates/deletes a vector in a constructor/destructor of a class. The constructor creates a vector with `target` ~ `enter` ~ `data` and uses an `alloc` modifier in the `map` clause to avoid copying values to the device. The destructor deletes the data ( `target` ~ `exit` ~ `data` ) and uses the `delete` modifier in the `map` clause to avoid copying data back to the host. Note, the stand-alone `target` ~ `enter` ~ `data` occurs after the host vector is created, and the `target` ~ `exit` ~ `data` construct occurs before the host data is deleted. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target_unstructured_data.1.cpp " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target_unstructured_data.1.cpp " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following C code allocates and frees the data member of a Matrix structure. The `init_matrix` function allocates the memory used in the structure and uses the `target` ~ `enter` ~ `data` directive to map it to the target device. The `free_matrix` function removes the mapped array from the target device and then frees the memory on the host. Note, the stand-alone `target` ~ `enter` ~ `data` occurs after the host memory is allocated, and the `target` ~ `exit` ~ `data` construct occurs before the host data is freed. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following C code allocates and frees the data member of a Matrix structure. The `init_matrix` function allocates the memory used in the structure and uses the `target` ~ `enter` ~ `data` directive to map it to the target device. The `free_matrix` function removes the mapped array from the target device and then frees the memory on the host. Note, the stand-alone `target` ~ `enter` ~ `data` occurs after the host memory is allocated, and the `target` ~ `exit` ~ `data` construct occurs before the host data is freed. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target_unstructured_data.1.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target_unstructured_data.1.c " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following Fortran code allocates and deallocates a module array. The `initialize` subroutine allocates the module array and uses the `target` ~ `enter` ~ `data` directive to map it to the target device. The `finalize` subroutine removes the mapped array from the target device and then deallocates the array on the host. Note, the stand-alone `target` ~ `enter` ~ `data` occurs after the host memory is allocated, and the `target` ~ `exit` ~ `data` construct occurs before the host data is deallocated. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following Fortran code allocates and deallocates a module array. The `initialize` subroutine allocates the module array and uses the `target` ~ `enter` ~ `data` directive to map it to the target device. The `finalize` subroutine removes the mapped array from the target device and then deallocates the array on the host. Note, the stand-alone `target` ~ `enter` ~ `data` occurs after the host memory is allocated, and the `target` ~ `exit` ~ `data` construct occurs before the host data is deallocated. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target_unstructured_data.1.f90 " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target_unstructured_data.1.f90 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", "end " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end--- " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_target_update.ipynb b/notebook/Examples_target_update.ipynb index 21e05a4..967ac89 100644 --- a/notebook/Examples_target_update.ipynb +++ b/notebook/Examples_target_update.ipynb @@ -1,137 +1,137 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### `target` `update` Construct " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### `target` `update` Construct " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### Simple `target` `data` and `target` `update` Constructs " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### Simple `target` `data` and `target` `update` Constructs " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows how the `target` `update` construct updates variables in a device data environment. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows how the `target` `update` construct updates variables in a device data environment. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `target` `data` construct maps array sections _v1[:N]_ and _v2[:N]_ (arrays _v1_ and _v2_ in the Fortran code) into a device data environment. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `target` `data` construct maps array sections _v1[:N]_ and _v2[:N]_ (arrays _v1_ and _v2_ in the Fortran code) into a device data environment. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The task executing on the host device encounters the first `target` region and waits for the completion of the region. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The task executing on the host device encounters the first `target` region and waits for the completion of the region. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " After the execution of the first `target` region, the task executing on the host device then assigns new values to _v1[:N]_ and _v2[:N]_ ( _v1_ and _v2_ arrays in Fortran code) in the task's data environment by calling the function `init_again()` . " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " After the execution of the first `target` region, the task executing on the host device then assigns new values to _v1[:N]_ and _v2[:N]_ ( _v1_ and _v2_ arrays in Fortran code) in the task's data environment by calling the function `init_again()` . " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `target` `update` construct assigns the new values of _v1_ and _v2_ from the task's data environment to the corresponding mapped array sections in the device data environment of the `target` `data` construct. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `target` `update` construct assigns the new values of _v1_ and _v2_ from the task's data environment to the corresponding mapped array sections in the device data environment of the `target` `data` construct. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The task executing on the host device then encounters the second `target` region and waits for the completion of the region. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The task executing on the host device then encounters the second `target` region and waits for the completion of the region. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The second `target` region uses the updated values of _v1[:N]_ and _v2[:N]_ . " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The second `target` region uses the updated values of _v1[:N]_ and _v2[:N]_ . " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target_update.1.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target_update.1.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target_update.1.f90 " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target_update.1.f90 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### `target` `update` Construct with `if` Clause " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### `target` `update` Construct with `if` Clause " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows how the `target` `update` construct updates variables in a device data environment. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows how the `target` `update` construct updates variables in a device data environment. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `target` `data` construct maps array sections _v1[:N]_ and _v2[:N]_ (arrays _v1_ and _v2_ in the Fortran code) into a device data environment. In between the two `target` regions, the task executing on the host device conditionally assigns new values to _v1_ and _v2_ in the task's data environment. The function `maybe_init_again()` returns _true_ if new data is written. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `target` `data` construct maps array sections _v1[:N]_ and _v2[:N]_ (arrays _v1_ and _v2_ in the Fortran code) into a device data environment. In between the two `target` regions, the task executing on the host device conditionally assigns new values to _v1_ and _v2_ in the task's data environment. The function `maybe_init_again()` returns _true_ if new data is written. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " When the conditional expression (the return value of `maybe_init_again()` ) in the `if` clause is _true_ , the `target` `update` construct assigns the new values of _v1_ and _v2_ from the task's data environment to the corresponding mapped array sections in the `target` `data` construct's device data environment. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " When the conditional expression (the return value of `maybe_init_again()` ) in the `if` clause is _true_ , the `target` `update` construct assigns the new values of _v1_ and _v2_ from the task's data environment to the corresponding mapped array sections in the `target` `data` construct's device data environment. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target_update.2.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target_update.2.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target_update.2.f90 " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_target_update.2.f90 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end--- " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_task_dep.ipynb b/notebook/Examples_task_dep.ipynb index fc7aa47..11bbedf 100644 --- a/notebook/Examples_task_dep.ipynb +++ b/notebook/Examples_task_dep.ipynb @@ -1,205 +1,205 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Task Dependences " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Task Dependences " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### Flow Dependence " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### Flow Dependence " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In this example we show a simple flow dependence expressed using the `depend` clause on the `task` construct. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In this example we show a simple flow dependence expressed using the `depend` clause on the `task` construct. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_task_dep.1.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_task_dep.1.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_task_dep.1.f90 " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_task_dep.1.f90 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The program will always print ' x = 2 ' , because the `depend` clauses enforce the ordering of the tasks. If the `depend` clauses had been omitted, then the tasks could execute in any order and the program and the program would have a race condition. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The program will always print ' x = 2 ' , because the `depend` clauses enforce the ordering of the tasks. If the `depend` clauses had been omitted, then the tasks could execute in any order and the program and the program would have a race condition. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### Anti-dependence " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### Anti-dependence " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In this example we show an anti-dependence expressed using the `depend` clause on the `task` construct. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In this example we show an anti-dependence expressed using the `depend` clause on the `task` construct. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_task_dep.2.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_task_dep.2.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_task_dep.2.f90 " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_task_dep.2.f90 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The program will always print ' x = 1 ' , because the `depend` clauses enforce the ordering of the tasks. If the `depend` clauses had been omitted, then the tasks could execute in any order and the program would have a race condition. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The program will always print ' x = 1 ' , because the `depend` clauses enforce the ordering of the tasks. If the `depend` clauses had been omitted, then the tasks could execute in any order and the program would have a race condition. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### Output Dependence " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### Output Dependence " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In this example we show an output dependence expressed using the `depend` clause on the `task` construct. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In this example we show an output dependence expressed using the `depend` clause on the `task` construct. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_task_dep.3.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_task_dep.3.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_task_dep.3.f90 " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_task_dep.3.f90 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The program will always print ' x = 2 ' , because the `depend` clauses enforce the ordering of the tasks. If the `depend` clauses had been omitted, then the tasks could execute in any order and the program would have a race condition. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The program will always print ' x = 2 ' , because the `depend` clauses enforce the ordering of the tasks. If the `depend` clauses had been omitted, then the tasks could execute in any order and the program would have a race condition. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### Concurrent Execution with Dependences " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### Concurrent Execution with Dependences " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In this example we show potentially concurrent execution of tasks using multiple flow dependences expressed using the `depend` clause on the `task` construct. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In this example we show potentially concurrent execution of tasks using multiple flow dependences expressed using the `depend` clause on the `task` construct. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_task_dep.4.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_task_dep.4.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_task_dep.4.f90 " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_task_dep.4.f90 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The last two tasks are dependent on the first task. However there is no dependence between the last two tasks, which may execute in any order (or concurrently if more than one thread is available). Thus, the possible outputs are ' x + 1 = 3. x + 2 = 4. ' and ' x + 2 = 4. x + 1 = 3. ' . If the `depend` clauses had been omitted, then all of the tasks could execute in any order and the program would have a race condition. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The last two tasks are dependent on the first task. However there is no dependence between the last two tasks, which may execute in any order (or concurrently if more than one thread is available). Thus, the possible outputs are ' x + 1 = 3. x + 2 = 4. ' and ' x + 2 = 4. x + 1 = 3. ' . If the `depend` clauses had been omitted, then all of the tasks could execute in any order and the program would have a race condition. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### Matrix multiplication " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### Matrix multiplication " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " This example shows a task-based blocked matrix multiplication. Matrices are of NxN elements, and the multiplication is implemented using blocks of BSxBS elements. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " This example shows a task-based blocked matrix multiplication. Matrices are of NxN elements, and the multiplication is implemented using blocks of BSxBS elements. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_task_dep.5.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_task_dep.5.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_task_dep.5.f90 " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_task_dep.5.f90 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end--- " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_task_priority.ipynb b/notebook/Examples_task_priority.ipynb index 3cb4acd..4b63587 100644 --- a/notebook/Examples_task_priority.ipynb +++ b/notebook/Examples_task_priority.ipynb @@ -1,58 +1,58 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Task Priority " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Task Priority " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", " #### Task Priority \n", " " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In this example we compute arrays in a matrix through a _compute_array_ routine. Each task has a priority value equal to the value of the loop variable _i_ at the moment of its creation. A higher priority on a task means that a task is a candidate to run sooner. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In this example we compute arrays in a matrix through a _compute_array_ routine. Each task has a priority value equal to the value of the loop variable _i_ at the moment of its creation. A higher priority on a task means that a task is a candidate to run sooner. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The creation of tasks occurs in ascending order (according to the iteration space of the loop) but a hint, by means of the `priority` clause, is provided to reverse the execution order. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The creation of tasks occurs in ascending order (according to the iteration space of the loop) but a hint, by means of the `priority` clause, is provided to reverse the execution order. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_task_priority.1.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_task_priority.1.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_task_priority.1.f90 " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_task_priority.1.f90 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end--- " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_taskgroup.ipynb b/notebook/Examples_taskgroup.ipynb index ae6e358..06654c2 100644 --- a/notebook/Examples_taskgroup.ipynb +++ b/notebook/Examples_taskgroup.ipynb @@ -1,49 +1,49 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### The `taskgroup` Construct " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### The `taskgroup` Construct " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In this example, tasks are grouped and synchronized using the `taskgroup` construct. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In this example, tasks are grouped and synchronized using the `taskgroup` construct. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Initially, one task (the task executing the `start_background_work()` call) is created in the `parallel` region, and later a parallel tree traversal is started (the task executing the root of the recursive `compute_tree()` calls). While synchronizing tasks at the end of each tree traversal, using the `taskgroup` construct ensures that the formerly started background task does not participate in the synchronization, and is left free to execute in parallel. This is opposed to the behaviour of the `taskwait` construct, which would include the background tasks in the synchronization. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Initially, one task (the task executing the `start_background_work()` call) is created in the `parallel` region, and later a parallel tree traversal is started (the task executing the root of the recursive `compute_tree()` calls). While synchronizing tasks at the end of each tree traversal, using the `taskgroup` construct ensures that the formerly started background task does not participate in the synchronization, and is left free to execute in parallel. This is opposed to the behaviour of the `taskwait` construct, which would include the background tasks in the synchronization. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_taskgroup.1.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_taskgroup.1.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_taskgroup.1.f90 " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_taskgroup.1.f90 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end--- " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_tasking.ipynb b/notebook/Examples_tasking.ipynb index a245f12..13c10c5 100644 --- a/notebook/Examples_tasking.ipynb +++ b/notebook/Examples_tasking.ipynb @@ -1,402 +1,402 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### The `task` and `taskwait` Constructs " - ] + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### The `task` and `taskwait` Constructs " + ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows how to traverse a tree-like structure using explicit tasks. Note that the `traverse` function should be called from within a parallel region for the different specified tasks to be executed in parallel. Also note that the tasks will be executed in no specified order because there are no synchronization directives. Thus, assuming that the traversal will be done in post order, as in the sequential code, is wrong. " - ] + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows how to traverse a tree-like structure using explicit tasks. Note that the `traverse` function should be called from within a parallel region for the different specified tasks to be executed in parallel. Also note that the tasks will be executed in no specified order because there are no synchronization directives. Thus, assuming that the traversal will be done in post order, as in the sequential code, is wrong. " + ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_tasking.1.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_tasking.1.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_tasking.1.f90 " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the next example, we force a postorder traversal of the tree by adding a `taskwait` directive. Now, we can safely assume that the left and right sons have been executed before we process the current node. " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_tasking.1.f90 " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the next example, we force a postorder traversal of the tree by adding a `taskwait` directive. Now, we can safely assume that the left and right sons have been executed before we process the current node. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_tasking.2.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_tasking.2.c " ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_tasking.2.f90 " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example demonstrates how to use the `task` construct to process elements of a linked list in parallel. The thread executing the `single` region generates all of the explicit tasks, which are then executed by the threads in the current team. The pointer _p_ is `firstprivate` by default on the `task` construct so it is not necessary to specify it in a `firstprivate` clause. " + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_tasking.2.f90 " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example demonstrates how to use the `task` construct to process elements of a linked list in parallel. The thread executing the `single` region generates all of the explicit tasks, which are then executed by the threads in the current team. The pointer _p_ is `firstprivate` by default on the `task` construct so it is not necessary to specify it in a `firstprivate` clause. " ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_tasking.3.c " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_tasking.3.f90 " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `fib()` function should be called from within a `parallel` region for the different specified tasks to be executed in parallel. Also, only one thread of the `parallel` region should call `fib()` unless multiple concurrent Fibonacci computations are desired. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_tasking.4.c " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_tasking.4.f " + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_tasking.3.c " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_tasking.3.f90 " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `fib()` function should be called from within a `parallel` region for the different specified tasks to be executed in parallel. Also, only one thread of the `parallel` region should call `fib()` unless multiple concurrent Fibonacci computations are desired. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_tasking.4.c " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_tasking.4.f " ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Note: There are more efficient algorithms for computing Fibonacci numbers. This classic recursion algorithm is for illustrative purposes. " + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Note: There are more efficient algorithms for computing Fibonacci numbers. This classic recursion algorithm is for illustrative purposes. " ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example demonstrates a way to generate a large number of tasks with one thread and execute them with the threads in the team. While generating these tasks, the implementation may reach its limit on unassigned tasks. If it does, the implementation is allowed to cause the thread executing the task generating loop to suspend its task at the task scheduling point in the `task` directive, and start executing unassigned tasks. Once the number of unassigned tasks is sufficiently low, the thread may resume execution of the task generating loop. " + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example demonstrates a way to generate a large number of tasks with one thread and execute them with the threads in the team. While generating these tasks, the implementation may reach its limit on unassigned tasks. If it does, the implementation is allowed to cause the thread executing the task generating loop to suspend its task at the task scheduling point in the `task` directive, and start executing unassigned tasks. Once the number of unassigned tasks is sufficiently low, the thread may resume execution of the task generating loop. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_tasking.5.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_tasking.5.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_tasking.5.f " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_tasking.5.f " ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example is the same as the previous one, except that the tasks are generated in an untied task. While generating the tasks, the implementation may reach its limit on unassigned tasks. If it does, the implementation is allowed to cause the thread executing the task generating loop to suspend its task at the task scheduling point in the `task` directive, and start executing unassigned tasks. If that thread begins execution of a task that takes a long time to complete, the other threads may complete all the other tasks before it is finished. " + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example is the same as the previous one, except that the tasks are generated in an untied task. While generating the tasks, the implementation may reach its limit on unassigned tasks. If it does, the implementation is allowed to cause the thread executing the task generating loop to suspend its task at the task scheduling point in the `task` directive, and start executing unassigned tasks. If that thread begins execution of a task that takes a long time to complete, the other threads may complete all the other tasks before it is finished. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In this case, since the loop is in an untied task, any other thread is eligible to resume the task generating loop. In the previous examples, the other threads would be forced to idle until the generating thread finishes its long task, since the task generating loop was in a tied task. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In this case, since the loop is in an untied task, any other thread is eligible to resume the task generating loop. In the previous examples, the other threads would be forced to idle until the generating thread finishes its long task, since the task generating loop was in a tied task. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_tasking.6.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_tasking.6.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_tasking.6.f " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_tasking.6.f " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following two examples demonstrate how the scheduling rules illustrated in Section 2.11.3 of the OpenMP 4.0 specification affect the usage of `threadprivate` variables in tasks. A `threadprivate` variable can be modified by another task that is executed by the same thread. Thus, the value of a `threadprivate` variable cannot be assumed to be unchanged across a task scheduling point. In untied tasks, task scheduling points may be added in any place by the implementation. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following two examples demonstrate how the scheduling rules illustrated in Section 2.11.3 of the OpenMP 4.0 specification affect the usage of `threadprivate` variables in tasks. A `threadprivate` variable can be modified by another task that is executed by the same thread. Thus, the value of a `threadprivate` variable cannot be assumed to be unchanged across a task scheduling point. In untied tasks, task scheduling points may be added in any place by the implementation. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " A task switch may occur at a task scheduling point. A single thread may execute both of the task regions that modify `tp` . The parts of these task regions in which `tp` is modified may be executed in any order so the resulting value of `var` can be either 1 or 2. " - ] + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " A task switch may occur at a task scheduling point. A single thread may execute both of the task regions that modify `tp` . The parts of these task regions in which `tp` is modified may be executed in any order so the resulting value of `var` can be either 1 or 2. " + ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_tasking.7.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_tasking.7.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_tasking.7.f " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_tasking.7.f " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In this example, scheduling constraints prohibit a thread in the team from executing a new task that modifies `tp` while another such task region tied to the same thread is suspended. Therefore, the value written will persist across the task scheduling point. " - ] + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In this example, scheduling constraints prohibit a thread in the team from executing a new task that modifies `tp` while another such task region tied to the same thread is suspended. Therefore, the value written will persist across the task scheduling point. " + ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_tasking.8.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_tasking.8.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_tasking.8.f " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_tasking.8.f " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following two examples demonstrate how the scheduling rules illustrated in Section 2.11.3 of the OpenMP 4.0 specification affect the usage of locks and critical sections in tasks. If a lock is held across a task scheduling point, no attempt should be made to acquire the same lock in any code that may be interleaved. Otherwise, a deadlock is possible. " - ] + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following two examples demonstrate how the scheduling rules illustrated in Section 2.11.3 of the OpenMP 4.0 specification affect the usage of locks and critical sections in tasks. If a lock is held across a task scheduling point, no attempt should be made to acquire the same lock in any code that may be interleaved. Otherwise, a deadlock is possible. " + ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the example below, suppose the thread executing task 1 defers task 2. When it encounters the task scheduling point at task 3, it could suspend task 1 and begin task 2 which will result in a deadlock when it tries to enter critical region 1. " - ] + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the example below, suppose the thread executing task 1 defers task 2. When it encounters the task scheduling point at task 3, it could suspend task 1 and begin task 2 which will result in a deadlock when it tries to enter critical region 1. " + ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_tasking.9.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_tasking.9.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_tasking.9.f " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_tasking.9.f " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the following example, `lock` is held across a task scheduling point. However, according to the scheduling restrictions, the executing thread can't begin executing one of the non-descendant tasks that also acquires `lock` before the task region is complete. Therefore, no deadlock is possible. " - ] + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the following example, `lock` is held across a task scheduling point. However, according to the scheduling restrictions, the executing thread can't begin executing one of the non-descendant tasks that also acquires `lock` before the task region is complete. Therefore, no deadlock is possible. " + ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_tasking.10.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_tasking.10.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_tasking.10.f90 " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following examples illustrate the use of the `mergeable` clause in the `task` construct. In this first example, the `task` construct has been annotated with the `mergeable` clause. The addition of this clause allows the implementation to reuse the data environment (including the ICVs) of the parent task for the task inside `foo` if the task is included or undeferred. Thus, the result of the execution may differ depending on whether the task is merged or not. Therefore the mergeable clause needs to be used with caution. In this example, the use of the mergeable clause is safe. As `x` is a shared variable the outcome does not depend on whether or not the task is merged (that is, the task will always increment the same variable and will always compute the same value for `x` ). " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_tasking.10.f90 " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following examples illustrate the use of the `mergeable` clause in the `task` construct. In this first example, the `task` construct has been annotated with the `mergeable` clause. The addition of this clause allows the implementation to reuse the data environment (including the ICVs) of the parent task for the task inside `foo` if the task is included or undeferred. Thus, the result of the execution may differ depending on whether the task is merged or not. Therefore the mergeable clause needs to be used with caution. In this example, the use of the mergeable clause is safe. As `x` is a shared variable the outcome does not depend on whether or not the task is merged (that is, the task will always increment the same variable and will always compute the same value for `x` ). " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_tasking.11.c " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_tasking.11.f90 " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " This second example shows an incorrect use of the `mergeable` clause. In this example, the created task will access different instances of the variable `x` if the task is not merged, as `x` is `firstprivate` , but it will access the same variable `x` if the task is merged. As a result, the behavior of the program is unspecified and it can print two different values for `x` depending on the decisions taken by the implementation. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_tasking.12.c " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_tasking.12.f90 " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows the use of the `final` clause and the `omp_in_final` API call in a recursive binary search program. To reduce overhead, once a certain depth of recursion is reached the program uses the `final` clause to create only included tasks, which allow additional optimizations. " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The use of the `omp_in_final` API call allows programmers to optimize their code by specifying which parts of the program are not necessary when a task can create only included tasks (that is, the code is inside a `final` task). In this example, the use of a different state variable is not necessary so once the program reaches the part of the computation that is finalized and copying from the parent state to the new state is eliminated. The allocation of `new_state` in the stack could also be avoided but it would make this example less clear. The `final` clause is most effective when used in conjunction with the `mergeable` clause since all tasks created in a `final` task region are included tasks that can be merged if the `mergeable` clause is present. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_tasking.13.c " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_tasking.13.f90 " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example illustrates the difference between the `if` and the `final` clauses. The `if` clause has a local effect. In the first nest of tasks, the one that has the `if` clause will be undeferred but the task nested inside that task will not be affected by the `if` clause and will be created as usual. Alternatively, the `final` clause affects all `task` constructs in the `final` task region but not the `final` task itself. In the second nest of tasks, the nested tasks will be created as included tasks. Note also that the conditions for the `if` and `final` clauses are usually the opposite. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_tasking.14.c " - ] + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_tasking.11.c " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_tasking.11.f90 " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " This second example shows an incorrect use of the `mergeable` clause. In this example, the created task will access different instances of the variable `x` if the task is not merged, as `x` is `firstprivate` , but it will access the same variable `x` if the task is merged. As a result, the behavior of the program is unspecified and it can print two different values for `x` depending on the decisions taken by the implementation. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_tasking.12.c " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_tasking.12.f90 " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows the use of the `final` clause and the `omp_in_final` API call in a recursive binary search program. To reduce overhead, once a certain depth of recursion is reached the program uses the `final` clause to create only included tasks, which allow additional optimizations. " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The use of the `omp_in_final` API call allows programmers to optimize their code by specifying which parts of the program are not necessary when a task can create only included tasks (that is, the code is inside a `final` task). In this example, the use of a different state variable is not necessary so once the program reaches the part of the computation that is finalized and copying from the parent state to the new state is eliminated. The allocation of `new_state` in the stack could also be avoided but it would make this example less clear. The `final` clause is most effective when used in conjunction with the `mergeable` clause since all tasks created in a `final` task region are included tasks that can be merged if the `mergeable` clause is present. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_tasking.13.c " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_tasking.13.f90 " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example illustrates the difference between the `if` and the `final` clauses. The `if` clause has a local effect. In the first nest of tasks, the one that has the `if` clause will be undeferred but the task nested inside that task will not be affected by the `if` clause and will be created as usual. Alternatively, the `final` clause affects all `task` constructs in the `final` task region but not the `final` task itself. In the second nest of tasks, the nested tasks will be created as included tasks. Note also that the conditions for the `if` and `final` clauses are usually the opposite. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_tasking.14.c " + ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_tasking.14.f90 " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_tasking.14.f90 " ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end--- " + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_taskloop.ipynb b/notebook/Examples_taskloop.ipynb index 18521c7..e37d41e 100644 --- a/notebook/Examples_taskloop.ipynb +++ b/notebook/Examples_taskloop.ipynb @@ -1,45 +1,45 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### The `taskloop` Construct " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### The `taskloop` Construct " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example illustrates how to execute a long running task concurrently with tasks created with a `taskloop` directive for a loop having unbalanced amounts of work for its iterations. The `grainsize` clause specifies that each task is to execute at least 500 iterations of the loop. The `nogroup` clause removes the implicit taskgroup of the `taskloop` construct; the explicit `taskgroup` construct in the example ensures that the function is not exited before the long-running task and the loops have finished execution. cexample{taskloop}{1} " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example illustrates how to execute a long running task concurrently with tasks created with a `taskloop` directive for a loop having unbalanced amounts of work for its iterations. The `grainsize` clause specifies that each task is to execute at least 500 iterations of the loop. The `nogroup` clause removes the implicit taskgroup of the `taskloop` construct; the explicit `taskgroup` construct in the example ensures that the function is not exited before the long-running task and the loops have finished execution. cexample{taskloop}{1} " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ffreeexample{taskloop}{1} " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ffreeexample{taskloop}{1} " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end--- " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_taskyield.ipynb b/notebook/Examples_taskyield.ipynb index caf6c99..4a6abd4 100644 --- a/notebook/Examples_taskyield.ipynb +++ b/notebook/Examples_taskyield.ipynb @@ -1,42 +1,42 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### The `taskyield` Construct " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### The `taskyield` Construct " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example illustrates the use of the `taskyield` directive. The tasks in the example compute something useful and then do some computation that must be done in a critical region. By using `taskyield` when a task cannot get access to the `critical` region the implementation can suspend the current task and schedule some other task that can do something useful. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example illustrates the use of the `taskyield` directive. The tasks in the example compute something useful and then do some computation that must be done in a critical region. By using `taskyield` when a task cannot get access to the `critical` region the implementation can suspend the current task and schedule some other task that can do something useful. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_taskyield.1.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_taskyield.1.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_taskyield.1.f90 " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_taskyield.1.f90 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end--- " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_teams.ipynb b/notebook/Examples_teams.ipynb index b4e1c74..0ea7046 100644 --- a/notebook/Examples_teams.ipynb +++ b/notebook/Examples_teams.ipynb @@ -1,293 +1,293 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### `teams` Constructs " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### `teams` Constructs " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "subsection{ `target` and `teams` Constructs with `omp_get_num_teams` " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "subsection{ `target` and `teams` Constructs with `omp_get_num_teams` " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " and `omp_get_team_num` Routines} " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " and `omp_get_team_num` Routines} " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows how the `target` and `teams` constructs are used to create a league of thread teams that execute a region. The `teams` construct creates a league of at most two teams where the master thread of each team executes the `teams` region. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows how the `target` and `teams` constructs are used to create a league of thread teams that execute a region. The `teams` construct creates a league of at most two teams where the master thread of each team executes the `teams` region. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `omp_get_num_teams` routine returns the number of teams executing in a `teams` region. The `omp_get_team_num` routine returns the team number, which is an integer between 0 and one less than the value returned by `omp_get_num_teams` . The following example manually distributes a loop across two teams. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `omp_get_num_teams` routine returns the number of teams executing in a `teams` region. The `omp_get_team_num` routine returns the team number, which is an integer between 0 and one less than the value returned by `omp_get_num_teams` . The following example manually distributes a loop across two teams. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_teams.1.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_teams.1.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_teams.1.f90 " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_teams.1.f90 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### `target` , `teams` , and `distribute` Constructs " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### `target` , `teams` , and `distribute` Constructs " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows how the `target` , `teams` , and `distribute` constructs are used to execute a loop nest in a `target` region. The `teams` construct creates a league and the master thread of each team executes the `teams` region. The `distribute` construct schedules the subsequent loop iterations across the master threads of each team. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows how the `target` , `teams` , and `distribute` constructs are used to execute a loop nest in a `target` region. The `teams` construct creates a league and the master thread of each team executes the `teams` region. The `distribute` construct schedules the subsequent loop iterations across the master threads of each team. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The number of teams in the league is less than or equal to the variable _num_blocks_ . Each team in the league has a number of threads less than or equal to the variable _block_threads_ . The iterations in the outer loop are distributed among the master threads of each team. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The number of teams in the league is less than or equal to the variable _num_blocks_ . Each team in the league has a number of threads less than or equal to the variable _block_threads_ . The iterations in the outer loop are distributed among the master threads of each team. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " When a team's master thread encounters the parallel loop construct before the inner loop, the other threads in its team are activated. The team executes the `parallel` region and then workshares the execution of the loop. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " When a team's master thread encounters the parallel loop construct before the inner loop, the other threads in its team are activated. The team executes the `parallel` region and then workshares the execution of the loop. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Each master thread executing the `teams` region has a private copy of the variable _sum_ that is created by the `reduction` clause on the `teams` construct. The master thread and all threads in its team have a private copy of the variable _sum_ that is created by the `reduction` clause on the parallel loop construct. The second private _sum_ is reduced into the master thread's private copy of _sum_ created by the `teams` construct. At the end of the `teams` region, each master thread's private copy of _sum_ is reduced into the final _sum_ that is implicitly mapped into the `target` region. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Each master thread executing the `teams` region has a private copy of the variable _sum_ that is created by the `reduction` clause on the `teams` construct. The master thread and all threads in its team have a private copy of the variable _sum_ that is created by the `reduction` clause on the parallel loop construct. The second private _sum_ is reduced into the master thread's private copy of _sum_ created by the `teams` construct. At the end of the `teams` region, each master thread's private copy of _sum_ is reduced into the final _sum_ that is implicitly mapped into the `target` region. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_teams.2.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_teams.2.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_teams.2.f90 " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_teams.2.f90 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### `target` `teams` , and Distribute Parallel Loop Constructs " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### `target` `teams` , and Distribute Parallel Loop Constructs " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows how the `target` `teams` and distribute parallel loop constructs are used to execute a `target` region. The `target` `teams` construct creates a league of teams where the master thread of each team executes the `teams` region. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows how the `target` `teams` and distribute parallel loop constructs are used to execute a `target` region. The `target` `teams` construct creates a league of teams where the master thread of each team executes the `teams` region. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The distribute parallel loop construct schedules the loop iterations across the master threads of each team and then across the threads of each team. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The distribute parallel loop construct schedules the loop iterations across the master threads of each team and then across the threads of each team. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_teams.3.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_teams.3.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_teams.3.f90 " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_teams.3.f90 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "subsection{ `target` `teams` and Distribute Parallel Loop " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "subsection{ `target` `teams` and Distribute Parallel Loop " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Constructs with Scheduling Clauses} " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Constructs with Scheduling Clauses} " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows how the `target` `teams` and distribute parallel loop constructs are used to execute a `target` region. The `teams` construct creates a league of at most eight teams where the master thread of each team executes the `teams` region. The number of threads in each team is less than or equal to 16. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows how the `target` `teams` and distribute parallel loop constructs are used to execute a `target` region. The `teams` construct creates a league of at most eight teams where the master thread of each team executes the `teams` region. The number of threads in each team is less than or equal to 16. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `distribute` parallel loop construct schedules the subsequent loop iterations across the master threads of each team and then across the threads of each team. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `distribute` parallel loop construct schedules the subsequent loop iterations across the master threads of each team and then across the threads of each team. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `dist_schedule` clause on the distribute parallel loop construct indicates that loop iterations are distributed to the master thread of each team in chunks of 1024 iterations. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `dist_schedule` clause on the distribute parallel loop construct indicates that loop iterations are distributed to the master thread of each team in chunks of 1024 iterations. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `schedule` clause indicates that the 1024 iterations distributed to a master thread are then assigned to the threads in its associated team in chunks of 64 iterations. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `schedule` clause indicates that the 1024 iterations distributed to a master thread are then assigned to the threads in its associated team in chunks of 64 iterations. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_teams.4.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_teams.4.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_teams.4.f90 " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_teams.4.f90 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### `target` `teams` and `distribute` `simd` Constructs " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### `target` `teams` and `distribute` `simd` Constructs " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows how the `target` `teams` and `distribute` `simd` constructs are used to execute a loop in a `target` region. The `target` `teams` construct creates a league of teams where the master thread of each team executes the `teams` region. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows how the `target` `teams` and `distribute` `simd` constructs are used to execute a loop in a `target` region. The `target` `teams` construct creates a league of teams where the master thread of each team executes the `teams` region. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `distribute` `simd` construct schedules the loop iterations across the master thread of each team and then uses SIMD parallelism to execute the iterations. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The `distribute` `simd` construct schedules the loop iterations across the master thread of each team and then uses SIMD parallelism to execute the iterations. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_teams.5.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_teams.5.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_teams.5.f90 " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_teams.5.f90 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### `target` `teams` and Distribute Parallel Loop SIMD Constructs " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " #### `target` `teams` and Distribute Parallel Loop SIMD Constructs " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows how the `target` `teams` and the distribute parallel loop SIMD constructs are used to execute a loop in a `target` `teams` region. The `target` `teams` construct creates a league of teams where the master thread of each team executes the `teams` region. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows how the `target` `teams` and the distribute parallel loop SIMD constructs are used to execute a loop in a `target` `teams` region. The `target` `teams` construct creates a league of teams where the master thread of each team executes the `teams` region. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The distribute parallel loop SIMD construct schedules the loop iterations across the master thread of each team and then across the threads of each team where each thread uses SIMD parallelism. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The distribute parallel loop SIMD construct schedules the loop iterations across the master thread of each team and then across the threads of each team where each thread uses SIMD parallelism. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_teams.6.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_teams.6.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_teams.6.f90 " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_teams.6.f90 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end--- " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_threadprivate.ipynb b/notebook/Examples_threadprivate.ipynb index 8bfc4d2..a67a907 100644 --- a/notebook/Examples_threadprivate.ipynb +++ b/notebook/Examples_threadprivate.ipynb @@ -1,269 +1,269 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### The `threadprivate` Directive " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### The `threadprivate` Directive " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following examples demonstrate how to use the `threadprivate` directive to give each thread a separate counter. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following examples demonstrate how to use the `threadprivate` directive to give each thread a separate counter. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_threadprivate.1.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_threadprivate.1.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_threadprivate.1.f " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_threadprivate.1.f " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ccppspecificstart The following example uses `threadprivate` on a static variable: " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ccppspecificstart The following example uses `threadprivate` on a static variable: " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_threadprivate.2.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_threadprivate.2.c " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example demonstrates unspecified behavior for the initialization of a `threadprivate` variable. A `threadprivate` variable is initialized once at an unspecified point before its first reference. Because `a` is constructed using the value of `x` (which is modified by the statement `x++` ), the value of `a.val` at the start of the `parallel` region could be either 1 or 2. This problem is avoided for `b` , which uses an auxiliary `const` variable and a copy-constructor. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example demonstrates unspecified behavior for the initialization of a `threadprivate` variable. A `threadprivate` variable is initialized once at an unspecified point before its first reference. Because `a` is constructed using the value of `x` (which is modified by the statement `x++` ), the value of `a.val` at the start of the `parallel` region could be either 1 or 2. This problem is avoided for `b` , which uses an auxiliary `const` variable and a copy-constructor. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_cppnexamplethreadprivate3 " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_cppnexamplethreadprivate3 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ccppspecificend " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ccppspecificend " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following examples show non-conforming uses and correct uses of the `threadprivate` directive. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following examples show non-conforming uses and correct uses of the `threadprivate` directive. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " fortranspecificstart The following example is non-conforming because the common block is not declared local to the subroutine that refers to it: " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " fortranspecificstart The following example is non-conforming because the common block is not declared local to the subroutine that refers to it: " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_threadprivate.2.f " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_threadprivate.2.f " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example is also non-conforming because the common block is not declared local to the subroutine that refers to it: " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example is also non-conforming because the common block is not declared local to the subroutine that refers to it: " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_threadprivate.3.f " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_threadprivate.3.f " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example is a correct rewrite of the previous example: " - ] + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example is a correct rewrite of the previous example: " + ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_threadprivate.4.f " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_threadprivate.4.f " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following is an example of the use of `threadprivate` for local variables: \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following is an example of the use of `threadprivate` for local variables: \n", " blue line floater at top of this page for 'Fortran, cont.' [t!] linewitharrows{-1}{dashed}{Fortran (cont.)}{8em} " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_threadprivate.5.f " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_threadprivate.5.f " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The above program, if executed by two threads, will print one of the following two sets of output: " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The above program, if executed by two threads, will print one of the following two sets of output: " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " `a = 11 12 13` `ptr = 4` `i = 15` " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " `a = 11 12 13` `ptr = 4` `i = 15` " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " `A is not allocated` `ptr = 4` `i = 5` " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " `A is not allocated` `ptr = 4` `i = 5` " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " or " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " or " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " `A is not allocated` `ptr = 4` `i = 15` " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " `A is not allocated` `ptr = 4` `i = 15` " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " `a = 1 2 3` `ptr = 4` `i = 5` " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " `a = 1 2 3` `ptr = 4` `i = 5` " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following is an example of the use of `threadprivate` for module variables: \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following is an example of the use of `threadprivate` for module variables: \n", " blue line floater at top of this page for 'Fortran, cont.' [t!] linewitharrows{-1}{dashed}{Fortran (cont.)}{8em} " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_threadprivate.6.f " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_threadprivate.6.f " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " fortranspecificend " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " fortranspecificend " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_cppspecificstart " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_cppspecificstart " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example illustrates initialization of `threadprivate` variables for class-type `T` . `t1` is default constructed, `t2` is constructed taking a constructor accepting one argument of integer type, `t3` is copy constructed with argument `f()` : " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example illustrates initialization of `threadprivate` variables for class-type `T` . `t1` is default constructed, `t2` is constructed taking a constructor accepting one argument of integer type, `t3` is copy constructed with argument `f()` : " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_cppnexamplethreadprivate4 " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_cppnexamplethreadprivate4 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example illustrates the use of `threadprivate` for static class members. The `threadprivate` directive for a static class member must be placed inside the class definition. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example illustrates the use of `threadprivate` for static class members. The `threadprivate` directive for a static class member must be placed inside the class definition. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_cppnexamplethreadprivate5 " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_cppnexamplethreadprivate5 " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_cppspecificend " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_cppspecificend " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end--- " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_workshare.ipynb b/notebook/Examples_workshare.ipynb index 38d318c..2ac951a 100644 --- a/notebook/Examples_workshare.ipynb +++ b/notebook/Examples_workshare.ipynb @@ -1,180 +1,180 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### The `workshare` Construct " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### The `workshare` Construct " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " fortranspecificstart " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " fortranspecificstart " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following are examples of the `workshare` construct. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following are examples of the `workshare` construct. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the following example, `workshare` spreads work across the threads executing the `parallel` region, and there is a barrier after the last statement. Implementations must enforce Fortran execution rules inside of the `workshare` block. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the following example, `workshare` spreads work across the threads executing the `parallel` region, and there is a barrier after the last statement. Implementations must enforce Fortran execution rules inside of the `workshare` block. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_workshare.1.f " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_workshare.1.f " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the following example, the barrier at the end of the first `workshare` region is eliminated with a `nowait` clause. Threads doing `CC = DD` immediately begin work on `EE = FF` when they are done with `CC = DD` . " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the following example, the barrier at the end of the first `workshare` region is eliminated with a `nowait` clause. Threads doing `CC = DD` immediately begin work on `EE = FF` when they are done with `CC = DD` . " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_workshare.2.f " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_workshare.2.f " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", " blue line floater at top of this page for 'Fortran, cont.' [t!] linewitharrows{-1}{dashed}{Fortran (cont.)}{8em} " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows the use of an `atomic` directive inside a `workshare` construct. The computation of `SUM(AA)` is workshared, but the update to `R` is atomic. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example shows the use of an `atomic` directive inside a `workshare` construct. The computation of `SUM(AA)` is workshared, but the update to `R` is atomic. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_workshare.3.f " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_workshare.3.f " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Fortran `WHERE` and `FORALL` statements are emph{compound statements}, made up of a emph{control} part and a emph{statement} part. When `workshare` is applied to one of these compound statements, both the control and the statement parts are workshared. The following example shows the use of a `WHERE` statement in a `workshare` construct. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Fortran `WHERE` and `FORALL` statements are emph{compound statements}, made up of a emph{control} part and a emph{statement} part. When `workshare` is applied to one of these compound statements, both the control and the statement parts are workshared. The following example shows the use of a `WHERE` statement in a `workshare` construct. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Each task gets worked on in order by the threads: " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Each task gets worked on in order by the threads: " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " `AA = BB` then `CC = DD` then `EE .ne. 0` then `FF = 1 / EE` then `GG = HH` " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " `AA = BB` then `CC = DD` then `EE .ne. 0` then `FF = 1 / EE` then `GG = HH` " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_workshare.4.f " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_workshare.4.f " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", " blue line floater at top of this page for 'Fortran, cont.' [t!] linewitharrows{-1}{dashed}{Fortran (cont.)}{8em} " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the following example, an assignment to a shared scalar variable is performed by one thread in a `workshare` while all other threads in the team wait. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " In the following example, an assignment to a shared scalar variable is performed by one thread in a `workshare` while all other threads in the team wait. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_workshare.5.f " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_workshare.5.f " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example contains an assignment to a private scalar variable, which is performed by one thread in a `workshare` while all other threads wait. It is non-conforming because the private scalar variable is undefined after the assignment statement. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example contains an assignment to a private scalar variable, which is performed by one thread in a `workshare` while all other threads wait. It is non-conforming because the private scalar variable is undefined after the assignment statement. " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_workshare.6.f " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_workshare.6.f " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Fortran execution rules must be enforced inside a `workshare` construct. In the following example, the same result is produced in the following program fragment regardless of whether the code is executed sequentially or inside an OpenMP program with multiple threads: " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Fortran execution rules must be enforced inside a `workshare` construct. In the following example, the same result is produced in the following program fragment regardless of whether the code is executed sequentially or inside an OpenMP program with multiple threads: " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_workshare.7.f " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_workshare.7.f " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " fortranspecificend " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " fortranspecificend " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end--- " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Examples_worksharing_critical.ipynb b/notebook/Examples_worksharing_critical.ipynb index 5a788a6..059ff71 100644 --- a/notebook/Examples_worksharing_critical.ipynb +++ b/notebook/Examples_worksharing_critical.ipynb @@ -1,42 +1,42 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Worksharing Constructs Inside a `critical` Construct " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Worksharing Constructs Inside a `critical` Construct " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example demonstrates using a worksharing construct inside a `critical` construct. This example is conforming because the worksharing `single` region is not closely nested inside the `critical` region. A single thread executes the one and only section in the `sections` region, and executes the `critical` region. The same thread encounters the nested `parallel` region, creates a new team of threads, and becomes the master of the new team. One of the threads in the new team enters the `single` region and increments `i` by `1` . At the end of this example `i` is equal to `2` . " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The following example demonstrates using a worksharing construct inside a `critical` construct. This example is conforming because the worksharing `single` region is not closely nested inside the `critical` region. A single thread executes the one and only section in the `sections` region, and executes the `critical` region. The same thread encounters the nested `parallel` region, creates a new team of threads, and becomes the master of the new team. One of the threads in the new team enters the `single` region and increments `i` by `1` . At the end of this example `i` is equal to `2` . " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_worksharing_critical.1.c " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_worksharing_critical.1.c " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_worksharing_critical.1.f " + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load ../sources/Example_worksharing_critical.1.f " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end--- " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/History.ipynb b/notebook/History.ipynb index 3a999c0..495cc6f 100644 --- a/notebook/History.ipynb +++ b/notebook/History.ipynb @@ -1,24 +1,24 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ## Document Revision History " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ## Document Revision History " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Changes from 4.0.2 to 4.5.0 " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Changes from 4.0.2 to 4.5.0 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", "* Reorganized into chapters of major topics \n", "* Included file extensions in example labels to indicate source type \n", "* Applied the explicit `map(tofrom)` for scalar variables in a number of examples to comply with the change of the default behavior for scalar variables from `map(tofrom)` to `firstprivate` in the 4.5 specification \n", @@ -37,59 +37,59 @@ "* C++ reference types in data sharing clauses () " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Changes from 4.0.1 to 4.0.2 " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Changes from 4.0.1 to 4.0.2 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", "* Names of examples were changed from numbers to mnemonics \n", "* Added SIMD examples () \n", "* Applied miscellaneous fixes in several source codes \n", "* Added the revision history " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Changes from 4.0 to 4.0.1 " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Changes from 4.0 to 4.0.1 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Added the following new examples: \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Added the following new examples: \n", "* the `proc_bind` clause () \n", "* the `taskgroup` construct () " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Changes from 3.1 to 4.0 " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ### Changes from 3.1 to 4.0 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Beginning with OpenMP 4.0, examples were placed in a separate document from the specification document. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Beginning with OpenMP 4.0, examples were placed in a separate document from the specification document. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Version 4.0 added the following new examples: \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Version 4.0 added the following new examples: \n", "* task dependences () \n", "* `target` construct () \n", "* `target` `data` construct () \n", @@ -103,11 +103,11 @@ "* cancellation constructs () " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end--- " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Introduction_Chapt.ipynb b/notebook/Introduction_Chapt.ipynb index 8653146..3d70b55 100644 --- a/notebook/Introduction_Chapt.ipynb +++ b/notebook/Introduction_Chapt.ipynb @@ -1,10 +1,10 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", " This is the introduction for the OpenMP Examples document. \n", " This is an included file. See the master file (openmp-examples.tex) for more information. \n", " \n", @@ -42,83 +42,83 @@ " " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "chapter*{Introduction} " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "chapter*{Introduction} " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " addcontentsline{toc}{chapter}{protectnumberline{}Introduction} This collection of programming examples supplements the OpenMP API for Shared Memory Parallelization specifications, and is not part of the formal specifications. It assumes familiarity with the OpenMP specifications, and shares the typographical conventions used in that document. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " addcontentsline{toc}{chapter}{protectnumberline{}Introduction} This collection of programming examples supplements the OpenMP API for Shared Memory Parallelization specifications, and is not part of the formal specifications. It assumes familiarity with the OpenMP specifications, and shares the typographical conventions used in that document. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " notestart noteheader – This first release of the OpenMP Examples reflects the OpenMP Version 4.5 specifications. Additional examples are being developed and will be published in future releases of this document. noteend " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " notestart noteheader – This first release of the OpenMP Examples reflects the OpenMP Version 4.5 specifications. Additional examples are being developed and will be published in future releases of this document. noteend " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The OpenMP API specification provides a model for parallel programming that is portable across shared memory architectures from different vendors. Compilers from numerous vendors support the OpenMP API. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The OpenMP API specification provides a model for parallel programming that is portable across shared memory architectures from different vendors. Compilers from numerous vendors support the OpenMP API. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The directives, library routines, and environment variables demonstrated in this document allow users to create and manage parallel programs while permitting portability. The directives extend the C, C++ and Fortran base languages with single program multiple data (SPMD) constructs, tasking constructs, device constructs, worksharing constructs, and synchronization constructs, and they provide support for sharing and privatizing data. The functionality to control the runtime environment is provided by library routines and environment variables. Compilers that support the OpenMP API often include a command line option to the compiler that activates and allows interpretation of all OpenMP directives. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The directives, library routines, and environment variables demonstrated in this document allow users to create and manage parallel programs while permitting portability. The directives extend the C, C++ and Fortran base languages with single program multiple data (SPMD) constructs, tasking constructs, device constructs, worksharing constructs, and synchronization constructs, and they provide support for sharing and privatizing data. The functionality to control the runtime environment is provided by library routines and environment variables. Compilers that support the OpenMP API often include a command line option to the compiler that activates and allows interpretation of all OpenMP directives. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The latest source codes for OpenMP Examples can be downloaded from the `sources` directory at https://github.com/OpenMP/Examples The codes for this OpenMP VER{} Examples document have the tag _vVER_ . " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " The latest source codes for OpenMP Examples can be downloaded from the `sources` directory at https://github.com/OpenMP/Examples The codes for this OpenMP VER{} Examples document have the tag _vVER_ . " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", " https://github.com/OpenMP/Examples/tree/master/sources " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Complete information about the OpenMP API and a list of the compilers that support the OpenMP API can be found at the OpenMP.org web site " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Complete information about the OpenMP API and a list of the compilers that support the OpenMP API can be found at the OpenMP.org web site " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " `http://www.openmp.org` " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " `http://www.openmp.org` " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", " This is the end of introduction.tex of the OpenMP Examples document. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end--- " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/Title_Page.ipynb b/notebook/Title_Page.ipynb index bd43872..39a8d7b 100644 --- a/notebook/Title_Page.ipynb +++ b/notebook/Title_Page.ipynb @@ -1,10 +1,10 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", "\n", "\n", "\n", @@ -102,101 +102,101 @@ " Title page " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " hspace{-6em} includegraphics[width=0.4textwidth]{openmp-logo.png} " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " hspace{-6em} includegraphics[width=0.4textwidth]{openmp-logo.png} " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " {-0.75in}{0in} Huge textsf{OpenMPApplication ProgrammingInterface} " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " {-0.75in}{0in} Huge textsf{OpenMPApplication ProgrammingInterface} " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", " An optional subtitle can go here: vspace{0.5in}textsf{Examples}vspace{-0.7in} normalsize " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " vspace{1.0in} " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " vspace{1.0in} " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " textbf{Version VER{} -- VERDATE} " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " textbf{Version VER{} -- VERDATE} " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " vspace{2.3in} \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " vspace{2.3in} \n", "was 3.0 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Source codes for OpenMP VER{} Examples can be downloaded from https://github.com/OpenMP/Examples/tree/vVER {github}. " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Source codes for OpenMP VER{} Examples can be downloaded from https://github.com/OpenMP/Examples/tree/vVER {github}. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " {0pt}{1em}setlength{parskip}{0.25baselineskip}\n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " {0pt}{1em}setlength{parskip}{0.25baselineskip}\n", " Copyright © 1997-2016 OpenMP Architecture Review Board. Permission to copy without fee all or part of this material is granted, provided the OpenMP Architecture Review Board copyright notice and the title of this document appear. Notice is given that copying is by permission of OpenMP Architecture Review Board. " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", " Blank page " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " clearpage thispagestyle{empty} phantom{a} emph{This page intentionally left blank} " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " clearpage thispagestyle{empty} phantom{a} emph{This page intentionally left blank} " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", "This working version enacted the following tickets: 180, 295, 299, 342, 381, \n", "and a few other editorial changes. vfill " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end--- " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/openmp-examples.ipynb b/notebook/openmp-examples.ipynb index 29f7c60..6c35158 100644 --- a/notebook/openmp-examples.ipynb +++ b/notebook/openmp-examples.ipynb @@ -1,10 +1,10 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", " Welcome to openmp-examples.tex. \n", " This is the master LaTex file for the OpenMP Examples document. \n", " \n", @@ -54,108 +54,108 @@ " " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", " The following says letter size, but the style sheet may change the size documentclass[10pt,letterpaper,twoside,makeidx,hidelinks]{scrreprt} " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", " Text to appear in the footer on even-numbered pages: newcommand{VER}{4.5.0} newcommand{VERDATE}{November 2016} newcommand{footerText}{OpenMP Examples Version VER{} - VERDATE} " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", " Unified style sheet for OpenMP documents: input{openmp.sty} " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " pagenumbering{roman} input{Title_Page} " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " pagenumbering{roman} input{Title_Page} " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " setcounter{page}{0} setcounter{tocdepth}{2} " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " setcounter{page}{0} setcounter{tocdepth}{2} " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " {1.3} tableofcontents " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " {1.3} tableofcontents " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", " Uncomment the next line to enable line numbering on the main body text: linenumberspagewiselinenumbers " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " newpagepagenumbering{arabic} " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " newpagepagenumbering{arabic} " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " input{Introduction_Chapt} input{Examples_Chapt} " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " input{Introduction_Chapt} input{Examples_Chapt} " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " setcounter{chapter}{0} \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " setcounter{chapter}{0} \n", " start chapter numbering here " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " input{Chap_parallel_execution} input{Examples_ploop} input{Examples_parallel} input{Examples_nthrs_nesting} input{Examples_nthrs_dynamic} input{Examples_fort_do} input{Examples_nowait} input{Examples_collapse} \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " input{Chap_parallel_execution} input{Examples_ploop} input{Examples_parallel} input{Examples_nthrs_nesting} input{Examples_nthrs_dynamic} input{Examples_fort_do} input{Examples_nowait} input{Examples_collapse} \n", " linear Clause 475 input{Examples_linear_in_loop} input{Examples_psections} input{Examples_fpriv_sections} input{Examples_single} input{Examples_workshare} input{Examples_master} input{Examples_pra_iterator} input{Examples_set_dynamic_nthrs} input{Examples_get_nthrs} " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " input{Chap_affinity} input{Examples_affinity} input{Examples_affinity_query} " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " input{Chap_affinity} input{Examples_affinity} input{Examples_affinity_query} " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " input{Chap_tasking} input{Examples_tasking} input{Examples_task_priority} input{Examples_task_dep} input{Examples_taskgroup} input{Examples_taskyield} input{Examples_taskloop} " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " input{Chap_tasking} input{Examples_tasking} input{Examples_task_priority} input{Examples_task_dep} input{Examples_taskgroup} input{Examples_taskyield} input{Examples_taskloop} " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " input{Chap_devices} input{Examples_target} input{Examples_target_data} input{Examples_target_unstructured_data} input{Examples_target_update} input{Examples_declare_target} \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " input{Chap_devices} input{Examples_target} input{Examples_target_data} input{Examples_target_unstructured_data} input{Examples_target_update} input{Examples_declare_target} \n", " Link clause 474 input{Examples_teams} input{Examples_async_target_depend} input{Examples_async_target_with_tasks} \n", "Title change of 57.1 and 57.2 \n", "New subsection input{Examples_async_target_nowait} input{Examples_async_target_nowait_depend} input{Examples_array_sections} \n", @@ -163,21 +163,21 @@ " MemoryRoutine and Device ptr 473 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " input{Chap_SIMD} input{Examples_SIMD} \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " input{Chap_SIMD} input{Examples_SIMD} \n", " Forward Depend 370 \n", " simdlen 476 \n", " simd linear modifier 480 " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " input{Chap_synchronization} input{Examples_critical} input{Examples_worksharing_critical} input{Examples_barrier_regions} input{Examples_atomic} input{Examples_atomic_restrict} input{Examples_flush_nolist} input{Examples_ordered} \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " input{Chap_synchronization} input{Examples_critical} input{Examples_worksharing_critical} input{Examples_barrier_regions} input{Examples_atomic} input{Examples_atomic_restrict} input{Examples_flush_nolist} input{Examples_ordered} \n", " Doacross loop 405 input{Examples_doacross} input{Examples_locks} input{Examples_init_lock} input{Examples_init_lock_with_hint} input{Examples_lock_owner} input{Examples_simple_lock} input{Examples_nestable_lock} \n", " \n", " LOCK with Hints 478 \n", @@ -187,54 +187,54 @@ " Lock routines with hint " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " input{Chap_data_environment} input{Examples_threadprivate} input{Examples_default_none} input{Examples_private} input{Examples_fort_loopvar} input{Examples_fort_sp_common} input{Examples_fort_sa_private} input{Examples_carrays_fpriv} input{Examples_lastprivate} input{Examples_reduction} \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " input{Chap_data_environment} input{Examples_threadprivate} input{Examples_default_none} input{Examples_private} input{Examples_fort_loopvar} input{Examples_fort_sp_common} input{Examples_fort_sa_private} input{Examples_carrays_fpriv} input{Examples_lastprivate} input{Examples_reduction} \n", " User UDR 287 \n", " C array reduction 377 input{Examples_copyin} input{Examples_copyprivate} input{Examples_cpp_reference} \n", " Fortran 2003 features 482 input{Examples_associate} \n", "section--> subsection " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " input{Chap_memory_model} input{Examples_mem_model} input{Examples_fort_race} " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " input{Chap_memory_model} input{Examples_mem_model} input{Examples_fort_race} " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " input{Chap_program_control} input{Examples_cond_comp} input{Examples_icv} \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " input{Chap_program_control} input{Examples_cond_comp} input{Examples_icv} \n", " If multi-ifs 471 input{Examples_standalone} input{Examples_cancellation} \n", " New Section Nested Regions input{Examples_nested_loop} input{Examples_nesting_restrict} " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " setcounter{chapter}{0} \n", + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " setcounter{chapter}{0} \n", " restart chapter numbering with 'letter A' renewcommand{thechapter}{Alph{chapter}}\n", " appendix input{History} " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end--- " + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---end--- " ] } ], diff --git a/notebook/tex2notebook.py b/notebook/tex2notebook.py index 872308c..dc77586 100644 --- a/notebook/tex2notebook.py +++ b/notebook/tex2notebook.py @@ -32,19 +32,19 @@ ' "nbformat_minor": 2\n' + \ '}\n' -MB = ' {\n' + \ - ' "cell_type": "markdown",\n' + \ - ' "metadata": {},\n' + \ - ' "source": [\n' + \ - ' "' - -CB = ' {\n' + \ - ' "cell_type": "code",\n' + \ - ' "execution_count": null,\n' + \ - ' "metadata": {},\n' + \ - ' "outputs": [],\n' + \ - ' "source": [\n' + \ - ' "' +MB = ' {\n' + \ + ' "cell_type": "markdown",\n' + \ + ' "metadata": {},\n' + \ + ' "source": [\n' + \ + ' "' + +CB = ' {\n' + \ + ' "cell_type": "code",\n' + \ + ' "execution_count": null,\n' + \ + ' "metadata": {},\n' + \ + ' "outputs": [],\n' + \ + ' "source": [\n' + \ + ' "' E = ' "\n ]\n },\n' E1 = ' \n ]\n },\n' From 2cc4b59ea19a5a29d643a779ef5ceb2b68c372ca Mon Sep 17 00:00:00 2001 From: Kewei Yan Date: Tue, 8 Oct 2019 11:53:49 -0400 Subject: [PATCH 11/21] test5 --- notebook/Chap_SIMD.ipynb | 16 +- notebook/Chap_affinity.ipynb | 30 +-- notebook/Chap_data_environment.ipynb | 30 +-- notebook/Chap_devices.ipynb | 20 +- notebook/Chap_memory_model.ipynb | 20 +- notebook/Chap_parallel_execution.ipynb | 42 ++--- notebook/Chap_program_control.ipynb | 36 ++-- notebook/Chap_synchronization.ipynb | 22 +-- notebook/Chap_tasking.ipynb | 18 +- notebook/Examples_Chapt.ipynb | 10 +- notebook/Examples_SIMD.ipynb | 68 +++---- notebook/Examples_affinity.ipynb | 178 +++++++++--------- notebook/Examples_affinity_query.ipynb | 20 +- notebook/Examples_array_sections.ipynb | 32 ++-- notebook/Examples_associate.ipynb | 22 +-- notebook/Examples_async_target_depend.ipynb | 12 +- notebook/Examples_async_target_nowait.ipynb | 18 +- .../Examples_async_target_nowait_depend.ipynb | 18 +- .../Examples_async_target_with_tasks.ipynb | 30 +-- notebook/Examples_atomic.ipynb | 28 +-- notebook/Examples_atomic_restrict.ipynb | 24 +-- notebook/Examples_barrier_regions.ipynb | 16 +- notebook/Examples_cancellation.ipynb | 22 +-- notebook/Examples_carrays_fpriv.ipynb | 30 +-- notebook/Examples_collapse.ipynb | 36 ++-- notebook/Examples_cond_comp.ipynb | 18 +- notebook/Examples_copyin.ipynb | 12 +- notebook/Examples_copyprivate.ipynb | 32 ++-- notebook/Examples_cpp_reference.ipynb | 14 +- notebook/Examples_critical.ipynb | 18 +- notebook/Examples_declare_target.ipynb | 82 ++++---- notebook/Examples_default_none.ipynb | 16 +- notebook/Examples_device.ipynb | 42 ++--- notebook/Examples_doacross.ipynb | 32 ++-- notebook/Examples_flush_nolist.ipynb | 12 +- notebook/Examples_fort_do.ipynb | 18 +- notebook/Examples_fort_loopvar.ipynb | 18 +- notebook/Examples_fort_race.ipynb | 14 +- notebook/Examples_fort_sa_private.ipynb | 24 +-- notebook/Examples_fort_sp_common.ipynb | 34 ++-- notebook/Examples_fpriv_sections.ipynb | 12 +- notebook/Examples_get_nthrs.ipynb | 18 +- notebook/Examples_icv.ipynb | 28 +-- notebook/Examples_init_lock.ipynb | 12 +- notebook/Examples_init_lock_with_hint.ipynb | 12 +- notebook/Examples_lastprivate.ipynb | 12 +- notebook/Examples_linear_in_loop.ipynb | 12 +- notebook/Examples_lock_owner.ipynb | 14 +- notebook/Examples_locks.ipynb | 8 +- notebook/Examples_master.ipynb | 12 +- notebook/Examples_mem_model.ipynb | 26 +-- notebook/Examples_nestable_lock.ipynb | 12 +- notebook/Examples_nested_loop.ipynb | 18 +- notebook/Examples_nesting_restrict.ipynb | 44 ++--- notebook/Examples_nowait.ipynb | 20 +- notebook/Examples_nthrs_dynamic.ipynb | 22 +-- notebook/Examples_nthrs_nesting.ipynb | 12 +- notebook/Examples_ordered.ipynb | 24 +-- notebook/Examples_parallel.ipynb | 12 +- notebook/Examples_ploop.ipynb | 12 +- notebook/Examples_pra_iterator.ipynb | 14 +- notebook/Examples_private.ipynb | 24 +-- notebook/Examples_psections.ipynb | 12 +- notebook/Examples_reduction.ipynb | 48 ++--- notebook/Examples_set_dynamic_nthrs.ipynb | 16 +- notebook/Examples_simple_lock.ipynb | 16 +- notebook/Examples_single.ipynb | 12 +- notebook/Examples_standalone.ipynb | 24 +-- notebook/Examples_target.ipynb | 70 +++---- notebook/Examples_target_data.ipynb | 86 ++++----- .../Examples_target_unstructured_data.ipynb | 28 +-- notebook/Examples_target_update.ipynb | 38 ++-- notebook/Examples_task_dep.ipynb | 54 +++--- notebook/Examples_task_priority.ipynb | 16 +- notebook/Examples_taskgroup.ipynb | 14 +- notebook/Examples_tasking.ipynb | 100 +++++----- notebook/Examples_taskloop.ipynb | 14 +- notebook/Examples_taskyield.ipynb | 12 +- notebook/Examples_teams.ipynb | 78 ++++---- notebook/Examples_threadprivate.ipynb | 70 +++---- notebook/Examples_workshare.ipynb | 48 ++--- notebook/Examples_worksharing_critical.ipynb | 12 +- notebook/History.ipynb | 24 +-- notebook/Introduction_Chapt.ipynb | 26 +-- notebook/Title_Page.ipynb | 30 +-- notebook/openmp-examples.ipynb | 48 ++--- notebook/tex2notebook.py | 8 +- 87 files changed, 1234 insertions(+), 1234 deletions(-) diff --git a/notebook/Chap_SIMD.ipynb b/notebook/Chap_SIMD.ipynb index 4a50475..06f5813 100644 --- a/notebook/Chap_SIMD.ipynb +++ b/notebook/Chap_SIMD.ipynb @@ -4,35 +4,35 @@ "cell_type": "markdown", "metadata": {}, "source": [ - " ## SIMD " + " ## SIMD" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " Single instruction, multiple data (SIMD) is a form of parallel execution in which the same operation is performed on multiple data elements independently in hardware vector processing units (VPU), also called SIMD units. The addition of two vectors to form a third vector is a SIMD operation. Many processors have SIMD (vector) units that can perform simultaneously 2, 4, 8 or more executions of the same operation (by a single SIMD unit). " + " Single instruction, multiple data (SIMD) is a form of parallel execution in which the same operation is performed on multiple data elements independently in hardware vector processing units (VPU), also called SIMD units. The addition of two vectors to form a third vector is a SIMD operation. Many processors have SIMD (vector) units that can perform simultaneously 2, 4, 8 or more executions of the same operation (by a single SIMD unit). " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " Loops without loop-carried backward dependency (or with dependency preserved using ordered simd) are candidates for vectorization by the compiler for execution with SIMD units. In addition, with state-of-the-art vectorization technology and `declare simd` construct extensions for function vectorization in the OpenMP 4.5 specification, loops with function calls can be vectorized as well. The basic idea is that a scalar function call in a loop can be replaced by a vector version of the function, and the loop can be vectorized simultaneously by combining a loop vectorization ( `simd` directive on the loop) and a function vectorization ( `declare simd` directive on the function). " + " Loops without loop-carried backward dependency (or with dependency preserved using ordered simd) are candidates for vectorization by the compiler for execution with SIMD units. In addition, with state-of-the-art vectorization technology and `declare simd` construct extensions for function vectorization in the OpenMP 4.5 specification, loops with function calls can be vectorized as well. The basic idea is that a scalar function call in a loop can be replaced by a vector version of the function, and the loop can be vectorized simultaneously by combining a loop vectorization ( `simd` directive on the loop) and a function vectorization ( `declare simd` directive on the function)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " A `simd` construct states that SIMD operations be performed on the data within the loop. A number of clauses are available to provide data-sharing attributes ( `private` , `linear` , `reduction` and `lastprivate` ). Other clauses provide vector length preference/restrictions ( `simdlen` / `safelen` ), loop fusion ( `collapse` ), and data alignment ( `aligned` ). " + " A `simd` construct states that SIMD operations be performed on the data within the loop. A number of clauses are available to provide data-sharing attributes ( `private` , `linear` , `reduction` and `lastprivate` ). Other clauses provide vector length preference/restrictions ( `simdlen` / `safelen` ), loop fusion ( `collapse` ), and data alignment ( `aligned` )." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The `declare simd` directive designates that a vector version of the function should also be constructed for execution within loops that contain the function and have a `simd` directive. Clauses provide argument specifications ( `linear` , `uniform` , and `aligned` ), a requested vector length ( `simdlen` ), and designate whether the function is always/never called conditionally in a loop ( `branch` / `inbranch` ). The latter is for optimizing peformance. " + " The `declare simd` directive designates that a vector version of the function should also be constructed for execution within loops that contain the function and have a `simd` directive. Clauses provide argument specifications ( `linear` , `uniform` , and `aligned` ), a requested vector length ( `simdlen` ), and designate whether the function is always/never called conditionally in a loop ( `branch` / `inbranch` ). The latter is for optimizing peformance." ] }, { @@ -45,14 +45,14 @@ "combination with a parallel loop construct to include thread parallelism \n", "(a parallel loop sequentially followed by a `simd` construct, \n", "or a combined construct such as `parallel do simd` or \n", -" `parallel for simd` ). " +" `parallel for simd` )." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---end--- " + "---end---" ] } ], @@ -70,4 +70,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/notebook/Chap_affinity.ipynb b/notebook/Chap_affinity.ipynb index 5d505dc..94229e4 100644 --- a/notebook/Chap_affinity.ipynb +++ b/notebook/Chap_affinity.ipynb @@ -4,28 +4,28 @@ "cell_type": "markdown", "metadata": {}, "source": [ - " ## OpenMP Affinity " + " ## OpenMP Affinity" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " OpenMP Affinity consists of a `proc_bind` policy (thread affinity policy) and a specification of places ( ' location units ' or _processors_ that may be cores, hardware threads, sockets, etc.). OpenMP Affinity enables users to bind computations on specific places. The placement will hold for the duration of the parallel region. However, the runtime is free to migrate the OpenMP threads to different cores (hardware threads, sockets, etc.) prescribed within a given place, if two or more cores (hardware threads, sockets, etc.) have been assigned to a given place. " + " OpenMP Affinity consists of a `proc_bind` policy (thread affinity policy) and a specification of places ( ' location units ' or _processors_ that may be cores, hardware threads, sockets, etc.). OpenMP Affinity enables users to bind computations on specific places. The placement will hold for the duration of the parallel region. However, the runtime is free to migrate the OpenMP threads to different cores (hardware threads, sockets, etc.) prescribed within a given place, if two or more cores (hardware threads, sockets, etc.) have been assigned to a given place." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " Often the binding can be managed without resorting to explicitly setting places. Without the specification of places in the `OMP_PLACES` variable, the OpenMP runtime will distribute and bind threads using the entire range of processors for the OpenMP program, according to the `OMP_PROC_BIND` environment variable or the `proc_bind` clause. When places are specified, the OMP runtime binds threads to the places according to a default distribution policy, or those specified in the `OMP_PROC_BIND` environment variable or the `proc_bind` clause. " + " Often the binding can be managed without resorting to explicitly setting places. Without the specification of places in the `OMP_PLACES` variable, the OpenMP runtime will distribute and bind threads using the entire range of processors for the OpenMP program, according to the `OMP_PROC_BIND` environment variable or the `proc_bind` clause. When places are specified, the OMP runtime binds threads to the places according to a default distribution policy, or those specified in the `OMP_PROC_BIND` environment variable or the `proc_bind` clause." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " In the OpenMP Specifications document a processor refers to an execution unit that is enabled for an OpenMP thread to use. A processor is a core when there is no SMT (Simultaneous Multi-Threading) support or SMT is disabled. When SMT is enabled, a processor is a hardware thread (HW-thread). (This is the usual case; but actually, the execution unit is implementation defined.) Processor numbers are numbered sequentially from 0 to the number of cores less one (without SMT), or 0 to the number HW-threads less one (with SMT). OpenMP places use the processor number to designate binding locations (unless an ' abstract name ' is used.) " + " In the OpenMP Specifications document a processor refers to an execution unit that is enabled for an OpenMP thread to use. A processor is a core when there is no SMT (Simultaneous Multi-Threading) support or SMT is disabled. When SMT is enabled, a processor is a hardware thread (HW-thread). (This is the usual case; but actually, the execution unit is implementation defined.) Processor numbers are numbered sequentially from 0 to the number of cores less one (without SMT), or 0 to the number HW-threads less one (with SMT). OpenMP places use the processor number to designate binding locations (unless an ' abstract name ' is used.) " ] }, { @@ -38,7 +38,7 @@ "processor set for execution from the parent process (the initial task region) \n", "when a parallel region forks threads. The binding policy set in \n", " `OMP_PROC_BIND` or the `proc_bind` clause will be applied to \n", -"the subset of processors available to _the particular_ MPI process. " +"the subset of processors available to _the particular_ MPI process." ] }, { @@ -52,21 +52,21 @@ "processors in the places list must not contain processors outside the subset \n", "of processors for an MPI process. A separate `OMP_PLACES` variable must \n", "be set for each MPI process, and is usually accomplished by launching a script \n", -"which sets `OMP_PLACES` specifically for the MPI process. " +"which sets `OMP_PLACES` specifically for the MPI process. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " Threads of a team are positioned onto places in a compact manner, a scattered distribution, or onto the master's place, by setting the `OMP_PROC_BIND` environment variable or the `proc_bind` clause to _close_ , _spread_ , or _master_ , respectively. When `OMP_PROC_BIND` is set to FALSE no binding is enforced; and when the value is TRUE, the binding is implementation defined to a set of places in the `OMP_PLACES` variable or to places defined by the implementation if the `OMP_PLACES` variable is not set. " + " Threads of a team are positioned onto places in a compact manner, a scattered distribution, or onto the master's place, by setting the `OMP_PROC_BIND` environment variable or the `proc_bind` clause to _close_ , _spread_ , or _master_ , respectively. When `OMP_PROC_BIND` is set to FALSE no binding is enforced; and when the value is TRUE, the binding is implementation defined to a set of places in the `OMP_PLACES` variable or to places defined by the implementation if the `OMP_PLACES` variable is not set." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The `OMP_PLACES` variable can also be set to an abstract name ( _threads_ , _cores_ , _sockets_ ) to specify that a place is either a single hardware thread, a core, or a socket, respectively. This description of the `OMP_PLACES` is most useful when the number of threads is equal to the number of hardware thread, cores or sockets. It can also be used with a _close_ or _spread_ distribution policy when the equality doesn't hold. " + " The `OMP_PLACES` variable can also be set to an abstract name ( _threads_ , _cores_ , _sockets_ ) to specify that a place is either a single hardware thread, a core, or a socket, respectively. This description of the `OMP_PLACES` is most useful when the number of threads is equal to the number of hardware thread, cores or sockets. It can also be used with a _close_ or _spread_ distribution policy when the equality doesn't hold." ] }, { @@ -74,7 +74,7 @@ "metadata": {}, "source": [ " \n", -" We need an example of using sockets, cores and threads: " +" We need an example of using sockets, cores and threads:" ] }, { @@ -82,7 +82,7 @@ "metadata": {}, "source": [ " \n", -" case 1 cores: " +" case 1 cores:" ] }, { @@ -101,7 +101,7 @@ " thread # 0 * _ _ _ _ _ _ _ #mask for thread 0 \n", " thread # 1 _ _ * _ _ _ _ _ #mask for thread 1 \n", " thread # 2 _ _ _ _ * _ _ _ #mask for thread 2 \n", -" thread # 3 _ _ _ _ _ _ * _ #mask for thread 3 " +" thread # 3 _ _ _ _ _ _ * _ #mask for thread 3" ] }, { @@ -122,7 +122,7 @@ " thread # 0 * * _ _ _ _ _ _ #mask for thread 0 \n", " thread # 1 _ _ * * _ _ _ _ #mask for thread 1 \n", " thread # 2 _ _ _ _ * * _ _ #mask for thread 2 \n", -" thread # 3 _ _ _ _ _ _ * * #mask for thread 3 " +" thread # 3 _ _ _ _ _ _ * * #mask for thread 3" ] }, { @@ -142,14 +142,14 @@ " processor # 0,1,2,3 4,5,6,7 8,9,10,11 \n", " thread # 0 * * * * _ _ _ _ _ _ _ _ #mask for thread 0 \n", " thread # 0 _ _ _ _ * * * * _ _ _ _ #mask for thread 1 \n", -" thread # 0 _ _ _ _ _ _ _ _ * * * * #mask for thread 2 " +" thread # 0 _ _ _ _ _ _ _ _ * * * * #mask for thread 2" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---end--- " + "---end---" ] } ], @@ -167,4 +167,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/notebook/Chap_data_environment.ipynb b/notebook/Chap_data_environment.ipynb index 3432430..84e83d7 100644 --- a/notebook/Chap_data_environment.ipynb +++ b/notebook/Chap_data_environment.ipynb @@ -4,42 +4,42 @@ "cell_type": "markdown", "metadata": {}, "source": [ - " ## Data Environment " + " ## Data Environment" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The OpenMP _data environment_ contains data attributes of variables and objects. Many constructs (such as `parallel` , `simd` , `task` ) accept clauses to control _data-sharing_ attributes of referenced variables in the construct, where _data-sharing_ applies to whether the attribute of the variable is _shared_ , is _private_ storage, or has special operational characteristics (as found in the `firstprivate` , `lastprivate` , `linear` , or `reduction` clause). " + " The OpenMP _data environment_ contains data attributes of variables and objects. Many constructs (such as `parallel` , `simd` , `task` ) accept clauses to control _data-sharing_ attributes of referenced variables in the construct, where _data-sharing_ applies to whether the attribute of the variable is _shared_ , is _private_ storage, or has special operational characteristics (as found in the `firstprivate` , `lastprivate` , `linear` , or `reduction` clause)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The data environment for a device (distinguished as a _device data environment_ ) is controlled on the host by _data-mapping_ attributes, which determine the relationship of the data on the host, the _original_ data, and the data on the device, the _corresponding_ data. " + " The data environment for a device (distinguished as a _device data environment_ ) is controlled on the host by _data-mapping_ attributes, which determine the relationship of the data on the host, the _original_ data, and the data on the device, the _corresponding_ data." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " bigskip DATA-SHARING ATTRIBUTES " + " bigskip DATA-SHARING ATTRIBUTES" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " Data-sharing attributes of variables can be classified as being _predetermined_ , _explicitly determined_ or _implicitly determined_ . " + " Data-sharing attributes of variables can be classified as being _predetermined_ , _explicitly determined_ or _implicitly determined_ ." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " Certain variables and objects have predetermined attributes. A commonly found case is the loop iteration variable in associated loops of a `for` or `do` construct. It has a private data-sharing attribute. Variables with predetermined data-sharing attributes can not be listed in a data-sharing clause; but there are some exceptions (mainly concerning loop iteration variables). " + " Certain variables and objects have predetermined attributes. A commonly found case is the loop iteration variable in associated loops of a `for` or `do` construct. It has a private data-sharing attribute. Variables with predetermined data-sharing attributes can not be listed in a data-sharing clause; but there are some exceptions (mainly concerning loop iteration variables)." ] }, { @@ -47,21 +47,21 @@ "metadata": {}, "source": [ " Variables with explicitly determined data-sharing attributes are those that are referenced in a given construct and are listed in a data-sharing attribute clause on the construct. Some of the common data-sharing clauses are: `shared` , `private` , `firstprivate` , `lastprivate` , `linear` , and `reduction` . \n", -" Are these all of them? " +" Are these all of them?" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " Variables with implicitly determined data-sharing attributes are those that are referenced in a given construct, do not have predetermined data-sharing attributes, and are not listed in a data-sharing attribute clause of an enclosing construct. For a complete list of variables and objects with predetermined and implicitly determined attributes, please refer to the _Data-sharing Attribute Rules for Variables Referenced in a Construct_ subsection of the OpenMP Specifications document. " + " Variables with implicitly determined data-sharing attributes are those that are referenced in a given construct, do not have predetermined data-sharing attributes, and are not listed in a data-sharing attribute clause of an enclosing construct. For a complete list of variables and objects with predetermined and implicitly determined attributes, please refer to the _Data-sharing Attribute Rules for Variables Referenced in a Construct_ subsection of the OpenMP Specifications document. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " bigskip DATA-MAPPING ATTRIBUTES " + " bigskip DATA-MAPPING ATTRIBUTES" ] }, { @@ -69,7 +69,7 @@ "metadata": {}, "source": [ " The `map` clause on a device construct explictly specifies how the list items in the clause are mapped from the encountering task's data environment (on the host) to the corresponding \n", -"* in the device data environment (on the device). The common _list items_ are arrays, array sections, scalars, pointers, and structure elements (members). " +"* in the device data environment (on the device). The common _list items_ are arrays, array sections, scalars, pointers, and structure elements (members). " ] }, { @@ -77,14 +77,14 @@ "metadata": {}, "source": [ " Procedures and global variables have predetermined data mapping if they appear within the list or block of a `declare target` directive. Also, a C/C++ pointer is mapped as a zero-length array section, as is a C++ variable that is a reference to a pointer. \n", -" Waiting for response from Eric on this. " +" Waiting for response from Eric on this." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " Without explict mapping, non-scalar and non-pointer variables within the scope of the `target` construct are implicitly mapped with a _map-type_ of `tofrom` . Without explicit mapping, scalar variables within the scope of the `target` construct are not mapped, but have an implicit firstprivate data-sharing attribute. (That is, the value of the original variable is given to a private variable of the same name on the device.) This behavior can be changed with the `defaultmap` clause. " + " Without explict mapping, non-scalar and non-pointer variables within the scope of the `target` construct are implicitly mapped with a _map-type_ of `tofrom` . Without explicit mapping, scalar variables within the scope of the `target` construct are not mapped, but have an implicit firstprivate data-sharing attribute. (That is, the value of the original variable is given to a private variable of the same name on the device.) This behavior can be changed with the `defaultmap` clause." ] }, { @@ -93,14 +93,14 @@ "source": [ " The `map` clause can appear on `target` , `target data` and `target enter/exit data` constructs. The operations of creation and removal of device storage as well as assignment of the original list \n", "* values to the corresponding list items may be complicated when the list \n", -"* appears on multiple constructs or when the host and device storage is shared. In these cases the item's reference count, the number of times it has been referenced (+1 on entry and -1 on exited) in nested (structured) map regions and/or accumulative (unstructured) mappings, determines the operation. Details of the `map` clause and reference count operation are specified in the _map Clause_ subsection of the OpenMP Specifications document. " +"* appears on multiple constructs or when the host and device storage is shared. In these cases the item's reference count, the number of times it has been referenced (+1 on entry and -1 on exited) in nested (structured) map regions and/or accumulative (unstructured) mappings, determines the operation. Details of the `map` clause and reference count operation are specified in the _map Clause_ subsection of the OpenMP Specifications document." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---end--- " + "---end---" ] } ], @@ -118,4 +118,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/notebook/Chap_devices.ipynb b/notebook/Chap_devices.ipynb index 344df1f..e07dde3 100644 --- a/notebook/Chap_devices.ipynb +++ b/notebook/Chap_devices.ipynb @@ -4,63 +4,63 @@ "cell_type": "markdown", "metadata": {}, "source": [ - " ## Devices " + " ## Devices" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The `target` construct consists of a `target` directive and an execution region. The `target` region is executed on the default device or the device specified in the `device` clause. " + " The `target` construct consists of a `target` directive and an execution region. The `target` region is executed on the default device or the device specified in the `device` clause. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " In OpenMP version 4.0, by default, all variables within the lexical scope of the construct are copied _to_ and _from_ the device, unless the device is the host, or the data exists on the device from a previously executed data-type construct that has created space on the device and possibly copied host data to the device storage. " + " In OpenMP version 4.0, by default, all variables within the lexical scope of the construct are copied _to_ and _from_ the device, unless the device is the host, or the data exists on the device from a previously executed data-type construct that has created space on the device and possibly copied host data to the device storage." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The constructs that explicitly create storage, transfer data, and free storage on the device are catagorized as structured and unstructured. The `target` `data` construct is structured. It creates a data region around `target` constructs, and is convenient for providing persistent data throughout multiple `target` regions. The `target` `enter` `data` and `target` `exit` `data` constructs are unstructured, because they can occur anywhere and do not support a 'structure' (a region) for enclosing `target` constructs, as does the `target` `data` construct. " + " The constructs that explicitly create storage, transfer data, and free storage on the device are catagorized as structured and unstructured. The `target` `data` construct is structured. It creates a data region around `target` constructs, and is convenient for providing persistent data throughout multiple `target` regions. The `target` `enter` `data` and `target` `exit` `data` constructs are unstructured, because they can occur anywhere and do not support a 'structure' (a region) for enclosing `target` constructs, as does the `target` `data` construct. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The `map` clause is used on `target` constructs and the data-type constructs to map host data. It specifies the device storage and data movement `to` and `from` the device, and controls on the storage duration. " + " The `map` clause is used on `target` constructs and the data-type constructs to map host data. It specifies the device storage and data movement `to` and `from` the device, and controls on the storage duration." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " There is an important change in the OpenMP 4.5 specification that alters the data model for scalar variables and C/C++ pointer variables. The default behavior for scalar variables and C/C++ pointer variables in an 4.5 compliant code is `firstprivate` . Example codes that have been updated to reflect this new behavior are annotated with a description that describes changes required for correct execution. Often it is a simple matter of mapping the variable as `tofrom` to obtain the intended 4.0 behavior. " + " There is an important change in the OpenMP 4.5 specification that alters the data model for scalar variables and C/C++ pointer variables. The default behavior for scalar variables and C/C++ pointer variables in an 4.5 compliant code is `firstprivate` . Example codes that have been updated to reflect this new behavior are annotated with a description that describes changes required for correct execution. Often it is a simple matter of mapping the variable as `tofrom` to obtain the intended 4.0 behavior." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " In OpenMP version 4.5 the mechanism for target execution is specified as occuring through a _target task_ . When the `target` construct is encountered a new _target task_ is generated. The _target task_ completes after the `target` region has executed and all data transfers have finished. " + " In OpenMP version 4.5 the mechanism for target execution is specified as occuring through a _target task_ . When the `target` construct is encountered a new _target task_ is generated. The _target task_ completes after the `target` region has executed and all data transfers have finished." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " This new specification does not affect the execution of pre-4.5 code; it is a necessary element for asynchronous execution of the `target` region when using the new `nowait` clause introduced in OpenMP 4.5. " + " This new specification does not affect the execution of pre-4.5 code; it is a necessary element for asynchronous execution of the `target` region when using the new `nowait` clause introduced in OpenMP 4.5." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---end--- " + "---end---" ] } ], @@ -78,4 +78,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/notebook/Chap_memory_model.ipynb b/notebook/Chap_memory_model.ipynb index 81e662f..66926a0 100644 --- a/notebook/Chap_memory_model.ipynb +++ b/notebook/Chap_memory_model.ipynb @@ -4,42 +4,42 @@ "cell_type": "markdown", "metadata": {}, "source": [ - " ## Memory Model " + " ## Memory Model" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " In this chapter, examples illustrate race conditions on access to variables with shared data-sharing attributes. A race condition can exist when two or more threads are involved in accessing a variable in which not all of the accesses are reads; that is, a WaR, RaW or WaW condition exists (R=read, a=after, W=write). A RaR does not produce a race condition. Ensuring thread execution order at the processor level is not enough to avoid race conditions, because the local storage at the processor level (registers, caches, etc.) must be synchronized so that a consistent view of the variable in the memory hierarchy can be seen by the threads accessing the variable. " + " In this chapter, examples illustrate race conditions on access to variables with shared data-sharing attributes. A race condition can exist when two or more threads are involved in accessing a variable in which not all of the accesses are reads; that is, a WaR, RaW or WaW condition exists (R=read, a=after, W=write). A RaR does not produce a race condition. Ensuring thread execution order at the processor level is not enough to avoid race conditions, because the local storage at the processor level (registers, caches, etc.) must be synchronized so that a consistent view of the variable in the memory hierarchy can be seen by the threads accessing the variable." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " OpenMP provides a shared-memory model which allows all threads access to _memory_ (shared data). Each thread also has exclusive access to _threadprivate memory_ (private data). A private variable referenced in an OpenMP directive's structured block is a new version of the original variable (with the same name) for each task (or SIMD lane) within the code block. A private variable is initially undefined (except for variables in `firstprivate` and `linear` clauses), and the original variable value is unaltered by assignments to the private variable, (except for `reduction` , `lastprivate` and `linear` clauses). " + " OpenMP provides a shared-memory model which allows all threads access to _memory_ (shared data). Each thread also has exclusive access to _threadprivate memory_ (private data). A private variable referenced in an OpenMP directive's structured block is a new version of the original variable (with the same name) for each task (or SIMD lane) within the code block. A private variable is initially undefined (except for variables in `firstprivate` and `linear` clauses), and the original variable value is unaltered by assignments to the private variable, (except for `reduction` , `lastprivate` and `linear` clauses)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " Private variables in an outer `parallel` region can be shared by implicit tasks of an inner `parallel` region (with a `share` clause on the inner `parallel` directive). Likewise, a private variable may be shared in the region of an explicit `task` (through a `shared` clause). " + " Private variables in an outer `parallel` region can be shared by implicit tasks of an inner `parallel` region (with a `share` clause on the inner `parallel` directive). Likewise, a private variable may be shared in the region of an explicit `task` (through a `shared` clause)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The `flush` directive forces a consistent view of local variables of the thread executing the `flush` . When a list is supplied on the directive, only the items (variables) in the list are guaranteed to be flushed. " + " The `flush` directive forces a consistent view of local variables of the thread executing the `flush` . When a list is supplied on the directive, only the items (variables) in the list are guaranteed to be flushed." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " Implied flushes exist at prescribed locations of certain constructs. For the complete list of these locations and associated constructs, please refer to the _flush Construct_ section of the OpenMP Specifications document. " + " Implied flushes exist at prescribed locations of certain constructs. For the complete list of these locations and associated constructs, please refer to the _flush Construct_ section of the OpenMP Specifications document." ] }, { @@ -111,21 +111,21 @@ " ( `atomic` directive without a `seq_cst` clause), where the list \n", "* is the \n", " specific storage location accessed atomically (specified as the _x_ variable \n", -" in _atomic Construct_ subsection of the OpenMP Specifications document). " +" in _atomic Construct_ subsection of the OpenMP Specifications document)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " Examples 1-3 show the difficulty of synchronizing threads through `flush` and `atomic` directives. " + " Examples 1-3 show the difficulty of synchronizing threads through `flush` and `atomic` directives." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---end--- " + "---end---" ] } ], @@ -143,4 +143,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/notebook/Chap_parallel_execution.ipynb b/notebook/Chap_parallel_execution.ipynb index bd15050..84fc9d1 100644 --- a/notebook/Chap_parallel_execution.ipynb +++ b/notebook/Chap_parallel_execution.ipynb @@ -4,28 +4,28 @@ "cell_type": "markdown", "metadata": {}, "source": [ - " ## Parallel Execution " + " ## Parallel Execution" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " A single thread, the _initial thread_ , begins sequential execution of an OpenMP enabled program, as if the whole program is in an implicit parallel region consisting of an implicit task executed by the _initial thread_ . " + " A single thread, the _initial thread_ , begins sequential execution of an OpenMP enabled program, as if the whole program is in an implicit parallel region consisting of an implicit task executed by the _initial thread_ ." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " A `parallel` construct encloses code, forming a parallel region. An _initial thread_ encountering a `parallel` region forks (creates) a team of threads at the beginning of the `parallel` region, and joins them (removes from execution) at the end of the region. The initial thread becomes the master thread of the team in a `parallel` region with a _thread_ number equal to zero, the other threads are numbered from 1 to number of threads minus 1. A team may be comprised of just a single thread. " + " A `parallel` construct encloses code, forming a parallel region. An _initial thread_ encountering a `parallel` region forks (creates) a team of threads at the beginning of the `parallel` region, and joins them (removes from execution) at the end of the region. The initial thread becomes the master thread of the team in a `parallel` region with a _thread_ number equal to zero, the other threads are numbered from 1 to number of threads minus 1. A team may be comprised of just a single thread." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " Each thread of a team is assigned an implicit task consisting of code within the parallel region. The task that creates a parallel region is suspended while the tasks of the team are executed. A thread is tied to its task; that is, only the thread assigned to the task can execute that task. After completion of the `parallel` region, the master thread resumes execution of the generating task. " + " Each thread of a team is assigned an implicit task consisting of code within the parallel region. The task that creates a parallel region is suspended while the tasks of the team are executed. A thread is tied to its task; that is, only the thread assigned to the task can execute that task. After completion of the `parallel` region, the master thread resumes execution of the generating task. " ] }, { @@ -34,42 +34,42 @@ "source": [ " \n", "After the `parallel` region the master thread becomes the initial \n", -"thread again, and continues to execute the _sequential part_ . " +"thread again, and continues to execute the _sequential part_ . " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " Any task within a `parallel` region is allowed to encounter another `parallel` region to form a nested `parallel` region. The parallelism of a nested `parallel` region (whether it forks additional threads, or is executed serially by the encountering task) can be controlled by the `OMP_NESTED` environment variable or the `omp_set_nested()` API routine with arguments indicating true or false. " + " Any task within a `parallel` region is allowed to encounter another `parallel` region to form a nested `parallel` region. The parallelism of a nested `parallel` region (whether it forks additional threads, or is executed serially by the encountering task) can be controlled by the `OMP_NESTED` environment variable or the `omp_set_nested()` API routine with arguments indicating true or false." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The number of threads of a `parallel` region can be set by the `OMP_NUM_THREADS` environment variable, the `omp_set_num_threads()` routine, or on the `parallel` directive with the `num_threads` clause. The routine overrides the environment variable, and the clause overrides all. Use the `OMP_DYNAMIC` or the `omp_set_dynamic()` function to specify that the OpenMP implementation dynamically adjust the number of threads for `parallel` regions. The default setting for dynamic adjustment is implementation defined. When dynamic adjustment is on and the number of threads is specified, the number of threads becomes an upper limit for the number of threads to be provided by the OpenMP runtime. " + " The number of threads of a `parallel` region can be set by the `OMP_NUM_THREADS` environment variable, the `omp_set_num_threads()` routine, or on the `parallel` directive with the `num_threads` clause. The routine overrides the environment variable, and the clause overrides all. Use the `OMP_DYNAMIC` or the `omp_set_dynamic()` function to specify that the OpenMP implementation dynamically adjust the number of threads for `parallel` regions. The default setting for dynamic adjustment is implementation defined. When dynamic adjustment is on and the number of threads is specified, the number of threads becomes an upper limit for the number of threads to be provided by the OpenMP runtime." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " WORKSHARING CONSTRUCTS " + " WORKSHARING CONSTRUCTS" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " A worksharing construct distributes the execution of the associated region among the members of the team that encounter it. There is an implied barrier at the end of the worksharing region (there is no barrier at the beginning). The worksharing constructs are: " + " A worksharing construct distributes the execution of the associated region among the members of the team that encounter it. There is an implied barrier at the end of the worksharing region (there is no barrier at the beginning). The worksharing constructs are:" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " " + " " ] }, { @@ -80,21 +80,21 @@ "* loop constructs: { `for` and `do` } \n", "* `sections` \n", "* `single` \n", -"* `workshare` " +"* `workshare` " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " " + " " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The `for` and `do` constructs (loop constructs) create a region consisting of a loop. A loop controlled by a loop construct is called an _associated_ loop. Nested loops can form a single region when the `collapse` clause (with an integer argument) designates the number of _associated_ loops to be executed in parallel, by forming a 'single iteration space' for the specified number of nested loops. The `ordered` clause can also control multiple associated loops. " + " The `for` and `do` constructs (loop constructs) create a region consisting of a loop. A loop controlled by a loop construct is called an _associated_ loop. Nested loops can form a single region when the `collapse` clause (with an integer argument) designates the number of _associated_ loops to be executed in parallel, by forming a 'single iteration space' for the specified number of nested loops. The `ordered` clause can also control multiple associated loops." ] }, { @@ -102,49 +102,49 @@ "metadata": {}, "source": [ " An associated loop must adhere to a 'canonical form' (specified in the _Canonical Loop Form_ of the OpenMP Specifications document) which allows the iteration count (of all associated loops) to be computed before the (outermost) loop is executed. \n", -"[58:27-29]. Most common loops comply with the canonical form, including C++ iterators. " +"[58:27-29]. Most common loops comply with the canonical form, including C++ iterators." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " A `single` construct forms a region in which only one thread (any one of the team) executes the region. The other threads wait at the implied barrier at the end, unless the `nowait` clause is specified. " + " A `single` construct forms a region in which only one thread (any one of the team) executes the region. The other threads wait at the implied barrier at the end, unless the `nowait` clause is specified." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The `sections` construct forms a region that contains one or more structured blocks. Each block of a `sections` directive is constructed with a `section` construct, and executed once by one of the threads (any one) in the team. (If only one block is formed in the region, the `section` construct, which is used to separate blocks, is not required.) The other threads wait at the implied barrier at the end, unless the `nowait` clause is specified. " + " The `sections` construct forms a region that contains one or more structured blocks. Each block of a `sections` directive is constructed with a `section` construct, and executed once by one of the threads (any one) in the team. (If only one block is formed in the region, the `section` construct, which is used to separate blocks, is not required.) The other threads wait at the implied barrier at the end, unless the `nowait` clause is specified." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The `workshare` construct is a Fortran feature that consists of a region with a single structure block (section of code). Statements in the `workshare` region are divided into units of work, and executed (once) by threads of the team. " + " The `workshare` construct is a Fortran feature that consists of a region with a single structure block (section of code). Statements in the `workshare` region are divided into units of work, and executed (once) by threads of the team. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " bigskip MASTER CONSTRUCT " + " bigskip MASTER CONSTRUCT" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The `master` construct is not a worksharing construct. The master region is is executed only by the master thread. There is no implicit barrier (and flush) at the end of the `master` region; hence the other threads of the team continue execution beyond code statements beyond the `master` region. " + " The `master` construct is not a worksharing construct. The master region is is executed only by the master thread. There is no implicit barrier (and flush) at the end of the `master` region; hence the other threads of the team continue execution beyond code statements beyond the `master` region." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---end--- " + "---end---" ] } ], @@ -162,4 +162,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/notebook/Chap_program_control.ipynb b/notebook/Chap_program_control.ipynb index 803704d..1fe190c 100644 --- a/notebook/Chap_program_control.ipynb +++ b/notebook/Chap_program_control.ipynb @@ -4,63 +4,63 @@ "cell_type": "markdown", "metadata": {}, "source": [ - " ## Program Control " + " ## Program Control" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " Some specific and elementary concepts of controlling program execution are illustrated in the examples of this chapter. Control can be directly managed with conditional control code (ifdef's with the `_OPENMP` macro, and the Fortran sentinel ( `!$` ) for conditionally compiling). The `if` clause on some constructs can direct the runtime to ignore or alter the behavior of the construct. Of course, the base-language `if` statements can be used to control the 'execution' of stand-alone directives (such as `flush` , `barrier` , `taskwait` , and `taskyield` ). However, the directives must appear in a block structure, and not as a substatement as shown in examples 1 and 2 of this chapter. " + " Some specific and elementary concepts of controlling program execution are illustrated in the examples of this chapter. Control can be directly managed with conditional control code (ifdef's with the `_OPENMP` macro, and the Fortran sentinel ( `!$` ) for conditionally compiling). The `if` clause on some constructs can direct the runtime to ignore or alter the behavior of the construct. Of course, the base-language `if` statements can be used to control the 'execution' of stand-alone directives (such as `flush` , `barrier` , `taskwait` , and `taskyield` ). However, the directives must appear in a block structure, and not as a substatement as shown in examples 1 and 2 of this chapter." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " bigskip CANCELLATION " + " bigskip CANCELLATION" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " Cancellation (termination) of the normal sequence of execution for the threads in an OpenMP region can be accomplished with the `cancel` construct. The construct uses a _construct-type-clause_ to set the region-type to activate for the cancellation. That is, inclusion of one of the _construct-type-clause_ names `parallel` , `for` , `do` , `sections` or `taskgroup` on the directive line activates the corresponding region. The `cancel` construct is activated by the first encountering thread, and it continues execution at the end of the named region. The `cancel` construct is also a concellation point for any other thread of the team to also continue execution at the end of the named region. " + " Cancellation (termination) of the normal sequence of execution for the threads in an OpenMP region can be accomplished with the `cancel` construct. The construct uses a _construct-type-clause_ to set the region-type to activate for the cancellation. That is, inclusion of one of the _construct-type-clause_ names `parallel` , `for` , `do` , `sections` or `taskgroup` on the directive line activates the corresponding region. The `cancel` construct is activated by the first encountering thread, and it continues execution at the end of the named region. The `cancel` construct is also a concellation point for any other thread of the team to also continue execution at the end of the named region. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " Also, once the specified region has been activated for cancellation any thread that encounnters a `cancellation point` construct with the same named region ( _construct-type-clause_ ), continues execution at the end of the region. " + " Also, once the specified region has been activated for cancellation any thread that encounnters a `cancellation point` construct with the same named region ( _construct-type-clause_ ), continues execution at the end of the region." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " For an activated `cancel taskgroup` construct, the tasks that belong to the taskgroup set of the innermost enclosing taskgroup region will be canceled. " + " For an activated `cancel taskgroup` construct, the tasks that belong to the taskgroup set of the innermost enclosing taskgroup region will be canceled. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " A task that encounters the cancel taskgroup construct continues execution at the end of its task region. Any task of the taskgroup that has already begun execution will run to completion, unless it encounters a `cancellation point` ; tasks that have not begun execution 'may' be discarded as completed tasks. " + " A task that encounters the cancel taskgroup construct continues execution at the end of its task region. Any task of the taskgroup that has already begun execution will run to completion, unless it encounters a `cancellation point` ; tasks that have not begun execution 'may' be discarded as completed tasks." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " bigskip CONTROL VARIABLES " + " bigskip CONTROL VARIABLES " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " Internal control variables (ICV) are used by implementations to hold values which control the execution of OpenMP regions. Control (and hence the ICVs) may be set as implementation defaults, or set and adjusted through environment variables, clauses, and API functions. Many of the ICV control values are accessible through API function calls. Also, initial ICV values are reported by the runtime if the `OMP_DISPLAY_ENV` environment variable has been set to `TRUE` . " + " Internal control variables (ICV) are used by implementations to hold values which control the execution of OpenMP regions. Control (and hence the ICVs) may be set as implementation defaults, or set and adjusted through environment variables, clauses, and API functions. Many of the ICV control values are accessible through API function calls. Also, initial ICV values are reported by the runtime if the `OMP_DISPLAY_ENV` environment variable has been set to `TRUE` . " ] }, { @@ -74,14 +74,14 @@ "value is implementation defined. All of the ICVs are presented in the _Internal Control Variables_ section \n", "of the _Directives_ chapter of the OpenMP Specifications document. Within the same document section, override \n", "relationships and scoping information can be found for applying user specifications and understanding the \n", -"extent of the control. " +"extent of the control." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " bigskip NESTED CONSTRUCTS " + " bigskip NESTED CONSTRUCTS" ] }, { @@ -90,7 +90,7 @@ "source": [ " Certain combinations of nested constructs are permitted, giving rise to a _combined_ construct consisting of two or more constructs. These can be used when the two (or several) constructs would be used immediately in succession (closely nested). A combined construct can use the clauses of the component constructs without restrictions. A _composite_ construct is a combined construct which has one or more clauses with (an often obviously) modified or restricted meaning, relative to when the constructs are uncombined. \n", "\n", -"[appear separately (singly). " +"[appear separately (singly)." ] }, { @@ -102,35 +102,35 @@ "construct with one of the loops constructs `do` or `for` . The \n", " `parallel do SIMD` and `parallel for SIMD` constructs are composite constructs (composed from \n", "the parallel loop constructs and the `SIMD` construct), because the `collapse` clause must \n", -"explicitly address the ordering of loop chunking _and_ SIMD 'combined' execution. " +"explicitly address the ordering of loop chunking _and_ SIMD 'combined' execution." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " Certain nestings are forbidden, and often the reasoning is obvious. Worksharing constructs cannot be nested, and the `barrier` construct cannot be nested inside a worksharing construct, or a `critical` construct. Also, `target` constructs cannot be nested. " + " Certain nestings are forbidden, and often the reasoning is obvious. Worksharing constructs cannot be nested, and the `barrier` construct cannot be nested inside a worksharing construct, or a `critical` construct. Also, `target` constructs cannot be nested. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The `parallel` construct can be nested, as well as the `task` construct. The parallel execution in the nested `parallel` construct(s) is control by the `OMP_NESTED` and `OMP_MAX_ACTIVE_LEVELS` environment variables, and the `omp_set_nested()` and `omp_set_max_active_levels()` functions. " + " The `parallel` construct can be nested, as well as the `task` construct. The parallel execution in the nested `parallel` construct(s) is control by the `OMP_NESTED` and `OMP_MAX_ACTIVE_LEVELS` environment variables, and the `omp_set_nested()` and `omp_set_max_active_levels()` functions." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " More details on nesting can be found in the _Nesting of Regions_ of the _Directives_ chapter in the OpenMP Specifications document. " + " More details on nesting can be found in the _Nesting of Regions_ of the _Directives_ chapter in the OpenMP Specifications document." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---end--- " + "---end---" ] } ], @@ -148,4 +148,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/notebook/Chap_synchronization.ipynb b/notebook/Chap_synchronization.ipynb index 56cc212..b8b11bc 100644 --- a/notebook/Chap_synchronization.ipynb +++ b/notebook/Chap_synchronization.ipynb @@ -4,28 +4,28 @@ "cell_type": "markdown", "metadata": {}, "source": [ - " ## Synchronization " + " ## Synchronization" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The `barrier` construct is a stand-alone directive that requires all threads of a team (within a contention group) to execute the barrier and complete execution of all tasks within the region, before continuing past the barrier. " + " The `barrier` construct is a stand-alone directive that requires all threads of a team (within a contention group) to execute the barrier and complete execution of all tasks within the region, before continuing past the barrier." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The `critical` construct is a directive that contains a structured block. The construct allows only a single thread at a time to execute the structured block (region). Multiple critical regions may exist in a parallel region, and may act cooperatively (only one thread at a time in all `critical` regions), or separately (only one thread at a time in each `critical` regions when a unique name is supplied on each `critical` construct). An optional (lock) `hint` clause may be specified on a named `critical` construct to provide the OpenMP runtime guidance in selection a locking mechanism. " + " The `critical` construct is a directive that contains a structured block. The construct allows only a single thread at a time to execute the structured block (region). Multiple critical regions may exist in a parallel region, and may act cooperatively (only one thread at a time in all `critical` regions), or separately (only one thread at a time in each `critical` regions when a unique name is supplied on each `critical` construct). An optional (lock) `hint` clause may be specified on a named `critical` construct to provide the OpenMP runtime guidance in selection a locking mechanism." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " On a finer scale the `atomic` construct allows only a single thread at a time to have atomic access to a storage location involving a single read, write, update or capture statement, and a limited number of combinations when specifying the `capture` _atomic-clause_ clause. The _atomic-clause_ clause is required for some expression statements, but are not required for `update` statements. Please see the details in the _atomic Construct_ subsection of the _Directives_ chapter in the OpenMP Specifications document. " + " On a finer scale the `atomic` construct allows only a single thread at a time to have atomic access to a storage location involving a single read, write, update or capture statement, and a limited number of combinations when specifying the `capture` _atomic-clause_ clause. The _atomic-clause_ clause is required for some expression statements, but are not required for `update` statements. Please see the details in the _atomic Construct_ subsection of the _Directives_ chapter in the OpenMP Specifications document." ] }, { @@ -33,28 +33,28 @@ "metadata": {}, "source": [ " \n", -" The following three sentences were stolen from the spec. The `ordered` construct either specifies a structured block in a loop, simd, or loop SIMD region that will be executed in the order of the loop iterations. The ordered construct sequentializes and orders the execution of ordered regions while allowing code outside the region to run in parallel. " +" The following three sentences were stolen from the spec. The `ordered` construct either specifies a structured block in a loop, simd, or loop SIMD region that will be executed in the order of the loop iterations. The ordered construct sequentializes and orders the execution of ordered regions while allowing code outside the region to run in parallel." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " Since OpenMP 4.5 the `ordered` construct can also be a stand-alone directive that specifies cross-iteration dependences in a doacross loop nest. The `depend` clause uses a `sink` _dependence-type_ , along with a iteration vector argument (vec) to indicate the iteration that satisfies the dependence. The `depend` clause with a `source` _dependence-type_ specifies dependence satisfaction. " + " Since OpenMP 4.5 the `ordered` construct can also be a stand-alone directive that specifies cross-iteration dependences in a doacross loop nest. The `depend` clause uses a `sink` _dependence-type_ , along with a iteration vector argument (vec) to indicate the iteration that satisfies the dependence. The `depend` clause with a `source` _dependence-type_ specifies dependence satisfaction." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The `flush` directive is a stand-alone construct that forces a thread's temporal local storage (view) of a variable to memory where a consistent view of the variable storage can be accesses. When the construct is used without a variable list, all the locally thread-visible data as defined by the base language are flushed. A construct with a list applies the flush operation only to the items in the list. The `flush` construct also effectively insures that no memory (load or store) operation for the variable set (list items, or default set) may be reordered across the `flush` directive. " + " The `flush` directive is a stand-alone construct that forces a thread's temporal local storage (view) of a variable to memory where a consistent view of the variable storage can be accesses. When the construct is used without a variable list, all the locally thread-visible data as defined by the base language are flushed. A construct with a list applies the flush operation only to the items in the list. The `flush` construct also effectively insures that no memory (load or store) operation for the variable set (list items, or default set) may be reordered across the `flush` directive. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " General-purpose routines provide mutual exclusion semantics through locks, represented by lock variables. The semantics allows a task to _set_ , and hence _own_ a lock, until it is _unset_ by the task that set it. A _nestable_ lock can be set multiple times by a task, and is used when in code requires nested control of locks. A _simple lock_ can only be set once by the owning task. There are specific calls for the two types of locks, and the variable of a specific lock type cannot be used by the other lock type. " + " General-purpose routines provide mutual exclusion semantics through locks, represented by lock variables. The semantics allows a task to _set_ , and hence _own_ a lock, until it is _unset_ by the task that set it. A _nestable_ lock can be set multiple times by a task, and is used when in code requires nested control of locks. A _simple lock_ can only be set once by the owning task. There are specific calls for the two types of locks, and the variable of a specific lock type cannot be used by the other lock type. " ] }, { @@ -62,14 +62,14 @@ "metadata": {}, "source": [ " Any explicit task will observe the synchronization prescribed in a `barrier` construct and an implied barrier. Also, additional synchronizations are available for tasks. All children of a task will wait at a `taskwait` (for their siblings to complete). A `taskgroup` construct creates a region in which the current task is suspended at the end of the region until all sibling tasks, and their descendants, have completed. Scheduling constraints on task execution can be prescribed by the `depend` clause to enforce dependence on previously generated tasks. More details on controlling task executions can be found in the _Tasking_ Chapter in the OpenMP Specifications document. \n", -"(DO REF. RIGHT.) " +"(DO REF. RIGHT.)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---end--- " + "---end---" ] } ], @@ -87,4 +87,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/notebook/Chap_tasking.ipynb b/notebook/Chap_tasking.ipynb index bdfd1f1..067119c 100644 --- a/notebook/Chap_tasking.ipynb +++ b/notebook/Chap_tasking.ipynb @@ -4,14 +4,14 @@ "cell_type": "markdown", "metadata": {}, "source": [ - " ## Tasking " + " ## Tasking" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " Tasking constructs provide units of work to a thread for execution. Worksharing constructs do this, too (e.g. `for` , `do` , `sections` , and `singles` constructs); but the work units are tightly controlled by an iteration limit and limited scheduling, or a limited number of `sections` or `single` regions. Worksharing was designed with ' data parallel ' computing in mind. Tasking was designed for ' task parallel ' computing and often involves non-locality or irregularity in memory access. " + " Tasking constructs provide units of work to a thread for execution. Worksharing constructs do this, too (e.g. `for` , `do` , `sections` , and `singles` constructs); but the work units are tightly controlled by an iteration limit and limited scheduling, or a limited number of `sections` or `single` regions. Worksharing was designed with ' data parallel ' computing in mind. Tasking was designed for ' task parallel ' computing and often involves non-locality or irregularity in memory access." ] }, { @@ -19,42 +19,42 @@ "metadata": {}, "source": [ " The `task` construct can be used to execute work chunks: in a while loop; while traversing nodes in a list; at nodes in a tree graph; or in a normal loop (with a `taskloop` construct). Unlike the statically scheduled loop iterations of worksharing, a task is often enqueued, and then dequeued for execution by any of the threads of the team within a parallel region. The generation of tasks can be from a single generating thread (creating sibling tasks), or from multiple generators in a recursive graph tree traversals. \n", -"(creating a parent-descendents hierarchy of tasks, see example 4 and 7 below). A `taskloop` construct bundles iterations of an associated loop into tasks, and provides similar controls found in the `task` construct. " +"(creating a parent-descendents hierarchy of tasks, see example 4 and 7 below). A `taskloop` construct bundles iterations of an associated loop into tasks, and provides similar controls found in the `task` construct." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " Sibling tasks are synchronized by the `taskwait` construct, and tasks and their descendent tasks can be synchronized by containing them in a `taskgroup` region. Ordered execution is accomplished by specifying dependences with a `depend` clause. Also, priorities can be specified as hints to the scheduler through a `priority` clause. " + " Sibling tasks are synchronized by the `taskwait` construct, and tasks and their descendent tasks can be synchronized by containing them in a `taskgroup` region. Ordered execution is accomplished by specifying dependences with a `depend` clause. Also, priorities can be specified as hints to the scheduler through a `priority` clause." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " Various clauses can be used to manage and optimize task generation, as well as reduce the overhead of execution and to relinquish control of threads for work balance and forward progress. " + " Various clauses can be used to manage and optimize task generation, as well as reduce the overhead of execution and to relinquish control of threads for work balance and forward progress. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " Once a thread starts executing a task, it is the designated thread for executing the task to completion, even though it may leave the execution at a scheduling point and return later. The thread is tied to the task. Scheduling points can be introduced with the `taskyield` construct. With an `untied` clause any other thread is allowed to continue the task. An `if` clause with a _true_ expression allows the generating thread to immediately execute the task as an undeferred task. By including the data environment of the generating task into the generated task with the `mergeable` and `final` clauses, task generation overhead can be reduced. " + " Once a thread starts executing a task, it is the designated thread for executing the task to completion, even though it may leave the execution at a scheduling point and return later. The thread is tied to the task. Scheduling points can be introduced with the `taskyield` construct. With an `untied` clause any other thread is allowed to continue the task. An `if` clause with a _true_ expression allows the generating thread to immediately execute the task as an undeferred task. By including the data environment of the generating task into the generated task with the `mergeable` and `final` clauses, task generation overhead can be reduced." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " A complete list of the tasking constructs and details of their clauses can be found in the _Tasking Constructs_ chapter of the OpenMP Specifications, in the _OpenMP Application Programming Interface_ section. " + " A complete list of the tasking constructs and details of their clauses can be found in the _Tasking Constructs_ chapter of the OpenMP Specifications, in the _OpenMP Application Programming Interface_ section." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---end--- " + "---end---" ] } ], @@ -72,4 +72,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/notebook/Examples_Chapt.ipynb b/notebook/Examples_Chapt.ipynb index c493b38..f37c20e 100644 --- a/notebook/Examples_Chapt.ipynb +++ b/notebook/Examples_Chapt.ipynb @@ -4,14 +4,14 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "chapter*{Examples} " + "chapter*{Examples}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " addcontentsline{toc}{chapter}{protectnumberline{}Examples} The following are examples of the OpenMP API directives, constructs, and routines. ccppspecificstart A statement following a directive is compound only when necessary, and a non-compound statement is indented with respect to a directive preceding it. ccppspecificend " + " addcontentsline{toc}{chapter}{protectnumberline{}Examples} The following are examples of the OpenMP API directives, constructs, and routines. ccppspecificstart A statement following a directive is compound only when necessary, and a non-compound statement is indented with respect to a directive preceding it. ccppspecificend" ] }, { @@ -22,14 +22,14 @@ "* _c_ -- C code, \n", "* _cpp_ -- C++ code, \n", "* _f_ -- Fortran code in fixed form, and \n", -"* _f90_ -- Fortran code in free form. " +"* _f90_ -- Fortran code in free form. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---end--- " + "---end---" ] } ], @@ -47,4 +47,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/notebook/Examples_SIMD.ipynb b/notebook/Examples_SIMD.ipynb index 14fc55a..cbf4e95 100644 --- a/notebook/Examples_SIMD.ipynb +++ b/notebook/Examples_SIMD.ipynb @@ -5,14 +5,14 @@ "metadata": {}, "source": [ " \n", -" ### `simd` and `declare` `simd` Constructs " +" ### `simd` and `declare` `simd` Constructs" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example illustrates the basic use of the `simd` construct to assure the compiler that the loop can be vectorized. " + " The following example illustrates the basic use of the `simd` construct to assure the compiler that the loop can be vectorized." ] }, { @@ -21,7 +21,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_SIMD.1.c " + "%load ../sources/Example_SIMD.1.c" ] }, { @@ -30,35 +30,35 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_SIMD.1.f90 " + "%load ../sources/Example_SIMD.1.f90" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " " + " " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " When a function can be inlined within a loop the compiler has an opportunity to vectorize the loop. By guaranteeing SIMD behavior of a function's operations, characterizing the arguments of the function and privatizing temporary variables of the loop, the compiler can often create faster, vector code for the loop. In the examples below the `declare` `simd` construct is used on the _add1_ and _add2_ functions to enable creation of their corresponding SIMD function versions for execution within the associated SIMD loop. The functions characterize two different approaches of accessing data within the function: by a single variable and as an element in a data array, respectively. The _add3_ C function uses dereferencing. " + " When a function can be inlined within a loop the compiler has an opportunity to vectorize the loop. By guaranteeing SIMD behavior of a function's operations, characterizing the arguments of the function and privatizing temporary variables of the loop, the compiler can often create faster, vector code for the loop. In the examples below the `declare` `simd` construct is used on the _add1_ and _add2_ functions to enable creation of their corresponding SIMD function versions for execution within the associated SIMD loop. The functions characterize two different approaches of accessing data within the function: by a single variable and as an element in a data array, respectively. The _add3_ C function uses dereferencing." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The `declare` `simd` constructs also illustrate the use of `uniform` and `linear` clauses. The `uniform(fact)` clause indicates that the variable _fact_ is invariant across the SIMD lanes. In the _add2_ function _a_ and _b_ are included in the `unform` list because the C pointer and the Fortran array references are constant. The _i_ index used in the _add2_ function is included in a `linear` clause with a constant-linear-step of 1, to guarantee a unity increment of the associated loop. In the `declare` `simd` construct for the _add3_ C function the `linear(a,b:1)` clause instructs the compiler to generate unit-stride loads across the SIMD lanes; otherwise, costly emph{gather} instructions would be generated for the unknown sequence of access of the pointer dereferences. " + " The `declare` `simd` constructs also illustrate the use of `uniform` and `linear` clauses. The `uniform(fact)` clause indicates that the variable _fact_ is invariant across the SIMD lanes. In the _add2_ function _a_ and _b_ are included in the `unform` list because the C pointer and the Fortran array references are constant. The _i_ index used in the _add2_ function is included in a `linear` clause with a constant-linear-step of 1, to guarantee a unity increment of the associated loop. In the `declare` `simd` construct for the _add3_ C function the `linear(a,b:1)` clause instructs the compiler to generate unit-stride loads across the SIMD lanes; otherwise, costly emph{gather} instructions would be generated for the unknown sequence of access of the pointer dereferences." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " In the `simd` constructs for the loops the `private(tmp)` clause is necessary to assure that the each vector operation has its own _tmp_ variable. " + " In the `simd` constructs for the loops the `private(tmp)` clause is necessary to assure that the each vector operation has its own _tmp_ variable." ] }, { @@ -67,7 +67,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_SIMD.2.c " + "%load ../sources/Example_SIMD.2.c" ] }, { @@ -76,14 +76,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_SIMD.2.f90 " + "%load ../sources/Example_SIMD.2.f90" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " A thread that encounters a SIMD construct executes a vectorized code of the iterations. Similar to the concerns of a worksharing loop a loop vectorized with a SIMD construct must assure that temporary and reduction variables are privatized and declared as reductions with clauses. The example below illustrates the use of `private` and `reduction` clauses in a SIMD construct. " + " A thread that encounters a SIMD construct executes a vectorized code of the iterations. Similar to the concerns of a worksharing loop a loop vectorized with a SIMD construct must assure that temporary and reduction variables are privatized and declared as reductions with clauses. The example below illustrates the use of `private` and `reduction` clauses in a SIMD construct." ] }, { @@ -92,7 +92,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_SIMD.3.c " + "%load ../sources/Example_SIMD.3.c" ] }, { @@ -101,14 +101,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_SIMD.3.f90 " + "%load ../sources/Example_SIMD.3.f90" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " A `safelen(N)` clause in a `simd` construct assures the compiler that there are no loop-carried dependencies for vectors of size _N_ or below. If the `safelen` clause is not specified, then the default safelen value is the number of loop iterations. The `safelen(16)` clause in the example below guarantees that the vector code is safe for vectors up to and including size 16. In the loop, _m_ can be 16 or greater, for correct code execution. If the value of _m_ is less than 16, the behavior is undefined. " + " A `safelen(N)` clause in a `simd` construct assures the compiler that there are no loop-carried dependencies for vectors of size _N_ or below. If the `safelen` clause is not specified, then the default safelen value is the number of loop iterations. The `safelen(16)` clause in the example below guarantees that the vector code is safe for vectors up to and including size 16. In the loop, _m_ can be 16 or greater, for correct code execution. If the value of _m_ is less than 16, the behavior is undefined." ] }, { @@ -117,7 +117,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_SIMD.4.c " + "%load ../sources/Example_SIMD.4.c" ] }, { @@ -126,14 +126,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_SIMD.4.f90 " + "%load ../sources/Example_SIMD.4.f90" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following SIMD construct instructs the compiler to collapse the _i_ and _j_ loops into a single SIMD loop in which SIMD chunks are executed by threads of the team. Within the workshared loop chunks of a thread, the SIMD chunks are executed in the lanes of the vector units. " + " The following SIMD construct instructs the compiler to collapse the _i_ and _j_ loops into a single SIMD loop in which SIMD chunks are executed by threads of the team. Within the workshared loop chunks of a thread, the SIMD chunks are executed in the lanes of the vector units." ] }, { @@ -142,7 +142,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_SIMD.5.c " + "%load ../sources/Example_SIMD.5.c" ] }, { @@ -151,7 +151,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_SIMD.5.f90 " + "%load ../sources/Example_SIMD.5.f90" ] }, { @@ -161,14 +161,14 @@ " \n", "\n", "\n", -" section ### `inbranch` and `notinbranch` Clauses " +" section ### `inbranch` and `notinbranch` Clauses" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following examples illustrate the use of the `declare` `simd` construct with the `inbranch` and `notinbranch` clauses. The `notinbranch` clause informs the compiler that the function _foo_ is never called conditionally in the SIMD loop of the function _myaddint_ . On the other hand, the `inbranch` clause for the function goo indicates that the function is always called conditionally in the SIMD loop inside the function _myaddfloat_ . " + " The following examples illustrate the use of the `declare` `simd` construct with the `inbranch` and `notinbranch` clauses. The `notinbranch` clause informs the compiler that the function _foo_ is never called conditionally in the SIMD loop of the function _myaddint_ . On the other hand, the `inbranch` clause for the function goo indicates that the function is always called conditionally in the SIMD loop inside the function _myaddfloat_ ." ] }, { @@ -177,7 +177,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_SIMD.6.c " + "%load ../sources/Example_SIMD.6.c" ] }, { @@ -186,14 +186,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_SIMD.6.f90 " + "%load ../sources/Example_SIMD.6.f90" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " In the code below, the function _fib()_ is called in the main program and also recursively called in the function _fib()_ within an `if` condition. The compiler creates a masked vector version and a non-masked vector version for the function _fib()_ while retaining the original scalar version of the _fib()_ function. " + " In the code below, the function _fib()_ is called in the main program and also recursively called in the function _fib()_ within an `if` condition. The compiler creates a masked vector version and a non-masked vector version for the function _fib()_ while retaining the original scalar version of the _fib()_ function." ] }, { @@ -202,7 +202,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_SIMD.7.c " + "%load ../sources/Example_SIMD.7.c" ] }, { @@ -211,7 +211,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_SIMD.7.f90 " + "%load ../sources/Example_SIMD.7.f90" ] }, { @@ -221,28 +221,28 @@ " \n", "\n", "\n", -" section ### Loop-Carried Lexical Forward Dependence " +" section ### Loop-Carried Lexical Forward Dependence" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example tests the restriction on an SIMD loop with the loop-carried lexical forward-dependence. This dependence must be preserved for the correct execution of SIMD loops. " + " The following example tests the restriction on an SIMD loop with the loop-carried lexical forward-dependence. This dependence must be preserved for the correct execution of SIMD loops." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " A loop can be vectorized even though the iterations are not completely independent when it has loop-carried dependences that are forward lexical dependences, indicated in the code below by the read of _A[j+1]_ and the write to _A[j]_ in C/C++ code (or _A(j+1)_ and _A(j)_ in Fortran). That is, the read of _A[j+1]_ (or _A(j+1)_ in Fortran) before the write to _A[j]_ (or _A(j)_ in Fortran) ordering must be preserved for each iteration in _j_ for valid SIMD code generation. " + " A loop can be vectorized even though the iterations are not completely independent when it has loop-carried dependences that are forward lexical dependences, indicated in the code below by the read of _A[j+1]_ and the write to _A[j]_ in C/C++ code (or _A(j+1)_ and _A(j)_ in Fortran). That is, the read of _A[j+1]_ (or _A(j+1)_ in Fortran) before the write to _A[j]_ (or _A(j)_ in Fortran) ordering must be preserved for each iteration in _j_ for valid SIMD code generation." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " This test assures that the compiler preserves the loop carried lexical forward-dependence for generating a correct SIMD code. " + " This test assures that the compiler preserves the loop carried lexical forward-dependence for generating a correct SIMD code." ] }, { @@ -251,7 +251,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_SIMD.8.c " + "%load ../sources/Example_SIMD.8.c" ] }, { @@ -260,14 +260,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_SIMD.8.f90 " + "%load ../sources/Example_SIMD.8.f90" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---end--- " + "---end---" ] } ], @@ -285,4 +285,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/notebook/Examples_affinity.ipynb b/notebook/Examples_affinity.ipynb index d6b97a0..6a29705 100644 --- a/notebook/Examples_affinity.ipynb +++ b/notebook/Examples_affinity.ipynb @@ -4,14 +4,14 @@ "cell_type": "markdown", "metadata": {}, "source": [ - " ### The `proc_bind` Clause " + " ### The `proc_bind` Clause" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following examples demonstrate how to use the `proc_bind` clause to control the thread binding for a team of threads in a `parallel` region. The machine architecture is depicted in the figure below. It consists of two sockets, each equipped with a quad-core processor and configured to execute two hardware threads simultaneously on each core. These examples assume a contiguous core numbering starting from 0, such that the hardware threads 0,1 form the first physical core. " + " The following examples demonstrate how to use the `proc_bind` clause to control the thread binding for a team of threads in a `parallel` region. The machine architecture is depicted in the figure below. It consists of two sockets, each equipped with a quad-core processor and configured to execute two hardware threads simultaneously on each core. These examples assume a contiguous core numbering starting from 0, such that the hardware threads 0,1 form the first physical core." ] }, { @@ -19,49 +19,49 @@ "metadata": {}, "source": [ " {figs/proc_bind_fig.pdf}} \n", -" fi " +" fi" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following equivalent place list declarations consist of eight places (which we designate as p0 to p7): " + " The following equivalent place list declarations consist of eight places (which we designate as p0 to p7):" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " `OMP_PLACES= ' {0,1},{2,3},{4,5},{6,7},{8,9},{10,11},{12,13},{14,15} ' ` " + " `OMP_PLACES= ' {0,1},{2,3},{4,5},{6,7},{8,9},{10,11},{12,13},{14,15} ' ` " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " or " + " or" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " `OMP_PLACES= ' {0:2}:8:2 ' ` " + " `OMP_PLACES= ' {0:2}:8:2 ' ` " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " #### Spread Affinity Policy " + " #### Spread Affinity Policy" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example shows the result of the `spread` affinity policy on the partition list when the number of threads is less than or equal to the number of places in the parent's place partition, for the machine architecture depicted above. Note that the threads are bound to the first place of each subpartition. " + " The following example shows the result of the `spread` affinity policy on the partition list when the number of threads is less than or equal to the number of places in the parent's place partition, for the machine architecture depicted above. Note that the threads are bound to the first place of each subpartition." ] }, { @@ -70,7 +70,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_affinity.1.c " + "%load ../sources/Example_affinity.1.c" ] }, { @@ -79,14 +79,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_affinity.1.f " + "%load ../sources/Example_affinity.1.f" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " It is unspecified on which place the master thread is initially started. If the master thread is initially started on p0, the following placement of threads will be applied in the parallel region: " + " It is unspecified on which place the master thread is initially started. If the master thread is initially started on p0, the following placement of threads will be applied in the parallel region:" ] }, { @@ -94,7 +94,7 @@ "metadata": {}, "source": [ " \n", -"* thread 0 executes on p0 with the place partition p0,p1 " +"* thread 0 executes on p0 with the place partition p0,p1" ] }, { @@ -102,7 +102,7 @@ "metadata": {}, "source": [ " \n", -"* thread 1 executes on p2 with the place partition p2,p3 " +"* thread 1 executes on p2 with the place partition p2,p3" ] }, { @@ -110,7 +110,7 @@ "metadata": {}, "source": [ " \n", -"* thread 2 executes on p4 with the place partition p4,p5 " +"* thread 2 executes on p4 with the place partition p4,p5" ] }, { @@ -118,14 +118,14 @@ "metadata": {}, "source": [ " \n", -"* thread 3 executes on p6 with the place partition p6,p7 " +"* thread 3 executes on p6 with the place partition p6,p7 " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " If the master thread would initially be started on p2, the placement of threads and distribution of the place partition would be as follows: " + " If the master thread would initially be started on p2, the placement of threads and distribution of the place partition would be as follows:" ] }, { @@ -133,7 +133,7 @@ "metadata": {}, "source": [ " \n", -"* thread 0 executes on p2 with the place partition p2,p3 " +"* thread 0 executes on p2 with the place partition p2,p3" ] }, { @@ -141,7 +141,7 @@ "metadata": {}, "source": [ " \n", -"* thread 1 executes on p4 with the place partition p4,p5 " +"* thread 1 executes on p4 with the place partition p4,p5" ] }, { @@ -149,7 +149,7 @@ "metadata": {}, "source": [ " \n", -"* thread 2 executes on p6 with the place partition p6,p7 " +"* thread 2 executes on p6 with the place partition p6,p7" ] }, { @@ -157,21 +157,21 @@ "metadata": {}, "source": [ " \n", -"* thread 3 executes on p0 with the place partition p0,p1 " +"* thread 3 executes on p0 with the place partition p0,p1 " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example illustrates the `spread` thread affinity policy when the number of threads is greater than the number of places in the parent's place partition. " + " The following example illustrates the `spread` thread affinity policy when the number of threads is greater than the number of places in the parent's place partition." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " Let _T_ be the number of threads in the team, and _P_ be the number of places in the parent's place partition. The first _T/P_ threads of the team (including the master thread) execute on the parent's place. The next _T/P_ threads execute on the next place in the place partition, and so on, with wrap around. " + " Let _T_ be the number of threads in the team, and _P_ be the number of places in the parent's place partition. The first _T/P_ threads of the team (including the master thread) execute on the parent's place. The next _T/P_ threads execute on the next place in the place partition, and so on, with wrap around. " ] }, { @@ -180,7 +180,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_affinity.2.c " + "%load ../sources/Example_affinity.2.c" ] }, { @@ -189,14 +189,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_affinity.2.f90 " + "%load ../sources/Example_affinity.2.f90" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " It is unspecified on which place the master thread is initially started. If the master thread is initially started on p0, the following placement of threads will be applied in the parallel region: " + " It is unspecified on which place the master thread is initially started. If the master thread is initially started on p0, the following placement of threads will be applied in the parallel region:" ] }, { @@ -204,7 +204,7 @@ "metadata": {}, "source": [ " \n", -"* threads 0,1 execute on p0 with the place partition p0 " +"* threads 0,1 execute on p0 with the place partition p0" ] }, { @@ -212,7 +212,7 @@ "metadata": {}, "source": [ " \n", -"* threads 2,3 execute on p1 with the place partition p1 " +"* threads 2,3 execute on p1 with the place partition p1" ] }, { @@ -220,7 +220,7 @@ "metadata": {}, "source": [ " \n", -"* threads 4,5 execute on p2 with the place partition p2 " +"* threads 4,5 execute on p2 with the place partition p2" ] }, { @@ -228,7 +228,7 @@ "metadata": {}, "source": [ " \n", -"* threads 6,7 execute on p3 with the place partition p3 " +"* threads 6,7 execute on p3 with the place partition p3" ] }, { @@ -236,7 +236,7 @@ "metadata": {}, "source": [ " \n", -"* threads 8,9 execute on p4 with the place partition p4 " +"* threads 8,9 execute on p4 with the place partition p4" ] }, { @@ -244,7 +244,7 @@ "metadata": {}, "source": [ " \n", -"* threads 10,11 execute on p5 with the place partition p5 " +"* threads 10,11 execute on p5 with the place partition p5" ] }, { @@ -252,7 +252,7 @@ "metadata": {}, "source": [ " \n", -"* threads 12,13 execute on p6 with the place partition p6 " +"* threads 12,13 execute on p6 with the place partition p6" ] }, { @@ -260,14 +260,14 @@ "metadata": {}, "source": [ " \n", -"* threads 14,15 execute on p7 with the place partition p7 " +"* threads 14,15 execute on p7 with the place partition p7 " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " If the master thread would initially be started on p2, the placement of threads and distribution of the place partition would be as follows: " + " If the master thread would initially be started on p2, the placement of threads and distribution of the place partition would be as follows:" ] }, { @@ -275,7 +275,7 @@ "metadata": {}, "source": [ " \n", -"* threads 0,1 execute on p2 with the place partition p2 " +"* threads 0,1 execute on p2 with the place partition p2" ] }, { @@ -283,7 +283,7 @@ "metadata": {}, "source": [ " \n", -"* threads 2,3 execute on p3 with the place partition p3 " +"* threads 2,3 execute on p3 with the place partition p3" ] }, { @@ -291,7 +291,7 @@ "metadata": {}, "source": [ " \n", -"* threads 4,5 execute on p4 with the place partition p4 " +"* threads 4,5 execute on p4 with the place partition p4" ] }, { @@ -299,7 +299,7 @@ "metadata": {}, "source": [ " \n", -"* threads 6,7 execute on p5 with the place partition p5 " +"* threads 6,7 execute on p5 with the place partition p5" ] }, { @@ -307,7 +307,7 @@ "metadata": {}, "source": [ " \n", -"* threads 8,9 execute on p6 with the place partition p6 " +"* threads 8,9 execute on p6 with the place partition p6" ] }, { @@ -315,7 +315,7 @@ "metadata": {}, "source": [ " \n", -"* threads 10,11 execute on p7 with the place partition p7 " +"* threads 10,11 execute on p7 with the place partition p7" ] }, { @@ -323,7 +323,7 @@ "metadata": {}, "source": [ " \n", -"* threads 12,13 execute on p0 with the place partition p0 " +"* threads 12,13 execute on p0 with the place partition p0" ] }, { @@ -331,21 +331,21 @@ "metadata": {}, "source": [ " \n", -"* threads 14,15 execute on p1 with the place partition p1 " +"* threads 14,15 execute on p1 with the place partition p1 " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " #### Close Affinity Policy " + " #### Close Affinity Policy" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example shows the result of the `close` affinity policy on the partition list when the number of threads is less than or equal to the number of places in parent's place partition, for the machine architecture depicted above. The place partition is not changed by the `close` policy. " + " The following example shows the result of the `close` affinity policy on the partition list when the number of threads is less than or equal to the number of places in parent's place partition, for the machine architecture depicted above. The place partition is not changed by the `close` policy." ] }, { @@ -354,7 +354,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_affinity.3.c " + "%load ../sources/Example_affinity.3.c" ] }, { @@ -363,14 +363,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_affinity.3.f " + "%load ../sources/Example_affinity.3.f" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " It is unspecified on which place the master thread is initially started. If the master thread is initially started on p0, the following placement of threads will be applied in the `parallel` region: " + " It is unspecified on which place the master thread is initially started. If the master thread is initially started on p0, the following placement of threads will be applied in the `parallel` region:" ] }, { @@ -378,7 +378,7 @@ "metadata": {}, "source": [ " \n", -"* thread 0 executes on p0 with the place partition p0-p7 " +"* thread 0 executes on p0 with the place partition p0-p7" ] }, { @@ -386,7 +386,7 @@ "metadata": {}, "source": [ " \n", -"* thread 1 executes on p1 with the place partition p0-p7 " +"* thread 1 executes on p1 with the place partition p0-p7" ] }, { @@ -394,7 +394,7 @@ "metadata": {}, "source": [ " \n", -"* thread 2 executes on p2 with the place partition p0-p7 " +"* thread 2 executes on p2 with the place partition p0-p7" ] }, { @@ -402,14 +402,14 @@ "metadata": {}, "source": [ " \n", -"* thread 3 executes on p3 with the place partition p0-p7 " +"* thread 3 executes on p3 with the place partition p0-p7 " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " If the master thread would initially be started on p2, the placement of threads and distribution of the place partition would be as follows: " + " If the master thread would initially be started on p2, the placement of threads and distribution of the place partition would be as follows:" ] }, { @@ -417,7 +417,7 @@ "metadata": {}, "source": [ " \n", -"* thread 0 executes on p2 with the place partition p0-p7 " +"* thread 0 executes on p2 with the place partition p0-p7" ] }, { @@ -425,7 +425,7 @@ "metadata": {}, "source": [ " \n", -"* thread 1 executes on p3 with the place partition p0-p7 " +"* thread 1 executes on p3 with the place partition p0-p7" ] }, { @@ -433,7 +433,7 @@ "metadata": {}, "source": [ " \n", -"* thread 2 executes on p4 with the place partition p0-p7 " +"* thread 2 executes on p4 with the place partition p0-p7" ] }, { @@ -441,21 +441,21 @@ "metadata": {}, "source": [ " \n", -"* thread 3 executes on p5 with the place partition p0-p7 " +"* thread 3 executes on p5 with the place partition p0-p7 " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example illustrates the `close` thread affinity policy when the number of threads is greater than the number of places in the parent's place partition. " + " The following example illustrates the `close` thread affinity policy when the number of threads is greater than the number of places in the parent's place partition." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " Let _T_ be the number of threads in the team, and _P_ be the number of places in the parent's place partition. The first _T/P_ threads of the team (including the master thread) execute on the parent's place. The next _T/P_ threads execute on the next place in the place partition, and so on, with wrap around. The place partition is not changed by the `close` policy. " + " Let _T_ be the number of threads in the team, and _P_ be the number of places in the parent's place partition. The first _T/P_ threads of the team (including the master thread) execute on the parent's place. The next _T/P_ threads execute on the next place in the place partition, and so on, with wrap around. The place partition is not changed by the `close` policy." ] }, { @@ -464,7 +464,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_affinity.4.c " + "%load ../sources/Example_affinity.4.c" ] }, { @@ -473,14 +473,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_affinity.4.f90 " + "%load ../sources/Example_affinity.4.f90" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " It is unspecified on which place the master thread is initially started. If the master thread is initially running on p0, the following placement of threads will be applied in the parallel region: " + " It is unspecified on which place the master thread is initially started. If the master thread is initially running on p0, the following placement of threads will be applied in the parallel region:" ] }, { @@ -488,7 +488,7 @@ "metadata": {}, "source": [ " \n", -"* threads 0,1 execute on p0 with the place partition p0-p7 " +"* threads 0,1 execute on p0 with the place partition p0-p7" ] }, { @@ -496,7 +496,7 @@ "metadata": {}, "source": [ " \n", -"* threads 2,3 execute on p1 with the place partition p0-p7 " +"* threads 2,3 execute on p1 with the place partition p0-p7" ] }, { @@ -504,7 +504,7 @@ "metadata": {}, "source": [ " \n", -"* threads 4,5 execute on p2 with the place partition p0-p7 " +"* threads 4,5 execute on p2 with the place partition p0-p7" ] }, { @@ -512,7 +512,7 @@ "metadata": {}, "source": [ " \n", -"* threads 6,7 execute on p3 with the place partition p0-p7 " +"* threads 6,7 execute on p3 with the place partition p0-p7" ] }, { @@ -520,7 +520,7 @@ "metadata": {}, "source": [ " \n", -"* threads 8,9 execute on p4 with the place partition p0-p7 " +"* threads 8,9 execute on p4 with the place partition p0-p7" ] }, { @@ -528,7 +528,7 @@ "metadata": {}, "source": [ " \n", -"* threads 10,11 execute on p5 with the place partition p0-p7 " +"* threads 10,11 execute on p5 with the place partition p0-p7" ] }, { @@ -536,7 +536,7 @@ "metadata": {}, "source": [ " \n", -"* threads 12,13 execute on p6 with the place partition p0-p7 " +"* threads 12,13 execute on p6 with the place partition p0-p7" ] }, { @@ -544,14 +544,14 @@ "metadata": {}, "source": [ " \n", -"* threads 14,15 execute on p7 with the place partition p0-p7 " +"* threads 14,15 execute on p7 with the place partition p0-p7 " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " If the master thread would initially be started on p2, the placement of threads and distribution of the place partition would be as follows: " + " If the master thread would initially be started on p2, the placement of threads and distribution of the place partition would be as follows:" ] }, { @@ -559,7 +559,7 @@ "metadata": {}, "source": [ " \n", -"* threads 0,1 execute on p2 with the place partition p0-p7 " +"* threads 0,1 execute on p2 with the place partition p0-p7" ] }, { @@ -567,7 +567,7 @@ "metadata": {}, "source": [ " \n", -"* threads 2,3 execute on p3 with the place partition p0-p7 " +"* threads 2,3 execute on p3 with the place partition p0-p7" ] }, { @@ -575,7 +575,7 @@ "metadata": {}, "source": [ " \n", -"* threads 4,5 execute on p4 with the place partition p0-p7 " +"* threads 4,5 execute on p4 with the place partition p0-p7" ] }, { @@ -583,7 +583,7 @@ "metadata": {}, "source": [ " \n", -"* threads 6,7 execute on p5 with the place partition p0-p7 " +"* threads 6,7 execute on p5 with the place partition p0-p7" ] }, { @@ -591,7 +591,7 @@ "metadata": {}, "source": [ " \n", -"* threads 8,9 execute on p6 with the place partition p0-p7 " +"* threads 8,9 execute on p6 with the place partition p0-p7" ] }, { @@ -599,7 +599,7 @@ "metadata": {}, "source": [ " \n", -"* threads 10,11 execute on p7 with the place partition p0-p7 " +"* threads 10,11 execute on p7 with the place partition p0-p7" ] }, { @@ -607,7 +607,7 @@ "metadata": {}, "source": [ " \n", -"* threads 12,13 execute on p0 with the place partition p0-p7 " +"* threads 12,13 execute on p0 with the place partition p0-p7" ] }, { @@ -615,21 +615,21 @@ "metadata": {}, "source": [ " \n", -"* threads 14,15 execute on p1 with the place partition p0-p7 " +"* threads 14,15 execute on p1 with the place partition p0-p7 " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " #### Master Affinity Policy " + " #### Master Affinity Policy" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example shows the result of the `master` affinity policy on the partition list for the machine architecture depicted above. The place partition is not changed by the master policy. " + " The following example shows the result of the `master` affinity policy on the partition list for the machine architecture depicted above. The place partition is not changed by the master policy." ] }, { @@ -638,7 +638,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_affinity.5.c " + "%load ../sources/Example_affinity.5.c" ] }, { @@ -647,14 +647,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_affinity.5.f " + "%load ../sources/Example_affinity.5.f" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " It is unspecified on which place the master thread is initially started. If the master thread is initially running on p0, the following placement of threads will be applied in the parallel region: " + " It is unspecified on which place the master thread is initially started. If the master thread is initially running on p0, the following placement of threads will be applied in the parallel region:" ] }, { @@ -662,14 +662,14 @@ "metadata": {}, "source": [ " \n", -"* threads 0-3 execute on p0 with the place partition p0-p7 " +"* threads 0-3 execute on p0 with the place partition p0-p7 " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " If the master thread would initially be started on p2, the placement of threads and distribution of the place partition would be as follows: " + " If the master thread would initially be started on p2, the placement of threads and distribution of the place partition would be as follows:" ] }, { @@ -677,14 +677,14 @@ "metadata": {}, "source": [ " \n", -"* threads 0-3 execute on p2 with the place partition p0-p7 " +"* threads 0-3 execute on p2 with the place partition p0-p7 " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---end--- " + "---end---" ] } ], @@ -702,4 +702,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/notebook/Examples_affinity_query.ipynb b/notebook/Examples_affinity_query.ipynb index d9db016..32880f6 100644 --- a/notebook/Examples_affinity_query.ipynb +++ b/notebook/Examples_affinity_query.ipynb @@ -4,42 +4,42 @@ "cell_type": "markdown", "metadata": {}, "source": [ - " ### Affinity Query Functions " + " ### Affinity Query Functions" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " In the example below a team of threads is generated on each socket of the system, using nested parallelism. Several query functions are used to gather information to support the creation of the teams and to obtain socket and thread numbers. " + " In the example below a team of threads is generated on each socket of the system, using nested parallelism. Several query functions are used to gather information to support the creation of the teams and to obtain socket and thread numbers." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " For proper execution of the code, the user must create a place partition, such that each place is a listing of the core numbers for a socket. For example, in a 2 socket system with 8 cores in each socket, and sequential numbering in the socket for the core numbers, the `OMP_PLACES` variable would be set to '{0:8},{8:8}', using the place syntax { _lower_bound_ : _length_ : _stride_ }, and the default stride of 1. " + " For proper execution of the code, the user must create a place partition, such that each place is a listing of the core numbers for a socket. For example, in a 2 socket system with 8 cores in each socket, and sequential numbering in the socket for the core numbers, the `OMP_PLACES` variable would be set to '{0:8},{8:8}', using the place syntax { _lower_bound_ : _length_ : _stride_ }, and the default stride of 1." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The code determines the number of sockets ( _n_sockets_ ) using the `omp_get_num_places()` query function. In this example each place is constructed with a list of each socket's core numbers, hence the number of places is equal to the number of sockets. " + " The code determines the number of sockets ( _n_sockets_ ) using the `omp_get_num_places()` query function. In this example each place is constructed with a list of each socket's core numbers, hence the number of places is equal to the number of sockets. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The outer parallel region forms a team of threads, and each thread executes on a socket (place) because the `proc_bind` clause uses `spread` in the outer `parallel` construct. Next, in the _socket_init_ function, an inner parallel region creates a team of threads equal to the number of elements (core numbers) from the place of the parent thread. Because the outer `parallel` construct uses a `spread` affinity policy, each of its threads inherits a subpartition of the original partition. Hence, the `omp_get_place_num_procs` query function returns the number of elements (here procs = cores) in the subpartition of the thread. After each parent thread creates its nested parallel region on the section, the socket number and thread number are reported. " + " The outer parallel region forms a team of threads, and each thread executes on a socket (place) because the `proc_bind` clause uses `spread` in the outer `parallel` construct. Next, in the _socket_init_ function, an inner parallel region creates a team of threads equal to the number of elements (core numbers) from the place of the parent thread. Because the outer `parallel` construct uses a `spread` affinity policy, each of its threads inherits a subpartition of the original partition. Hence, the `omp_get_place_num_procs` query function returns the number of elements (here procs = cores) in the subpartition of the thread. After each parent thread creates its nested parallel region on the section, the socket number and thread number are reported." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " Note: Portable tools like hwloc (Portable HardWare LOCality package), which support many common operating systems, can be used to determine the configuration of a system. On some systems there are utilities, files or user guides that provide configuration information. For instance, the socket number and proc_id's for a socket can be found in the /proc/cpuinfo text file on Linux systems. " + " Note: Portable tools like hwloc (Portable HardWare LOCality package), which support many common operating systems, can be used to determine the configuration of a system. On some systems there are utilities, files or user guides that provide configuration information. For instance, the socket number and proc_id's for a socket can be found in the /proc/cpuinfo text file on Linux systems." ] }, { @@ -48,7 +48,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_affinity.6.c " + "%load ../sources/Example_affinity.6.c" ] }, { @@ -57,14 +57,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_affinity.6.f90 " + "%load ../sources/Example_affinity.6.f90" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---end--- " + "---end---" ] } ], @@ -82,4 +82,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/notebook/Examples_array_sections.ipynb b/notebook/Examples_array_sections.ipynb index 2e8ef95..fdbc4e4 100644 --- a/notebook/Examples_array_sections.ipynb +++ b/notebook/Examples_array_sections.ipynb @@ -4,21 +4,21 @@ "cell_type": "markdown", "metadata": {}, "source": [ - " ### Array Sections in Device Constructs " + " ### Array Sections in Device Constructs" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following examples show the usage of array sections in `map` clauses on `target` and `target` `data` constructs. " + " The following examples show the usage of array sections in `map` clauses on `target` and `target` `data` constructs." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " This example shows the invalid usage of two seperate sections of the same array inside of a `target` construct. " + " This example shows the invalid usage of two seperate sections of the same array inside of a `target` construct." ] }, { @@ -27,7 +27,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_array_sections.1.c " + "%load ../sources/Example_array_sections.1.c" ] }, { @@ -36,14 +36,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_array_sections.1.f90 " + "%load ../sources/Example_array_sections.1.f90" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " This example shows the invalid usage of two separate sections of the same array inside of a `target` construct. " + " This example shows the invalid usage of two separate sections of the same array inside of a `target` construct." ] }, { @@ -52,7 +52,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_array_sections.2.c " + "%load ../sources/Example_array_sections.2.c" ] }, { @@ -61,14 +61,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_array_sections.2.f90 " + "%load ../sources/Example_array_sections.2.f90" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " This example shows the valid usage of two separate sections of the same array inside of a `target` construct. " + " This example shows the valid usage of two separate sections of the same array inside of a `target` construct." ] }, { @@ -77,7 +77,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_array_sections.3.c " + "%load ../sources/Example_array_sections.3.c" ] }, { @@ -86,14 +86,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_array_sections.3.f90 " + "%load ../sources/Example_array_sections.3.f90" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " This example shows the valid usage of a wholly contained array section of an already mapped array section inside of a `target` construct. " + " This example shows the valid usage of a wholly contained array section of an already mapped array section inside of a `target` construct." ] }, { @@ -102,7 +102,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_array_sections.4.c " + "%load ../sources/Example_array_sections.4.c" ] }, { @@ -111,14 +111,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_array_sections.4.f90 " + "%load ../sources/Example_array_sections.4.f90" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---end--- " + "---end---" ] } ], @@ -136,4 +136,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/notebook/Examples_associate.ipynb b/notebook/Examples_associate.ipynb index edb6209..006ed1b 100644 --- a/notebook/Examples_associate.ipynb +++ b/notebook/Examples_associate.ipynb @@ -4,21 +4,21 @@ "cell_type": "markdown", "metadata": {}, "source": [ - " ### Fortran `ASSOCIATE` Construct " + " ### Fortran `ASSOCIATE` Construct" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " fortranspecificstart " + " fortranspecificstart" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following is an invalid example of specifying an associate name on a data-sharing attribute clause. The constraint in the Data Sharing Attribute Rules section in the OpenMP 4.0 API Specifications states that an associate name preserves the association with the selector established at the `ASSOCIATE` statement. The associate name _b_ is associated with the shared variable _a_ . With the predetermined data-sharing attribute rule, the associate name _b_ is not allowed to be specified on the `private` clause. " + " The following is an invalid example of specifying an associate name on a data-sharing attribute clause. The constraint in the Data Sharing Attribute Rules section in the OpenMP 4.0 API Specifications states that an associate name preserves the association with the selector established at the `ASSOCIATE` statement. The associate name _b_ is associated with the shared variable _a_ . With the predetermined data-sharing attribute rule, the associate name _b_ is not allowed to be specified on the `private` clause." ] }, { @@ -27,14 +27,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_associate.1.f " + "%load ../sources/Example_associate.1.f" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " In next example, within the `parallel` construct, the association name _thread_id_ is associated with the private copy of _i_ . The print statement should output the unique thread number. " + " In next example, within the `parallel` construct, the association name _thread_id_ is associated with the private copy of _i_ . The print statement should output the unique thread number." ] }, { @@ -43,14 +43,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_associate.2.f " + "%load ../sources/Example_associate.2.f" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example illustrates the effect of specifying a selector name on a data-sharing attribute clause. The associate name _u_ is associated with _v_ and the variable _v_ is specified on the `private` clause of the `parallel` construct. The construct association is established prior to the `parallel` region. The association between _u_ and the original _v_ is retained (see the Data Sharing Attribute Rules section in the OpenMP 4.0 API Specifications). Inside the `parallel` region, _v_ has the value of -1 and _u_ has the value of the original _v_ . " + " The following example illustrates the effect of specifying a selector name on a data-sharing attribute clause. The associate name _u_ is associated with _v_ and the variable _v_ is specified on the `private` clause of the `parallel` construct. The construct association is established prior to the `parallel` region. The association between _u_ and the original _v_ is retained (see the Data Sharing Attribute Rules section in the OpenMP 4.0 API Specifications). Inside the `parallel` region, _v_ has the value of -1 and _u_ has the value of the original _v_ ." ] }, { @@ -59,21 +59,21 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_ffreenexampleassociate3 " + "%load ../sources/Example_ffreenexampleassociate3" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " fortranspecificend " + " fortranspecificend" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---end--- " + "---end---" ] } ], @@ -91,4 +91,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/notebook/Examples_async_target_depend.ipynb b/notebook/Examples_async_target_depend.ipynb index e154e3d..bad2686 100644 --- a/notebook/Examples_async_target_depend.ipynb +++ b/notebook/Examples_async_target_depend.ipynb @@ -4,35 +4,35 @@ "cell_type": "markdown", "metadata": {}, "source": [ - " ### Asynchronous `target` Execution and Dependences " + " ### Asynchronous `target` Execution and Dependences" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " Asynchronous execution of a `target` region can be accomplished by creating an explicit task around the `target` region. Examples with explicit tasks are shown at the beginning of this section. " + " Asynchronous execution of a `target` region can be accomplished by creating an explicit task around the `target` region. Examples with explicit tasks are shown at the beginning of this section. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " As of OpenMP 4.5 and beyond the `nowait` clause can be used on the `target` directive for asynchronous execution. Examples with `nowait` clauses follow the explicit `task` examples. " + " As of OpenMP 4.5 and beyond the `nowait` clause can be used on the `target` directive for asynchronous execution. Examples with `nowait` clauses follow the explicit `task` examples." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " This section also shows the use of `depend` clauses to order executions through dependences. " + " This section also shows the use of `depend` clauses to order executions through dependences." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---end--- " + "---end---" ] } ], @@ -50,4 +50,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/notebook/Examples_async_target_nowait.ipynb b/notebook/Examples_async_target_nowait.ipynb index 85ba1dd..8ce16db 100644 --- a/notebook/Examples_async_target_nowait.ipynb +++ b/notebook/Examples_async_target_nowait.ipynb @@ -4,35 +4,35 @@ "cell_type": "markdown", "metadata": {}, "source": [ - " #### `nowait` Clause on `target` Construct " + " #### `nowait` Clause on `target` Construct" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example shows how to execute code asynchronously on a device without an explicit task. The `nowait` clause on a `target` construct allows the thread of the _target task_ to perform other work while waiting for the `target` region execution to complete. Hence, the the `target` region can execute asynchronously on the device (without requiring a host thread to idle while waiting for the _target task_ execution to complete). " + " The following example shows how to execute code asynchronously on a device without an explicit task. The `nowait` clause on a `target` construct allows the thread of the _target task_ to perform other work while waiting for the `target` region execution to complete. Hence, the the `target` region can execute asynchronously on the device (without requiring a host thread to idle while waiting for the _target task_ execution to complete)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " In this example the product of two vectors (arrays), _v1_ and _v2_ , is formed. One half of the operations is performed on the device, and the last half on the host, concurrently. " + " In this example the product of two vectors (arrays), _v1_ and _v2_ , is formed. One half of the operations is performed on the device, and the last half on the host, concurrently." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " After a team of threads is formed the master thread generates the _target task_ while the other threads can continue on, without a barrier, to the execution of the host portion of the vector product. The completion of the _target task_ (asynchronous target execution) is guaranteed by the synchronization in the implicit barrier at the end of the host vector-product worksharing loop region. See the `barrier` glossary entry in the OpenMP specification for details. " + " After a team of threads is formed the master thread generates the _target task_ while the other threads can continue on, without a barrier, to the execution of the host portion of the vector product. The completion of the _target task_ (asynchronous target execution) is guaranteed by the synchronization in the implicit barrier at the end of the host vector-product worksharing loop region. See the `barrier` glossary entry in the OpenMP specification for details." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The host loop scheduling is `dynamic` , to balance the host thread executions, since one thread is being used for offload generation. In the situation where little time is spent by the _target task_ in setting up and tearing down the the target execution, `static` scheduling may be desired. " + " The host loop scheduling is `dynamic` , to balance the host thread executions, since one thread is being used for offload generation. In the situation where little time is spent by the _target task_ in setting up and tearing down the the target execution, `static` scheduling may be desired. " ] }, { @@ -41,7 +41,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_async_target.3.c " + "%load ../sources/Example_async_target.3.c" ] }, { @@ -50,14 +50,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_async_target.3.f90 " + "%load ../sources/Example_async_target.3.f90" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---end--- " + "---end---" ] } ], @@ -75,4 +75,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/notebook/Examples_async_target_nowait_depend.ipynb b/notebook/Examples_async_target_nowait_depend.ipynb index edf777b..ecf7cec 100644 --- a/notebook/Examples_async_target_nowait_depend.ipynb +++ b/notebook/Examples_async_target_nowait_depend.ipynb @@ -5,28 +5,28 @@ "metadata": {}, "source": [ " \n", -"begin #### Asynchronous `target` with `nowait` and `depend` Clauses " +"begin #### Asynchronous `target` with `nowait` and `depend` Clauses" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " More details on dependences can be found in , Task Dependences. In this example, there are three flow dependences. In the first two dependences the target task does not execute until the preceding explicit tasks have finished. These dependences are produced by arrays _v1_ and _v2_ with the `out` dependence type in the first two tasks, and the `in` dependence type in the target task. " + " More details on dependences can be found in , Task Dependences. In this example, there are three flow dependences. In the first two dependences the target task does not execute until the preceding explicit tasks have finished. These dependences are produced by arrays _v1_ and _v2_ with the `out` dependence type in the first two tasks, and the `in` dependence type in the target task. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The last dependence is produced by array _p_ with the `out` dependence type in the target task, and the `in` dependence type in the last task. The last task does not execute until the target task finishes. " + " The last dependence is produced by array _p_ with the `out` dependence type in the target task, and the `in` dependence type in the last task. The last task does not execute until the target task finishes. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The `nowait` clause on the `target` construct creates a deferrable _target task_ , allowing the encountering task to continue execution without waiting for the completion of the _target task_ . " + " The `nowait` clause on the `target` construct creates a deferrable _target task_ , allowing the encountering task to continue execution without waiting for the completion of the _target task_ ." ] }, { @@ -35,7 +35,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_async_target.4.c " + "%load ../sources/Example_async_target.4.c" ] }, { @@ -44,7 +44,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_async_target.4.f90 " + "%load ../sources/Example_async_target.4.f90" ] }, { @@ -52,14 +52,14 @@ "metadata": {}, "source": [ " \n", -"end " +"end" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---end--- " + "---end---" ] } ], @@ -77,4 +77,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/notebook/Examples_async_target_with_tasks.ipynb b/notebook/Examples_async_target_with_tasks.ipynb index bd43a1b..f0303fc 100644 --- a/notebook/Examples_async_target_with_tasks.ipynb +++ b/notebook/Examples_async_target_with_tasks.ipynb @@ -4,14 +4,14 @@ "cell_type": "markdown", "metadata": {}, "source": [ - " #### Asynchronous `target` with Tasks " + " #### Asynchronous `target` with Tasks" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example shows how the `task` and `target` constructs are used to execute multiple `target` regions asynchronously. The task that encounters the `task` construct generates an explicit task that contains a `target` region. The thread executing the explicit task encounters a task scheduling point while waiting for the execution of the `target` region to complete, allowing the thread to switch back to the execution of the encountering task or one of the previously generated explicit tasks. " + " The following example shows how the `task` and `target` constructs are used to execute multiple `target` regions asynchronously. The task that encounters the `task` construct generates an explicit task that contains a `target` region. The thread executing the explicit task encounters a task scheduling point while waiting for the execution of the `target` region to complete, allowing the thread to switch back to the execution of the encountering task or one of the previously generated explicit tasks." ] }, { @@ -20,14 +20,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_async_target.1.c " + "%load ../sources/Example_async_target.1.c" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The Fortran version has an interface block that contains the `declare` `target` . An identical statement exists in the function declaration (not shown here). " + " The Fortran version has an interface block that contains the `declare` `target` . An identical statement exists in the function declaration (not shown here)." ] }, { @@ -36,14 +36,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_async_target.1.f90 " + "%load ../sources/Example_async_target.1.f90" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example shows how the `task` and `target` constructs are used to execute multiple `target` regions asynchronously. The task dependence ensures that the storage is allocated and initialized on the device before it is accessed. " + " The following example shows how the `task` and `target` constructs are used to execute multiple `target` regions asynchronously. The task dependence ensures that the storage is allocated and initialized on the device before it is accessed." ] }, { @@ -52,42 +52,42 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_async_target.2.c " + "%load ../sources/Example_async_target.2.c" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The Fortran example below is similar to the C version above. Instead of pointers, though, it uses the convenience of Fortran allocatable arrays on the device. In order to preserve the arrays allocated on the device across multiple `target` regions, a `target` ~ `data` region is used in this case. " + " The Fortran example below is similar to the C version above. Instead of pointers, though, it uses the convenience of Fortran allocatable arrays on the device. In order to preserve the arrays allocated on the device across multiple `target` regions, a `target` ~ `data` region is used in this case." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " If there is no shape specified for an allocatable array in a `map` clause, only the array descriptor (also called a dope vector) is mapped. That is, device space is created for the descriptor, and it is initially populated with host values. In this case, the _v1_ and _v2_ arrays will be in a non-associated state on the device. When space for _v1_ and _v2_ is allocated on the device in the first `target` region the addresses to the space will be included in their descriptors. " + " If there is no shape specified for an allocatable array in a `map` clause, only the array descriptor (also called a dope vector) is mapped. That is, device space is created for the descriptor, and it is initially populated with host values. In this case, the _v1_ and _v2_ arrays will be in a non-associated state on the device. When space for _v1_ and _v2_ is allocated on the device in the first `target` region the addresses to the space will be included in their descriptors." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " At the end of the first `target` region, the arrays _v1_ and _v2_ are preserved on the device for access in the second `target` region. At the end of the second `target` region, the data in array _p_ is copied back, the arrays _v1_ and _v2_ are not. " + " At the end of the first `target` region, the arrays _v1_ and _v2_ are preserved on the device for access in the second `target` region. At the end of the second `target` region, the data in array _p_ is copied back, the arrays _v1_ and _v2_ are not." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " A `depend` clause is used in the `task` directive to provide a wait at the beginning of the second `target` region, to insure that there is no race condition with _v1_ and _v2_ in the two tasks. It would be noncompliant to use _v1_ and/or _v2_ in lieu of _N_ in the `depend` clauses, because the use of non-allocated allocatable arrays as list items in a `depend` clause would lead to unspecified behavior. " + " A `depend` clause is used in the `task` directive to provide a wait at the beginning of the second `target` region, to insure that there is no race condition with _v1_ and _v2_ in the two tasks. It would be noncompliant to use _v1_ and/or _v2_ in lieu of _N_ in the `depend` clauses, because the use of non-allocated allocatable arrays as list items in a `depend` clause would lead to unspecified behavior. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " noteheader{--} This example is not strictly compliant with the OpenMP 4.5 specification since the allocation status of allocatable arrays _v1_ and _v2_ is changed inside the `target` region, which is not allowed. (See the restrictions for the `map` clause in the _Data-mapping Attribute Rules and Clauses_ section of the specification.) However, the intention is to relax the restrictions on mapping of allocatable variables in the next release of the specification so that the example will be compliant. " + " noteheader{--} This example is not strictly compliant with the OpenMP 4.5 specification since the allocation status of allocatable arrays _v1_ and _v2_ is changed inside the `target` region, which is not allowed. (See the restrictions for the `map` clause in the _Data-mapping Attribute Rules and Clauses_ section of the specification.) However, the intention is to relax the restrictions on mapping of allocatable variables in the next release of the specification so that the example will be compliant." ] }, { @@ -96,14 +96,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_async_target.2.f90 " + "%load ../sources/Example_async_target.2.f90" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---end--- " + "---end---" ] } ], @@ -121,4 +121,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/notebook/Examples_atomic.ipynb b/notebook/Examples_atomic.ipynb index 9bdccbf..b252e0e 100644 --- a/notebook/Examples_atomic.ipynb +++ b/notebook/Examples_atomic.ipynb @@ -4,28 +4,28 @@ "cell_type": "markdown", "metadata": {}, "source": [ - " ### The `atomic` Construct " + " ### The `atomic` Construct" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example avoids race conditions (simultaneous updates of an element of _x_ by multiple threads) by using the `atomic` construct . " + " The following example avoids race conditions (simultaneous updates of an element of _x_ by multiple threads) by using the `atomic` construct ." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The advantage of using the `atomic` construct in this example is that it allows updates of two different elements of _x_ to occur in parallel. If a `critical` construct were used instead, then all updates to elements of _x_ would be executed serially (though not in any guaranteed order). " + " The advantage of using the `atomic` construct in this example is that it allows updates of two different elements of _x_ to occur in parallel. If a `critical` construct were used instead, then all updates to elements of _x_ would be executed serially (though not in any guaranteed order)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " Note that the `atomic` directive applies only to the statement immediately following it. As a result, elements of _y_ are not updated atomically in this example. " + " Note that the `atomic` directive applies only to the statement immediately following it. As a result, elements of _y_ are not updated atomically in this example." ] }, { @@ -34,7 +34,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_atomic.1.c " + "%load ../sources/Example_atomic.1.c" ] }, { @@ -43,14 +43,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_atomic.1.f " + "%load ../sources/Example_atomic.1.f" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example illustrates the `read` and `write` clauses for the `atomic` directive. These clauses ensure that the given variable is read or written, respectively, as a whole. Otherwise, some other thread might read or write part of the variable while the current thread was reading or writing another part of the variable. Note that most hardware provides atomic reads and writes for some set of properly aligned variables of specific sizes, but not necessarily for all the variable types supported by the OpenMP API. " + " The following example illustrates the `read` and `write` clauses for the `atomic` directive. These clauses ensure that the given variable is read or written, respectively, as a whole. Otherwise, some other thread might read or write part of the variable while the current thread was reading or writing another part of the variable. Note that most hardware provides atomic reads and writes for some set of properly aligned variables of specific sizes, but not necessarily for all the variable types supported by the OpenMP API." ] }, { @@ -59,7 +59,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_atomic.2.c " + "%load ../sources/Example_atomic.2.c" ] }, { @@ -68,14 +68,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_atomic.2.f " + "%load ../sources/Example_atomic.2.f" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example illustrates the `capture` clause for the `atomic` directive. In this case the value of a variable is captured, and then the variable is incremented. These operations occur atomically. This particular example could be implemented using the fetch-and-add instruction available on many kinds of hardware. The example also shows a way to implement a spin lock using the `capture` and `read` clauses. " + " The following example illustrates the `capture` clause for the `atomic` directive. In this case the value of a variable is captured, and then the variable is incremented. These operations occur atomically. This particular example could be implemented using the fetch-and-add instruction available on many kinds of hardware. The example also shows a way to implement a spin lock using the `capture` and `read` clauses." ] }, { @@ -84,7 +84,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_atomic.3.c " + "%load ../sources/Example_atomic.3.c" ] }, { @@ -93,14 +93,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_atomic.3.f " + "%load ../sources/Example_atomic.3.f" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---end--- " + "---end---" ] } ], @@ -118,4 +118,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/notebook/Examples_atomic_restrict.ipynb b/notebook/Examples_atomic_restrict.ipynb index df3bfd2..5b15dd5 100644 --- a/notebook/Examples_atomic_restrict.ipynb +++ b/notebook/Examples_atomic_restrict.ipynb @@ -4,14 +4,14 @@ "cell_type": "markdown", "metadata": {}, "source": [ - " ### Restrictions on the `atomic` Construct " + " ### Restrictions on the `atomic` Construct" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following non-conforming examples illustrate the restrictions on the `atomic` construct. " + " The following non-conforming examples illustrate the restrictions on the `atomic` construct. " ] }, { @@ -20,7 +20,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_atomic_restrict.1.c " + "%load ../sources/Example_atomic_restrict.1.c" ] }, { @@ -29,7 +29,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_atomic_restrict.1.f " + "%load ../sources/Example_atomic_restrict.1.f" ] }, { @@ -38,14 +38,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_atomic_restrict.2.c " + "%load ../sources/Example_atomic_restrict.2.c" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " fortranspecificstart The following example is non-conforming because `I` and `R` reference the same location but have different types. " + " fortranspecificstart The following example is non-conforming because `I` and `R` reference the same location but have different types." ] }, { @@ -54,14 +54,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_atomic_restrict.2.f " + "%load ../sources/Example_atomic_restrict.2.f" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " Although the following example might work on some implementations, this is also non-conforming: " + " Although the following example might work on some implementations, this is also non-conforming:" ] }, { @@ -70,21 +70,21 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_atomic_restrict.3.f " + "%load ../sources/Example_atomic_restrict.3.f" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " fortranspecificend " + " fortranspecificend" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---end--- " + "---end---" ] } ], @@ -102,4 +102,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/notebook/Examples_barrier_regions.ipynb b/notebook/Examples_barrier_regions.ipynb index edd0364..721ac64 100644 --- a/notebook/Examples_barrier_regions.ipynb +++ b/notebook/Examples_barrier_regions.ipynb @@ -4,28 +4,28 @@ "cell_type": "markdown", "metadata": {}, "source": [ - " ### Binding of `barrier` Regions " + " ### Binding of `barrier` Regions" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The binding rules call for a `barrier` region to bind to the closest enclosing `parallel` region. " + " The binding rules call for a `barrier` region to bind to the closest enclosing `parallel` region. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " In the following example, the call from the main program to _sub2_ is conforming because the `barrier` region (in _sub3_ ) binds to the `parallel` region in _sub2_ . The call from the main program to _sub1_ is conforming because the `barrier` region binds to the `parallel` region in subroutine _sub2_ . " + " In the following example, the call from the main program to _sub2_ is conforming because the `barrier` region (in _sub3_ ) binds to the `parallel` region in _sub2_ . The call from the main program to _sub1_ is conforming because the `barrier` region binds to the `parallel` region in subroutine _sub2_ ." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The call from the main program to _sub3_ is conforming because the `barrier` region binds to the implicit inactive `parallel` region enclosing the sequential part. Also note that the `barrier` region in _sub3_ when called from _sub2_ only synchronizes the team of threads in the enclosing `parallel` region and not all the threads created in _sub1_ . " + " The call from the main program to _sub3_ is conforming because the `barrier` region binds to the implicit inactive `parallel` region enclosing the sequential part. Also note that the `barrier` region in _sub3_ when called from _sub2_ only synchronizes the team of threads in the enclosing `parallel` region and not all the threads created in _sub1_ ." ] }, { @@ -34,7 +34,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_barrier_regions.1.c " + "%load ../sources/Example_barrier_regions.1.c" ] }, { @@ -43,14 +43,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_barrier_regions.1.f " + "%load ../sources/Example_barrier_regions.1.f" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---end--- " + "---end---" ] } ], @@ -68,4 +68,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/notebook/Examples_cancellation.ipynb b/notebook/Examples_cancellation.ipynb index 2e3a4dd..fdf781e 100644 --- a/notebook/Examples_cancellation.ipynb +++ b/notebook/Examples_cancellation.ipynb @@ -4,14 +4,14 @@ "cell_type": "markdown", "metadata": {}, "source": [ - " ### Cancellation Constructs " + " ### Cancellation Constructs" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example shows how the `cancel` directive can be used to terminate an OpenMP region. Although the `cancel` construct terminates the OpenMP worksharing region, programmers must still track the exception through the pointer ex and issue a cancellation for the `parallel` region if an exception has been raised. The master thread checks the exception pointer to make sure that the exception is properly handled in the sequential part. If cancellation of the `parallel` region has been requested, some threads might have executed `phase_1()` . However, it is guaranteed that none of the threads executed `phase_2()` . " + " The following example shows how the `cancel` directive can be used to terminate an OpenMP region. Although the `cancel` construct terminates the OpenMP worksharing region, programmers must still track the exception through the pointer ex and issue a cancellation for the `parallel` region if an exception has been raised. The master thread checks the exception pointer to make sure that the exception is properly handled in the sequential part. If cancellation of the `parallel` region has been requested, some threads might have executed `phase_1()` . However, it is guaranteed that none of the threads executed `phase_2()` ." ] }, { @@ -20,14 +20,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_cancellation.1.cpp " + "%load ../sources/Example_cancellation.1.cpp" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example illustrates the use of the `cancel` construct in error handling. If there is an error condition from the `allocate` statement, the cancellation is activated. The encountering thread sets the shared variable `err` and other threads of the binding thread set proceed to the end of the worksharing construct after the cancellation has been activated. " + " The following example illustrates the use of the `cancel` construct in error handling. If there is an error condition from the `allocate` statement, the cancellation is activated. The encountering thread sets the shared variable `err` and other threads of the binding thread set proceed to the end of the worksharing construct after the cancellation has been activated. " ] }, { @@ -36,14 +36,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_cancellation.1.f90 " + "%load ../sources/Example_cancellation.1.f90" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example shows how to cancel a parallel search on a binary tree as soon as the search value has been detected. The code creates a task to descend into the child nodes of the current tree node. If the search value has been found, the code remembers the tree node with the found value through an `atomic` write to the result variable and then cancels execution of all search tasks. The function `search_tree_parallel` groups all search tasks into a single task group to control the effect of the `cancel taskgroup` directive. The _level_ argument is used to create undeferred tasks after the first ten levels of the tree. " + " The following example shows how to cancel a parallel search on a binary tree as soon as the search value has been detected. The code creates a task to descend into the child nodes of the current tree node. If the search value has been found, the code remembers the tree node with the found value through an `atomic` write to the result variable and then cancels execution of all search tasks. The function `search_tree_parallel` groups all search tasks into a single task group to control the effect of the `cancel taskgroup` directive. The _level_ argument is used to create undeferred tasks after the first ten levels of the tree." ] }, { @@ -52,14 +52,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_cancellation.2.c " + "%load ../sources/Example_cancellation.2.c" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following is the equivalent parallel search example in Fortran. " + " The following is the equivalent parallel search example in Fortran." ] }, { @@ -68,14 +68,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_cancellation.2.f90 " + "%load ../sources/Example_cancellation.2.f90" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---end--- " + "---end---" ] } ], @@ -93,4 +93,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/notebook/Examples_carrays_fpriv.ipynb b/notebook/Examples_carrays_fpriv.ipynb index 9422073..b6e9fc0 100644 --- a/notebook/Examples_carrays_fpriv.ipynb +++ b/notebook/Examples_carrays_fpriv.ipynb @@ -4,28 +4,28 @@ "cell_type": "markdown", "metadata": {}, "source": [ - " ### C/C++ Arrays in a `firstprivate` Clause " + " ### C/C++ Arrays in a `firstprivate` Clause" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " ccppspecificstart " + " ccppspecificstart" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example illustrates the size and value of list items of array or pointer type in a `firstprivate` clause . The size of new list items is based on the type of the corresponding original list item, as determined by the base language. " + " The following example illustrates the size and value of list items of array or pointer type in a `firstprivate` clause . The size of new list items is based on the type of the corresponding original list item, as determined by the base language." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " In this example: " + " In this example:" ] }, { @@ -33,7 +33,7 @@ "metadata": {}, "source": [ " \n", -"* The type of `A` is array of two arrays of two ints. " +"* The type of `A` is array of two arrays of two ints." ] }, { @@ -41,7 +41,7 @@ "metadata": {}, "source": [ " \n", -"* The type of `B` is adjusted to pointer to array of `n` ints, because it is a function parameter. " +"* The type of `B` is adjusted to pointer to array of `n` ints, because it is a function parameter." ] }, { @@ -49,7 +49,7 @@ "metadata": {}, "source": [ " \n", -"* The type of `C` is adjusted to pointer to int, because it is a function parameter. " +"* The type of `C` is adjusted to pointer to int, because it is a function parameter." ] }, { @@ -57,7 +57,7 @@ "metadata": {}, "source": [ " \n", -"* The type of `D` is array of two arrays of two ints. " +"* The type of `D` is array of two arrays of two ints." ] }, { @@ -65,14 +65,14 @@ "metadata": {}, "source": [ " \n", -"* The type of `E` is array of `n` arrays of `n` ints. " +"* The type of `E` is array of `n` arrays of `n` ints. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " Note that `B` and `E` involve variable length array types. " + " Note that `B` and `E` involve variable length array types." ] }, { @@ -80,7 +80,7 @@ "metadata": {}, "source": [ " The new items of array type are initialized as if each integer element of the original array is assigned to the corresponding element of the new array. Those of pointer type are initialized as if by assignment from the original \n", -"* to the new item. " +"* to the new item." ] }, { @@ -89,21 +89,21 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_carrays_fpriv.1.c " + "%load ../sources/Example_carrays_fpriv.1.c" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " ccppspecificend " + " ccppspecificend" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---end--- " + "---end---" ] } ], @@ -121,4 +121,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/notebook/Examples_collapse.ipynb b/notebook/Examples_collapse.ipynb index 6d142f6..1a93c70 100644 --- a/notebook/Examples_collapse.ipynb +++ b/notebook/Examples_collapse.ipynb @@ -4,21 +4,21 @@ "cell_type": "markdown", "metadata": {}, "source": [ - " ### The `collapse` Clause " + " ### The `collapse` Clause" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " In the following example, the `k` and `j` loops are associated with the loop construct. So the iterations of the `k` and `j` loops are collapsed into one loop with a larger iteration space, and that loop is then divided among the threads in the current team. Since the `i` loop is not associated with the loop construct, it is not collapsed, and the `i` loop is executed sequentially in its entirety in every iteration of the collapsed `k` and `j` loop. " + " In the following example, the `k` and `j` loops are associated with the loop construct. So the iterations of the `k` and `j` loops are collapsed into one loop with a larger iteration space, and that loop is then divided among the threads in the current team. Since the `i` loop is not associated with the loop construct, it is not collapsed, and the `i` loop is executed sequentially in its entirety in every iteration of the collapsed `k` and `j` loop. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The variable `j` can be omitted from the `private` clause when the `collapse` clause is used since it is implicitly private. However, if the `collapse` clause is omitted then `j` will be shared if it is omitted from the `private` clause. In either case, `k` is implicitly private and could be omitted from the `private` clause. " + " The variable `j` can be omitted from the `private` clause when the `collapse` clause is used since it is implicitly private. However, if the `collapse` clause is omitted then `j` will be shared if it is omitted from the `private` clause. In either case, `k` is implicitly private and could be omitted from the `private` clause." ] }, { @@ -27,7 +27,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_collapse.1.c " + "%load ../sources/Example_collapse.1.c" ] }, { @@ -36,21 +36,21 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_collapse.1.f " + "%load ../sources/Example_collapse.1.f" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " In the next example, the `k` and `j` loops are associated with the loop construct. So the iterations of the `k` and `j` loops are collapsed into one loop with a larger iteration space, and that loop is then divided among the threads in the current team. " + " In the next example, the `k` and `j` loops are associated with the loop construct. So the iterations of the `k` and `j` loops are collapsed into one loop with a larger iteration space, and that loop is then divided among the threads in the current team." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The sequential execution of the iterations in the `k` and `j` loops determines the order of the iterations in the collapsed iteration space. This implies that in the sequentially last iteration of the collapsed iteration space, `k` will have the value `2` and `j` will have the value `3` . Since `klast` and `jlast` are `lastprivate` , their values are assigned by the sequentially last iteration of the collapsed `k` and `j` loop. This example prints: `2 3` . " + " The sequential execution of the iterations in the `k` and `j` loops determines the order of the iterations in the collapsed iteration space. This implies that in the sequentially last iteration of the collapsed iteration space, `k` will have the value `2` and `j` will have the value `3` . Since `klast` and `jlast` are `lastprivate` , their values are assigned by the sequentially last iteration of the collapsed `k` and `j` loop. This example prints: `2 3` ." ] }, { @@ -59,7 +59,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_collapse.2.c " + "%load ../sources/Example_collapse.2.c" ] }, { @@ -68,42 +68,42 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_collapse.2.f " + "%load ../sources/Example_collapse.2.f" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The next example illustrates the interaction of the `collapse` and `ordered` clauses. " + " The next example illustrates the interaction of the `collapse` and `ordered` clauses." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " In the example, the loop construct has both a `collapse` clause and an `ordered` clause. The `collapse` clause causes the iterations of the `k` and `j` loops to be collapsed into one loop with a larger iteration space, and that loop is divided among the threads in the current team. An `ordered` clause is added to the loop construct, because an ordered region binds to the loop region arising from the loop construct. " + " In the example, the loop construct has both a `collapse` clause and an `ordered` clause. The `collapse` clause causes the iterations of the `k` and `j` loops to be collapsed into one loop with a larger iteration space, and that loop is divided among the threads in the current team. An `ordered` clause is added to the loop construct, because an ordered region binds to the loop region arising from the loop construct." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " According to Section 2.12.8 of the OpenMP 4.0 specification, a thread must not execute more than one ordered region that binds to the same loop region. So the `collapse` clause is required for the example to be conforming. With the `collapse` clause, the iterations of the `k` and `j` loops are collapsed into one loop, and therefore only one ordered region will bind to the collapsed `k` and `j` loop. Without the `collapse` clause, there would be two ordered regions that bind to each iteration of the `k` loop (one arising from the first iteration of the `j` loop, and the other arising from the second iteration of the `j` loop). " + " According to Section 2.12.8 of the OpenMP 4.0 specification, a thread must not execute more than one ordered region that binds to the same loop region. So the `collapse` clause is required for the example to be conforming. With the `collapse` clause, the iterations of the `k` and `j` loops are collapsed into one loop, and therefore only one ordered region will bind to the collapsed `k` and `j` loop. Without the `collapse` clause, there would be two ordered regions that bind to each iteration of the `k` loop (one arising from the first iteration of the `j` loop, and the other arising from the second iteration of the `j` loop)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The code prints " + " The code prints" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " `0 1 1` `0 1 2` `0 2 1` `1 2 2` `1 3 1` `1 3 2` " + " `0 1 1` `0 1 2` `0 2 1` `1 2 2` `1 3 1` `1 3 2` " ] }, { @@ -112,7 +112,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_collapse.3.c " + "%load ../sources/Example_collapse.3.c" ] }, { @@ -121,14 +121,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_collapse.3.f " + "%load ../sources/Example_collapse.3.f" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---end--- " + "---end---" ] } ], @@ -146,4 +146,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/notebook/Examples_cond_comp.ipynb b/notebook/Examples_cond_comp.ipynb index b3ba559..8bb4087 100644 --- a/notebook/Examples_cond_comp.ipynb +++ b/notebook/Examples_cond_comp.ipynb @@ -4,14 +4,14 @@ "cell_type": "markdown", "metadata": {}, "source": [ - " ### Conditional Compilation " + " ### Conditional Compilation" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " ccppspecificstart The following example illustrates the use of conditional compilation using the OpenMP macro `_OPENMP` . With OpenMP compilation, the `_OPENMP` macro becomes defined. " + " ccppspecificstart The following example illustrates the use of conditional compilation using the OpenMP macro `_OPENMP` . With OpenMP compilation, the `_OPENMP` macro becomes defined." ] }, { @@ -20,21 +20,21 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_cond_comp.1.c " + "%load ../sources/Example_cond_comp.1.c" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " ccppspecificend " + " ccppspecificend" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " fortranspecificstart The following example illustrates the use of the conditional compilation sentinel. With OpenMP compilation, the conditional compilation sentinel `!$` is recognized and treated as two spaces. In fixed form source, statements guarded by the sentinel must start after column 6. " + " fortranspecificstart The following example illustrates the use of the conditional compilation sentinel. With OpenMP compilation, the conditional compilation sentinel `!$` is recognized and treated as two spaces. In fixed form source, statements guarded by the sentinel must start after column 6." ] }, { @@ -43,21 +43,21 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_cond_comp.1.f " + "%load ../sources/Example_cond_comp.1.f" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " fortranspecificend " + " fortranspecificend" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---end--- " + "---end---" ] } ], @@ -75,4 +75,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/notebook/Examples_copyin.ipynb b/notebook/Examples_copyin.ipynb index cc7d288..04c740b 100644 --- a/notebook/Examples_copyin.ipynb +++ b/notebook/Examples_copyin.ipynb @@ -4,14 +4,14 @@ "cell_type": "markdown", "metadata": {}, "source": [ - " ### The `copyin` Clause " + " ### The `copyin` Clause" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The `copyin` clause is used to initialize threadprivate data upon entry to a `parallel` region. The value of the threadprivate variable in the master thread is copied to the threadprivate variable of each other team member. " + " The `copyin` clause is used to initialize threadprivate data upon entry to a `parallel` region. The value of the threadprivate variable in the master thread is copied to the threadprivate variable of each other team member." ] }, { @@ -20,7 +20,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_copyin.1.c " + "%load ../sources/Example_copyin.1.c" ] }, { @@ -29,14 +29,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_copyin.1.f " + "%load ../sources/Example_copyin.1.f" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---end--- " + "---end---" ] } ], @@ -54,4 +54,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/notebook/Examples_copyprivate.ipynb b/notebook/Examples_copyprivate.ipynb index f109074..e9e36ea 100644 --- a/notebook/Examples_copyprivate.ipynb +++ b/notebook/Examples_copyprivate.ipynb @@ -4,21 +4,21 @@ "cell_type": "markdown", "metadata": {}, "source": [ - " ### The `copyprivate` Clause " + " ### The `copyprivate` Clause" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The `copyprivate` clause can be used to broadcast values acquired by a single thread directly to all instances of the private variables in the other threads. In this example, if the routine is called from the sequential part, its behavior is not affected by the presence of the directives. If it is called from a `parallel` region, then the actual arguments with which `a` and `b` are associated must be private. " + " The `copyprivate` clause can be used to broadcast values acquired by a single thread directly to all instances of the private variables in the other threads. In this example, if the routine is called from the sequential part, its behavior is not affected by the presence of the directives. If it is called from a `parallel` region, then the actual arguments with which `a` and `b` are associated must be private. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The thread that executes the structured block associated with the `single` construct broadcasts the values of the private variables `a` , `b` , `x` , and `y` from its implicit task's data environment to the data environments of the other implicit tasks in the thread team. The broadcast completes before any of the threads have left the barrier at the end of the construct. " + " The thread that executes the structured block associated with the `single` construct broadcasts the values of the private variables `a` , `b` , `x` , and `y` from its implicit task's data environment to the data environments of the other implicit tasks in the thread team. The broadcast completes before any of the threads have left the barrier at the end of the construct." ] }, { @@ -27,7 +27,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_copyprivate.1.c " + "%load ../sources/Example_copyprivate.1.c" ] }, { @@ -36,14 +36,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_copyprivate.1.f " + "%load ../sources/Example_copyprivate.1.f" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " In this example, assume that the input must be performed by the master thread. Since the `master` construct does not support the `copyprivate` clause, it cannot broadcast the input value that is read. However, `copyprivate` is used to broadcast an address where the input value is stored. " + " In this example, assume that the input must be performed by the master thread. Since the `master` construct does not support the `copyprivate` clause, it cannot broadcast the input value that is read. However, `copyprivate` is used to broadcast an address where the input value is stored." ] }, { @@ -52,7 +52,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_copyprivate.2.c " + "%load ../sources/Example_copyprivate.2.c" ] }, { @@ -61,14 +61,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_copyprivate.2.f " + "%load ../sources/Example_copyprivate.2.f" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " Suppose that the number of lock variables required within a `parallel` region cannot easily be determined prior to entering it. The `copyprivate` clause can be used to provide access to shared lock variables that are allocated within that `parallel` region. " + " Suppose that the number of lock variables required within a `parallel` region cannot easily be determined prior to entering it. The `copyprivate` clause can be used to provide access to shared lock variables that are allocated within that `parallel` region." ] }, { @@ -77,21 +77,21 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_copyprivate.3.c " + "%load ../sources/Example_copyprivate.3.c" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " fortranspecificstartfnexample{copyprivate}{3} " + " fortranspecificstartfnexample{copyprivate}{3}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " Note that the effect of the `copyprivate` clause on a variable with the `allocatable` attribute is different than on a variable with the `pointer` attribute. The value of `A` is copied (as if by intrinsic assignment) and the pointer `B` is copied (as if by pointer assignment) to the corresponding list items in the other implicit tasks belonging to the `parallel` region. " + " Note that the effect of the `copyprivate` clause on a variable with the `allocatable` attribute is different than on a variable with the `pointer` attribute. The value of `A` is copied (as if by intrinsic assignment) and the pointer `B` is copied (as if by pointer assignment) to the corresponding list items in the other implicit tasks belonging to the `parallel` region. " ] }, { @@ -100,21 +100,21 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_copyprivate.4.f " + "%load ../sources/Example_copyprivate.4.f" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " fortranspecificend " + " fortranspecificend" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---end--- " + "---end---" ] } ], @@ -132,4 +132,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/notebook/Examples_cpp_reference.ipynb b/notebook/Examples_cpp_reference.ipynb index edad052..b15f073 100644 --- a/notebook/Examples_cpp_reference.ipynb +++ b/notebook/Examples_cpp_reference.ipynb @@ -4,7 +4,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - " ### C++ Reference in Data-Sharing Clauses " + " ### C++ Reference in Data-Sharing Clauses" ] }, { @@ -13,14 +13,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_cppspecificstart " + "%load ../sources/Example_cppspecificstart" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " C++ reference types are allowed in data-sharing attribute clauses as of OpenMP 4.5, except for the `threadprivate` , `copyin` and `copyprivate` clauses. (See the Data-Sharing Attribute Clauses Section of the 4.5 OpenMP specification.) When a variable with C++ reference type is privatized, the object the reference refers to is privatized in addition to the reference itself. The following example shows the use of reference types in data-sharing clauses in the usual way. Additionally it shows how the data-sharing of formal arguments with a C++ reference type on an orphaned task generating construct is determined implicitly. (See the Data-sharing Attribute Rules for Variables Referenced in a Construct Section of the 4.5 OpenMP specification.) " + " C++ reference types are allowed in data-sharing attribute clauses as of OpenMP 4.5, except for the `threadprivate` , `copyin` and `copyprivate` clauses. (See the Data-Sharing Attribute Clauses Section of the 4.5 OpenMP specification.) When a variable with C++ reference type is privatized, the object the reference refers to is privatized in addition to the reference itself. The following example shows the use of reference types in data-sharing clauses in the usual way. Additionally it shows how the data-sharing of formal arguments with a C++ reference type on an orphaned task generating construct is determined implicitly. (See the Data-sharing Attribute Rules for Variables Referenced in a Construct Section of the 4.5 OpenMP specification.)" ] }, { @@ -29,7 +29,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_cppnexamplecpp_reference1 " + "%load ../sources/Example_cppnexamplecpp_reference1" ] }, { @@ -38,14 +38,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_cppspecificend " + "%load ../sources/Example_cppspecificend" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---end--- " + "---end---" ] } ], @@ -63,4 +63,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/notebook/Examples_critical.ipynb b/notebook/Examples_critical.ipynb index 02c30d3..cc352e4 100644 --- a/notebook/Examples_critical.ipynb +++ b/notebook/Examples_critical.ipynb @@ -4,14 +4,14 @@ "cell_type": "markdown", "metadata": {}, "source": [ - " ### The `critical` Construct " + " ### The `critical` Construct" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example includes several `critical` constructs. The example illustrates a queuing model in which a task is dequeued and worked on. To guard against multiple threads dequeuing the same task, the dequeuing operation must be in a `critical` region. Because the two queues in this example are independent, they are protected by `critical` constructs with different names, _xaxis_ and _yaxis_ . " + " The following example includes several `critical` constructs. The example illustrates a queuing model in which a task is dequeued and worked on. To guard against multiple threads dequeuing the same task, the dequeuing operation must be in a `critical` region. Because the two queues in this example are independent, they are protected by `critical` constructs with different names, _xaxis_ and _yaxis_ ." ] }, { @@ -20,7 +20,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_critical.1.c " + "%load ../sources/Example_critical.1.c" ] }, { @@ -29,14 +29,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_critical.1.f " + "%load ../sources/Example_critical.1.f" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example extends the previous example by adding the `hint` clause to the `critical` constructs. " + " The following example extends the previous example by adding the `hint` clause to the `critical` constructs." ] }, { @@ -45,7 +45,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_critical.2.c " + "%load ../sources/Example_critical.2.c" ] }, { @@ -54,14 +54,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_critical.2.f " + "%load ../sources/Example_critical.2.f" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---end--- " + "---end---" ] } ], @@ -79,4 +79,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/notebook/Examples_declare_target.ipynb b/notebook/Examples_declare_target.ipynb index 2a7dce7..3129697 100644 --- a/notebook/Examples_declare_target.ipynb +++ b/notebook/Examples_declare_target.ipynb @@ -4,35 +4,35 @@ "cell_type": "markdown", "metadata": {}, "source": [ - " ### `declare` `target` Construct " + " ### `declare` `target` Construct" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " #### `declare` `target` and `end` `declare` `target` for a Function " + " #### `declare` `target` and `end` `declare` `target` for a Function" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example shows how the `declare` `target` directive is used to indicate that the corresponding call inside a `target` region is to a `fib` function that can execute on the default target device. " + " The following example shows how the `declare` `target` directive is used to indicate that the corresponding call inside a `target` region is to a `fib` function that can execute on the default target device." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " A version of the function is also available on the host device. When the `if` clause conditional expression on the `target` construct evaluates to _false_ , the `target` region (thus `fib` ) will execute on the host device. " + " A version of the function is also available on the host device. When the `if` clause conditional expression on the `target` construct evaluates to _false_ , the `target` region (thus `fib` ) will execute on the host device." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " For C/C++ codes the declaration of the function `fib` appears between the `declare` `target` and `end` `declare` `target` directives. " + " For C/C++ codes the declaration of the function `fib` appears between the `declare` `target` and `end` `declare` `target` directives." ] }, { @@ -41,21 +41,21 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_declare_target.1.c " + "%load ../sources/Example_declare_target.1.c" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The Fortran `fib` subroutine contains a `declare` `target` declaration to indicate to the compiler to create an device executable version of the procedure. The subroutine name has not been included on the `declare` `target` directive and is, therefore, implicitly assumed. " + " The Fortran `fib` subroutine contains a `declare` `target` declaration to indicate to the compiler to create an device executable version of the procedure. The subroutine name has not been included on the `declare` `target` directive and is, therefore, implicitly assumed." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The program uses the `module_fib` module, which presents an explicit interface to the compiler with the `declare` `target` declarations for processing the `fib` call. " + " The program uses the `module_fib` module, which presents an explicit interface to the compiler with the `declare` `target` declarations for processing the `fib` call." ] }, { @@ -64,14 +64,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_declare_target.1.f90 " + "%load ../sources/Example_declare_target.1.f90" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The next Fortran example shows the use of an external subroutine. Without an explicit interface (through module use or an interface block) the `declare` `target` declarations within a external subroutine are unknown to the main program unit; therefore, a `declare` `target` must be provided within the program scope for the compiler to determine that a target binary should be available. " + " The next Fortran example shows the use of an external subroutine. Without an explicit interface (through module use or an interface block) the `declare` `target` declarations within a external subroutine are unknown to the main program unit; therefore, a `declare` `target` must be provided within the program scope for the compiler to determine that a target binary should be available." ] }, { @@ -80,14 +80,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_declare_target.2.f90 " + "%load ../sources/Example_declare_target.2.f90" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " #### `declare` `target` Construct for Class Type " + " #### `declare` `target` Construct for Class Type" ] }, { @@ -96,14 +96,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_cppspecificstart " + "%load ../sources/Example_cppspecificstart" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example shows how the `declare` `target` and `end` `declare` `target` directives are used to enclose the declaration of a variable _varY_ with a class type `typeY` . The member function `typeY::foo()` cannot be accessed on a target device because its declaration did not appear between `declare` `target` and `end` `declare` `target` directives. " + " The following example shows how the `declare` `target` and `end` `declare` `target` directives are used to enclose the declaration of a variable _varY_ with a class type `typeY` . The member function `typeY::foo()` cannot be accessed on a target device because its declaration did not appear between `declare` `target` and `end` `declare` `target` directives." ] }, { @@ -112,7 +112,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_cppnexampledeclare_target2 " + "%load ../sources/Example_cppnexampledeclare_target2" ] }, { @@ -121,28 +121,28 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_cppspecificend " + "%load ../sources/Example_cppspecificend" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " #### `declare` `target` and `end` `declare` `target` for Variables " + " #### `declare` `target` and `end` `declare` `target` for Variables" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following examples show how the `declare` `target` and `end` `declare` `target` directives are used to indicate that global variables are mapped to the implicit device data environment of each target device. " + " The following examples show how the `declare` `target` and `end` `declare` `target` directives are used to indicate that global variables are mapped to the implicit device data environment of each target device." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " In the following example, the declarations of the variables _p_ , _v1_ , and _v2_ appear between `declare` `target` and `end` `declare` `target` directives indicating that the variables are mapped to the implicit device data environment of each target device. The `target` `update` directive is then used to manage the consistency of the variables _p_ , _v1_ , and _v2_ between the data environment of the encountering host device task and the implicit device data environment of the default target device. " + " In the following example, the declarations of the variables _p_ , _v1_ , and _v2_ appear between `declare` `target` and `end` `declare` `target` directives indicating that the variables are mapped to the implicit device data environment of each target device. The `target` `update` directive is then used to manage the consistency of the variables _p_ , _v1_ , and _v2_ between the data environment of the encountering host device task and the implicit device data environment of the default target device." ] }, { @@ -151,14 +151,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_declare_target.3.c " + "%load ../sources/Example_declare_target.3.c" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The Fortran version of the above C code uses a different syntax. Fortran modules use a list syntax on the `declare` `target` directive to declare mapped variables. " + " The Fortran version of the above C code uses a different syntax. Fortran modules use a list syntax on the `declare` `target` directive to declare mapped variables." ] }, { @@ -167,21 +167,21 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_declare_target.3.f90 " + "%load ../sources/Example_declare_target.3.f90" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example also indicates that the function `Pfun()` is available on the target device, as well as the variable _Q_ , which is mapped to the implicit device data environment of each target device. The `target` `update` directive is then used to manage the consistency of the variable _Q_ between the data environment of the encountering host device task and the implicit device data environment of the default target device. " + " The following example also indicates that the function `Pfun()` is available on the target device, as well as the variable _Q_ , which is mapped to the implicit device data environment of each target device. The `target` `update` directive is then used to manage the consistency of the variable _Q_ between the data environment of the encountering host device task and the implicit device data environment of the default target device." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " In the following example, the function and variable declarations appear between the `declare` `target` and `end` `declare` `target` directives. " + " In the following example, the function and variable declarations appear between the `declare` `target` and `end` `declare` `target` directives." ] }, { @@ -190,14 +190,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_declare_target.4.c " + "%load ../sources/Example_declare_target.4.c" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The Fortran version of the above C code uses a different syntax. In Fortran modules a list syntax on the `declare` `target` directive is used to declare mapped variables and procedures. The _N_ and _Q_ variables are declared as a comma separated list. When the `declare` `target` directive is used to declare just the procedure, the procedure name need not be listed -- it is implicitly assumed, as illustrated in the `Pfun()` function. " + " The Fortran version of the above C code uses a different syntax. In Fortran modules a list syntax on the `declare` `target` directive is used to declare mapped variables and procedures. The _N_ and _Q_ variables are declared as a comma separated list. When the `declare` `target` directive is used to declare just the procedure, the procedure name need not be listed -- it is implicitly assumed, as illustrated in the `Pfun()` function." ] }, { @@ -206,21 +206,21 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_declare_target.4.f90 " + "%load ../sources/Example_declare_target.4.f90" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " #### `declare` `target` and `end` `declare` `target` with `declare` `simd` " + " #### `declare` `target` and `end` `declare` `target` with `declare` `simd` " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example shows how the `declare` `target` and `end` `declare` `target` directives are used to indicate that a function is available on a target device. The `declare` `simd` directive indicates that there is a SIMD version of the function `P()` that is available on the target device as well as one that is available on the host device. " + " The following example shows how the `declare` `target` and `end` `declare` `target` directives are used to indicate that a function is available on a target device. The `declare` `simd` directive indicates that there is a SIMD version of the function `P()` that is available on the target device as well as one that is available on the host device." ] }, { @@ -229,14 +229,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_declare_target.5.c " + "%load ../sources/Example_declare_target.5.c" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The Fortran version of the above C code uses a different syntax. Fortran modules use a list syntax of the `declare` `target` declaration for the mapping. Here the _N_ and _Q_ variables are declared in the list form as a comma separated list. The function declaration does not use a list and implicitly assumes the function name. In this Fortran example row and column indices are reversed relative to the C/C++ example, as is usual for codes optimized for memory access. " + " The Fortran version of the above C code uses a different syntax. Fortran modules use a list syntax of the `declare` `target` declaration for the mapping. Here the _N_ and _Q_ variables are declared in the list form as a comma separated list. The function declaration does not use a list and implicitly assumes the function name. In this Fortran example row and column indices are reversed relative to the C/C++ example, as is usual for codes optimized for memory access." ] }, { @@ -245,42 +245,42 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_declare_target.5.f90 " + "%load ../sources/Example_declare_target.5.f90" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " #### `declare` ~ `target` Directive with `link` Clause " + " #### `declare` ~ `target` Directive with `link` Clause" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " In the OpenMP 4.5 standard the `declare` ~ `target` directive was extended to allow static data to be mapped, emph{when needed}, through a `link` clause. " + " In the OpenMP 4.5 standard the `declare` ~ `target` directive was extended to allow static data to be mapped, emph{when needed}, through a `link` clause." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " Data storage for items listed in the `link` clause becomes available on the device when it is mapped implicitly or explicitly in a `map` clause, and it persists for the scope of the mapping (as specified by a `target` construct, a `target` ~ `data` construct, or `target` ~ `enter/exit` ~ `data` constructs). " + " Data storage for items listed in the `link` clause becomes available on the device when it is mapped implicitly or explicitly in a `map` clause, and it persists for the scope of the mapping (as specified by a `target` construct, a `target` ~ `data` construct, or `target` ~ `enter/exit` ~ `data` constructs)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " Tip: When all the global data items will not fit on a device and are not needed simultaneously, use the `link` clause and map the data only when it is needed. " + " Tip: When all the global data items will not fit on a device and are not needed simultaneously, use the `link` clause and map the data only when it is needed." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following C and Fortran examples show two sets of data (single precision and double precision) that are global on the host for the entire execution on the host; but are only used globally on the device for part of the program execution. The single precision data are allocated and persist only for the first `target` region. Similarly, the double precision data are in scope on the device only for the second `target` region. " + " The following C and Fortran examples show two sets of data (single precision and double precision) that are global on the host for the entire execution on the host; but are only used globally on the device for part of the program execution. The single precision data are allocated and persist only for the first `target` region. Similarly, the double precision data are in scope on the device only for the second `target` region." ] }, { @@ -289,7 +289,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_declare_target.6.c " + "%load ../sources/Example_declare_target.6.c" ] }, { @@ -298,14 +298,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_declare_target.6.f90 " + "%load ../sources/Example_declare_target.6.f90" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---end--- " + "---end---" ] } ], @@ -323,4 +323,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/notebook/Examples_default_none.ipynb b/notebook/Examples_default_none.ipynb index ef2552e..04d6d8c 100644 --- a/notebook/Examples_default_none.ipynb +++ b/notebook/Examples_default_none.ipynb @@ -4,21 +4,21 @@ "cell_type": "markdown", "metadata": {}, "source": [ - " ### The `default(none)` Clause " + " ### The `default(none)` Clause" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example distinguishes the variables that are affected by the `default(none)` clause from those that are not. " + " The following example distinguishes the variables that are affected by the `default(none)` clause from those that are not. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " ccppspecificstart Beginning with OpenMP 4.0, variables with `const` -qualified type and no mutable member are no longer predetermined shared. Thus, these variables (variable _c_ in the example) need to be explicitly listed in data-sharing attribute clauses when the `default(none)` clause is specified. " + " ccppspecificstart Beginning with OpenMP 4.0, variables with `const` -qualified type and no mutable member are no longer predetermined shared. Thus, these variables (variable _c_ in the example) need to be explicitly listed in data-sharing attribute clauses when the `default(none)` clause is specified." ] }, { @@ -27,14 +27,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_default_none.1.c " + "%load ../sources/Example_default_none.1.c" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " ccppspecificend " + " ccppspecificend" ] }, { @@ -43,14 +43,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_default_none.1.f " + "%load ../sources/Example_default_none.1.f" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---end--- " + "---end---" ] } ], @@ -68,4 +68,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/notebook/Examples_device.ipynb b/notebook/Examples_device.ipynb index de2cdc1..6edeba5 100644 --- a/notebook/Examples_device.ipynb +++ b/notebook/Examples_device.ipynb @@ -4,21 +4,21 @@ "cell_type": "markdown", "metadata": {}, "source": [ - " ### Device Routines " + " ### Device Routines" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " #### `omp_is_initial_device` Routine " + " #### `omp_is_initial_device` Routine" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example shows how the `omp_is_initial_device` runtime library routine can be used to query if a code is executing on the initial host device or on a target device. The example then sets the number of threads in the `parallel` region based on where the code is executing. " + " The following example shows how the `omp_is_initial_device` runtime library routine can be used to query if a code is executing on the initial host device or on a target device. The example then sets the number of threads in the `parallel` region based on where the code is executing." ] }, { @@ -27,7 +27,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_device.1.c " + "%load ../sources/Example_device.1.c" ] }, { @@ -36,21 +36,21 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_device.1.f90 " + "%load ../sources/Example_device.1.f90" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " #### `omp_get_num_devices` Routine " + " #### `omp_get_num_devices` Routine" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example shows how the `omp_get_num_devices` runtime library routine can be used to determine the number of devices. " + " The following example shows how the `omp_get_num_devices` runtime library routine can be used to determine the number of devices." ] }, { @@ -59,7 +59,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_device.2.c " + "%load ../sources/Example_device.2.c" ] }, { @@ -68,28 +68,28 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_device.2.f90 " + "%load ../sources/Example_device.2.f90" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "subsection{ `omp_set_default_device` and " + "subsection{ `omp_set_default_device` and " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " `omp_get_default_device` Routines} " + " `omp_get_default_device` Routines}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example shows how the `omp_set_default_device` and `omp_get_default_device` runtime library routines can be used to set the default device and determine the default device respectively. " + " The following example shows how the `omp_set_default_device` and `omp_get_default_device` runtime library routines can be used to set the default device and determine the default device respectively." ] }, { @@ -98,7 +98,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_device.3.c " + "%load ../sources/Example_device.3.c" ] }, { @@ -107,35 +107,35 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_device.3.f90 " + "%load ../sources/Example_device.3.f90" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " #### Target Memory and Device Pointers Routines " + " #### Target Memory and Device Pointers Routines" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example shows how to create space on a device, transfer data to and from that space, and free the space, using API calls. The API calls directly execute allocation, copy and free operations on the device, without invoking any mapping through a `target` directive. The `omp_target_alloc` routine allocates space and returns a device pointer for referencing the space in the `omp_target_memcpy` API routine on the host. The `omp_target_free` routine frees the space on the device. " + " The following example shows how to create space on a device, transfer data to and from that space, and free the space, using API calls. The API calls directly execute allocation, copy and free operations on the device, without invoking any mapping through a `target` directive. The `omp_target_alloc` routine allocates space and returns a device pointer for referencing the space in the `omp_target_memcpy` API routine on the host. The `omp_target_free` routine frees the space on the device." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The example also illustrates how to access that space in a `target` region by exposing the device pointer in an `is_device_ptr` clause. " + " The example also illustrates how to access that space in a `target` region by exposing the device pointer in an `is_device_ptr` clause." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The example creates an array of cosine values on the default device, to be used on the host device. The function fails if a default device is not available. " + " The example creates an array of cosine values on the default device, to be used on the host device. The function fails if a default device is not available." ] }, { @@ -144,14 +144,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_device.4.c " + "%load ../sources/Example_device.4.c" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---end--- " + "---end---" ] } ], @@ -169,4 +169,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/notebook/Examples_doacross.ipynb b/notebook/Examples_doacross.ipynb index 2016b86..9825f52 100644 --- a/notebook/Examples_doacross.ipynb +++ b/notebook/Examples_doacross.ipynb @@ -4,21 +4,21 @@ "cell_type": "markdown", "metadata": {}, "source": [ - " ### Doacross Loop Nest " + " ### Doacross Loop Nest" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " An `ordered` clause can be used on a loop construct with an integer parameter argument to define the number of associated loops within a _doacross loop nest_ where cross-iteration dependences exist. A `depend` clause on an `ordered` construct within an ordered loop describes the dependences of the _doacross_ loops. " + " An `ordered` clause can be used on a loop construct with an integer parameter argument to define the number of associated loops within a _doacross loop nest_ where cross-iteration dependences exist. A `depend` clause on an `ordered` construct within an ordered loop describes the dependences of the _doacross_ loops. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " In the code below, the `depend(sink:i-1)` clause defines an _i-1_ to _i_ cross-iteration dependence that specifies a wait point for the completion of computation from iteration _i-1_ before proceeding to the subsequent statements. The `depend(source)` clause indicates the completion of computation from the current iteration ( _i_ ) to satisfy the cross-iteration dependence that arises from the iteration. For this example the same sequential ordering could have been achieved with an `ordered` clause without a parameter, on the loop directive, and a single `ordered` directive without the `depend` clause specified for the statement executing the _bar_ function. " + " In the code below, the `depend(sink:i-1)` clause defines an _i-1_ to _i_ cross-iteration dependence that specifies a wait point for the completion of computation from iteration _i-1_ before proceeding to the subsequent statements. The `depend(source)` clause indicates the completion of computation from the current iteration ( _i_ ) to satisfy the cross-iteration dependence that arises from the iteration. For this example the same sequential ordering could have been achieved with an `ordered` clause without a parameter, on the loop directive, and a single `ordered` directive without the `depend` clause specified for the statement executing the _bar_ function." ] }, { @@ -27,7 +27,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_doacross.1.c " + "%load ../sources/Example_doacross.1.c" ] }, { @@ -36,14 +36,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_doacross.1.f90 " + "%load ../sources/Example_doacross.1.f90" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following code is similar to the previous example but with _doacross loop nest_ extended to two nested loops, _i_ and _j_ , as specified by the `ordered(2)` clause on the loop directive. In the C/C++ code, the _i_ and _j_ loops are the first and second associated loops, respectively, whereas in the Fortran code, the _j_ and _i_ loops are the first and second associated loops, respectively. The `depend(sink:i-1,j)` and `depend(sink:i,j-1)` clauses in the C/C++ code define cross-iteration dependences in two dimensions from iterations ( _i-1, j_ ) and ( _i, j-1_ ) to iteration ( _i, j_ ). Likewise, the `depend(sink:j-1,i)` and `depend(sink:j,i-1)` clauses in the Fortran code define cross-iteration dependences from iterations ( _j-1, i_ ) and ( _j, i-1_ ) to iteration ( _j, i_ ). " + " The following code is similar to the previous example but with _doacross loop nest_ extended to two nested loops, _i_ and _j_ , as specified by the `ordered(2)` clause on the loop directive. In the C/C++ code, the _i_ and _j_ loops are the first and second associated loops, respectively, whereas in the Fortran code, the _j_ and _i_ loops are the first and second associated loops, respectively. The `depend(sink:i-1,j)` and `depend(sink:i,j-1)` clauses in the C/C++ code define cross-iteration dependences in two dimensions from iterations ( _i-1, j_ ) and ( _i, j-1_ ) to iteration ( _i, j_ ). Likewise, the `depend(sink:j-1,i)` and `depend(sink:j,i-1)` clauses in the Fortran code define cross-iteration dependences from iterations ( _j-1, i_ ) and ( _j, i-1_ ) to iteration ( _j, i_ )." ] }, { @@ -52,7 +52,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_doacross.2.c " + "%load ../sources/Example_doacross.2.c" ] }, { @@ -61,14 +61,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_doacross.2.f90 " + "%load ../sources/Example_doacross.2.f90" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example shows the incorrect use of the `ordered` directive with a `depend` clause. There are two issues with the code. The first issue is a missing `ordered` ~ `depend(source)` directive, which could cause a deadlock. The second issue is the `depend(sink:i+1,j)` and `depend(sink:i,j+1)` clauses define dependences on lexicographically later source iterations ( _i+1, j_ ) and ( _i, j+1_ ), which could cause a deadlock as well since they may not start to execute until the current iteration completes. " + " The following example shows the incorrect use of the `ordered` directive with a `depend` clause. There are two issues with the code. The first issue is a missing `ordered` ~ `depend(source)` directive, which could cause a deadlock. The second issue is the `depend(sink:i+1,j)` and `depend(sink:i,j+1)` clauses define dependences on lexicographically later source iterations ( _i+1, j_ ) and ( _i, j+1_ ), which could cause a deadlock as well since they may not start to execute until the current iteration completes." ] }, { @@ -77,7 +77,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_doacross.3.c " + "%load ../sources/Example_doacross.3.c" ] }, { @@ -86,14 +86,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_doacross.3.f90 " + "%load ../sources/Example_doacross.3.f90" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example illustrates the use of the `collapse` clause for a _doacross loop nest_ . The _i_ and _j_ loops are the associated loops for the collapsed loop as well as for the _doacross loop nest_ . The example also shows a compliant usage of the dependence source directive placed before the corresponding sink directive. Checking the completion of computation from previous iterations at the sink point can occur after the source statement. " + " The following example illustrates the use of the `collapse` clause for a _doacross loop nest_ . The _i_ and _j_ loops are the associated loops for the collapsed loop as well as for the _doacross loop nest_ . The example also shows a compliant usage of the dependence source directive placed before the corresponding sink directive. Checking the completion of computation from previous iterations at the sink point can occur after the source statement." ] }, { @@ -102,7 +102,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_doacross.4.c " + "%load ../sources/Example_doacross.4.c" ] }, { @@ -111,14 +111,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_doacross.4.f90 " + "%load ../sources/Example_doacross.4.f90" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---end--- " + "---end---" ] } ], @@ -136,4 +136,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/notebook/Examples_flush_nolist.ipynb b/notebook/Examples_flush_nolist.ipynb index 871bb0a..585c6f0 100644 --- a/notebook/Examples_flush_nolist.ipynb +++ b/notebook/Examples_flush_nolist.ipynb @@ -4,14 +4,14 @@ "cell_type": "markdown", "metadata": {}, "source": [ - " ### The `flush` Construct without a List " + " ### The `flush` Construct without a List" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example distinguishes the shared variables affected by a `flush` construct with no list from the shared objects that are not affected: " + " The following example distinguishes the shared variables affected by a `flush` construct with no list from the shared objects that are not affected:" ] }, { @@ -20,7 +20,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_flush_nolist.1.c " + "%load ../sources/Example_flush_nolist.1.c" ] }, { @@ -29,14 +29,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_flush_nolist.1.f " + "%load ../sources/Example_flush_nolist.1.f" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---end--- " + "---end---" ] } ], @@ -54,4 +54,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/notebook/Examples_fort_do.ipynb b/notebook/Examples_fort_do.ipynb index 1c2615b..5df04ce 100644 --- a/notebook/Examples_fort_do.ipynb +++ b/notebook/Examples_fort_do.ipynb @@ -4,21 +4,21 @@ "cell_type": "markdown", "metadata": {}, "source": [ - " ### Fortran Restrictions on the `do` Construct " + " ### Fortran Restrictions on the `do` Construct" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " fortranspecificstart " + " fortranspecificstart" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " If an `end do` directive follows a _do-construct_ in which several `DO` statements share a `DO` termination statement, then a `do` directive can only be specified for the outermost of these `DO` statements. The following example contains correct usages of loop constructs: " + " If an `end do` directive follows a _do-construct_ in which several `DO` statements share a `DO` termination statement, then a `do` directive can only be specified for the outermost of these `DO` statements. The following example contains correct usages of loop constructs:" ] }, { @@ -27,14 +27,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_fort_do.1.f " + "%load ../sources/Example_fort_do.1.f" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example is non-conforming because the matching `do` directive for the `end do` does not precede the outermost loop: " + " The following example is non-conforming because the matching `do` directive for the `end do` does not precede the outermost loop:" ] }, { @@ -43,21 +43,21 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_fort_do.2.f " + "%load ../sources/Example_fort_do.2.f" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " fortranspecificend " + " fortranspecificend" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---end--- " + "---end---" ] } ], @@ -75,4 +75,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/notebook/Examples_fort_loopvar.ipynb b/notebook/Examples_fort_loopvar.ipynb index 329cd1a..be2576a 100644 --- a/notebook/Examples_fort_loopvar.ipynb +++ b/notebook/Examples_fort_loopvar.ipynb @@ -4,21 +4,21 @@ "cell_type": "markdown", "metadata": {}, "source": [ - " ### Fortran Private Loop Iteration Variables " + " ### Fortran Private Loop Iteration Variables" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " fortranspecificstart " + " fortranspecificstart" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " In general loop iteration variables will be private, when used in the _do-loop_ of a `do` and `parallel do` construct or in sequential loops in a `parallel` construct (see Section 2.7.1 and Section 2.14.1 of the OpenMP 4.0 specification). In the following example of a sequential loop in a `parallel` construct the loop iteration variable _I_ will be private. " + " In general loop iteration variables will be private, when used in the _do-loop_ of a `do` and `parallel do` construct or in sequential loops in a `parallel` construct (see Section 2.7.1 and Section 2.14.1 of the OpenMP 4.0 specification). In the following example of a sequential loop in a `parallel` construct the loop iteration variable _I_ will be private." ] }, { @@ -27,14 +27,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_ffreenexamplefort_loopvar1 " + "%load ../sources/Example_ffreenexamplefort_loopvar1" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " In exceptional cases, loop iteration variables can be made shared, as in the following example: " + " In exceptional cases, loop iteration variables can be made shared, as in the following example:" ] }, { @@ -43,21 +43,21 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_ffreenexamplefort_loopvar2 " + "%load ../sources/Example_ffreenexamplefort_loopvar2" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " Note however that the use of shared loop iteration variables can easily lead to race conditions. fortranspecificend " + " Note however that the use of shared loop iteration variables can easily lead to race conditions. fortranspecificend" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---end--- " + "---end---" ] } ], @@ -75,4 +75,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/notebook/Examples_fort_race.ipynb b/notebook/Examples_fort_race.ipynb index d457dd3..c77abdf 100644 --- a/notebook/Examples_fort_race.ipynb +++ b/notebook/Examples_fort_race.ipynb @@ -4,21 +4,21 @@ "cell_type": "markdown", "metadata": {}, "source": [ - " ### Race Conditions Caused by Implied Copies of Shared Variables in Fortran " + " ### Race Conditions Caused by Implied Copies of Shared Variables in Fortran" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " fortranspecificstart " + " fortranspecificstart" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example contains a race condition, because the shared variable, which is an array section, is passed as an actual argument to a routine that has an assumed-size array as its dummy argument. The subroutine call passing an array section argument may cause the compiler to copy the argument into a temporary location prior to the call and copy from the temporary location into the original variable when the subroutine returns. This copying would cause races in the `parallel` region. " + " The following example contains a race condition, because the shared variable, which is an array section, is passed as an actual argument to a routine that has an assumed-size array as its dummy argument. The subroutine call passing an array section argument may cause the compiler to copy the argument into a temporary location prior to the call and copy from the temporary location into the original variable when the subroutine returns. This copying would cause races in the `parallel` region." ] }, { @@ -27,21 +27,21 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_ffreenexamplefort_race1 " + "%load ../sources/Example_ffreenexamplefort_race1" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " fortranspecificend " + " fortranspecificend" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---end--- " + "---end---" ] } ], @@ -59,4 +59,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/notebook/Examples_fort_sa_private.ipynb b/notebook/Examples_fort_sa_private.ipynb index c329b6e..31e9042 100644 --- a/notebook/Examples_fort_sa_private.ipynb +++ b/notebook/Examples_fort_sa_private.ipynb @@ -4,21 +4,21 @@ "cell_type": "markdown", "metadata": {}, "source": [ - " ### Fortran Restrictions on Storage Association with the `private` Clause " + " ### Fortran Restrictions on Storage Association with the `private` Clause" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " fortranspecificstart " + " fortranspecificstart" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following non-conforming examples illustrate the implications of the `private` clause rules with regard to storage association. " + " The following non-conforming examples illustrate the implications of the `private` clause rules with regard to storage association. " ] }, { @@ -27,7 +27,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_fort_sa_private.1.f " + "%load ../sources/Example_fort_sa_private.1.f" ] }, { @@ -36,7 +36,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_fort_sa_private.2.f " + "%load ../sources/Example_fort_sa_private.2.f" ] }, { @@ -45,7 +45,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_fort_sa_private.3.f " + "%load ../sources/Example_fort_sa_private.3.f" ] }, { @@ -53,7 +53,7 @@ "metadata": {}, "source": [ " \n", -" blue line floater at top of this page for 'Fortran, cont.' [t!] linewitharrows{-1}{dashed}{Fortran (cont.)}{8em} " +" blue line floater at top of this page for 'Fortran, cont.' [t!] linewitharrows{-1}{dashed}{Fortran (cont.)}{8em} " ] }, { @@ -62,7 +62,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_fort_sa_private.4.f " + "%load ../sources/Example_fort_sa_private.4.f" ] }, { @@ -71,21 +71,21 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_fort_sa_private.5.f " + "%load ../sources/Example_fort_sa_private.5.f" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " fortranspecificend " + " fortranspecificend" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---end--- " + "---end---" ] } ], @@ -103,4 +103,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/notebook/Examples_fort_sp_common.ipynb b/notebook/Examples_fort_sp_common.ipynb index 7947994..367e96e 100644 --- a/notebook/Examples_fort_sp_common.ipynb +++ b/notebook/Examples_fort_sp_common.ipynb @@ -4,28 +4,28 @@ "cell_type": "markdown", "metadata": {}, "source": [ - " ### Fortran Restrictions on `shared` and `private` Clauses with Common Blocks " + " ### Fortran Restrictions on `shared` and `private` Clauses with Common Blocks" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " fortranspecificstart " + " fortranspecificstart" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " When a named common block is specified in a `private` , `firstprivate` , or `lastprivate` clause of a construct, none of its members may be declared in another data-sharing attribute clause on that construct. The following examples illustrate this point. " + " When a named common block is specified in a `private` , `firstprivate` , or `lastprivate` clause of a construct, none of its members may be declared in another data-sharing attribute clause on that construct. The following examples illustrate this point. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example is conforming: " + " The following example is conforming:" ] }, { @@ -34,14 +34,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_fort_sp_common.1.f " + "%load ../sources/Example_fort_sp_common.1.f" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example is also conforming: " + " The following example is also conforming:" ] }, { @@ -50,7 +50,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_fort_sp_common.2.f " + "%load ../sources/Example_fort_sp_common.2.f" ] }, { @@ -58,14 +58,14 @@ "metadata": {}, "source": [ " \n", -" blue line floater at top of this page for 'Fortran, cont.' [t!] linewitharrows{-1}{dashed}{Fortran (cont.)}{8em} " +" blue line floater at top of this page for 'Fortran, cont.' [t!] linewitharrows{-1}{dashed}{Fortran (cont.)}{8em} " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example is conforming: " + " The following example is conforming:" ] }, { @@ -74,14 +74,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_fort_sp_common.3.f " + "%load ../sources/Example_fort_sp_common.3.f" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example is non-conforming because `x` is a constituent element of `c` : " + " The following example is non-conforming because `x` is a constituent element of `c` :" ] }, { @@ -90,14 +90,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_fort_sp_common.4.f " + "%load ../sources/Example_fort_sp_common.4.f" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example is non-conforming because a common block may not be declared both shared and private: " + " The following example is non-conforming because a common block may not be declared both shared and private:" ] }, { @@ -106,21 +106,21 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_fort_sp_common.5.f " + "%load ../sources/Example_fort_sp_common.5.f" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " fortranspecificend " + " fortranspecificend" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---end--- " + "---end---" ] } ], @@ -138,4 +138,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/notebook/Examples_fpriv_sections.ipynb b/notebook/Examples_fpriv_sections.ipynb index 5f5f985..16adcc4 100644 --- a/notebook/Examples_fpriv_sections.ipynb +++ b/notebook/Examples_fpriv_sections.ipynb @@ -4,14 +4,14 @@ "cell_type": "markdown", "metadata": {}, "source": [ - " ### The `firstprivate` Clause and the `sections` Construct " + " ### The `firstprivate` Clause and the `sections` Construct" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " In the following example of the `sections` construct the `firstprivate` clause is used to initialize the private copy of `section_count` of each thread. The problem is that the `section` constructs modify `section_count` , which breaks the independence of the `section` constructs. When different threads execute each section, both sections will print the value 1. When the same thread executes the two sections, one section will print the value 1 and the other will print the value 2. Since the order of execution of the two sections in this case is unspecified, it is unspecified which section prints which value. " + " In the following example of the `sections` construct the `firstprivate` clause is used to initialize the private copy of `section_count` of each thread. The problem is that the `section` constructs modify `section_count` , which breaks the independence of the `section` constructs. When different threads execute each section, both sections will print the value 1. When the same thread executes the two sections, one section will print the value 1 and the other will print the value 2. Since the order of execution of the two sections in this case is unspecified, it is unspecified which section prints which value. " ] }, { @@ -20,7 +20,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_fpriv_sections.1.c " + "%load ../sources/Example_fpriv_sections.1.c" ] }, { @@ -29,14 +29,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_fpriv_sections.1.f90 " + "%load ../sources/Example_fpriv_sections.1.f90" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---end--- " + "---end---" ] } ], @@ -54,4 +54,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/notebook/Examples_get_nthrs.ipynb b/notebook/Examples_get_nthrs.ipynb index e42cdec..5ebddf1 100644 --- a/notebook/Examples_get_nthrs.ipynb +++ b/notebook/Examples_get_nthrs.ipynb @@ -4,14 +4,14 @@ "cell_type": "markdown", "metadata": {}, "source": [ - " ### The `omp_get_num_threads` Routine " + " ### The `omp_get_num_threads` Routine" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " In the following example, the `omp_get_num_threads` call returns 1 in the sequential part of the code, so `np` will always be equal to 1. To determine the number of threads that will be deployed for the `parallel` region, the call should be inside the `parallel` region. " + " In the following example, the `omp_get_num_threads` call returns 1 in the sequential part of the code, so `np` will always be equal to 1. To determine the number of threads that will be deployed for the `parallel` region, the call should be inside the `parallel` region." ] }, { @@ -20,7 +20,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_get_nthrs.1.c " + "%load ../sources/Example_get_nthrs.1.c" ] }, { @@ -29,14 +29,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_get_nthrs.1.f " + "%load ../sources/Example_get_nthrs.1.f" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example shows how to rewrite this program without including a query for the number of threads: " + " The following example shows how to rewrite this program without including a query for the number of threads:" ] }, { @@ -45,7 +45,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_get_nthrs.2.c " + "%load ../sources/Example_get_nthrs.2.c" ] }, { @@ -54,14 +54,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_get_nthrs.2.f " + "%load ../sources/Example_get_nthrs.2.f" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---end--- " + "---end---" ] } ], @@ -79,4 +79,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/notebook/Examples_icv.ipynb b/notebook/Examples_icv.ipynb index e09d706..d5a5a8b 100644 --- a/notebook/Examples_icv.ipynb +++ b/notebook/Examples_icv.ipynb @@ -4,70 +4,70 @@ "cell_type": "markdown", "metadata": {}, "source": [ - " ### Internal Control Variables (ICVs) " + " ### Internal Control Variables (ICVs)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " According to Section 2.3 of the OpenMP 4.0 specification, an OpenMP implementation must act as if there are ICVs that control the behavior of the program. This example illustrates two ICVs, _nthreads-var_ and _max-active-levels-var_ . The _nthreads-var_ ICV controls the number of threads requested for encountered parallel regions; there is one copy of this ICV per task. The _max-active-levels-var_ ICV controls the maximum number of nested active parallel regions; there is one copy of this ICV for the whole program. " + " According to Section 2.3 of the OpenMP 4.0 specification, an OpenMP implementation must act as if there are ICVs that control the behavior of the program. This example illustrates two ICVs, _nthreads-var_ and _max-active-levels-var_ . The _nthreads-var_ ICV controls the number of threads requested for encountered parallel regions; there is one copy of this ICV per task. The _max-active-levels-var_ ICV controls the maximum number of nested active parallel regions; there is one copy of this ICV for the whole program." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " In the following example, the _nest-var_ , _max-active-levels-var_ , _dyn-var_ , and _nthreads-var_ ICVs are modified through calls to the runtime library routines `omp_set_nested` , `omp_set_max_active_levels` , ` omp_set_dynamic` , and `omp_set_num_threads` respectively. These ICVs affect the operation of `parallel` regions. Each implicit task generated by a `parallel` region has its own copy of the _nest-var, dyn-var_ , and _nthreads-var_ ICVs. " + " In the following example, the _nest-var_ , _max-active-levels-var_ , _dyn-var_ , and _nthreads-var_ ICVs are modified through calls to the runtime library routines `omp_set_nested` , `omp_set_max_active_levels` , ` omp_set_dynamic` , and `omp_set_num_threads` respectively. These ICVs affect the operation of `parallel` regions. Each implicit task generated by a `parallel` region has its own copy of the _nest-var, dyn-var_ , and _nthreads-var_ ICVs." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " In the following example, the new value of _nthreads-var_ applies only to the implicit tasks that execute the call to `omp_set_num_threads` . There is one copy of the _max-active-levels-var_ ICV for the whole program and its value is the same for all tasks. This example assumes that nested parallelism is supported. " + " In the following example, the new value of _nthreads-var_ applies only to the implicit tasks that execute the call to `omp_set_num_threads` . There is one copy of the _max-active-levels-var_ ICV for the whole program and its value is the same for all tasks. This example assumes that nested parallelism is supported." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The outer `parallel` region creates a team of two threads; each of the threads will execute one of the two implicit tasks generated by the outer `parallel` region. " + " The outer `parallel` region creates a team of two threads; each of the threads will execute one of the two implicit tasks generated by the outer `parallel` region." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " Each implicit task generated by the outer `parallel` region calls `omp_set_num_threads(3)` , assigning the value 3 to its respective copy of _nthreads-var_ . Then each implicit task encounters an inner `parallel` region that creates a team of three threads; each of the threads will execute one of the three implicit tasks generated by that inner `parallel` region. " + " Each implicit task generated by the outer `parallel` region calls `omp_set_num_threads(3)` , assigning the value 3 to its respective copy of _nthreads-var_ . Then each implicit task encounters an inner `parallel` region that creates a team of three threads; each of the threads will execute one of the three implicit tasks generated by that inner `parallel` region." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " Since the outer `parallel` region is executed by 2 threads, and the inner by 3, there will be a total of 6 implicit tasks generated by the two inner `parallel` regions. " + " Since the outer `parallel` region is executed by 2 threads, and the inner by 3, there will be a total of 6 implicit tasks generated by the two inner `parallel` regions." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " Each implicit task generated by an inner `parallel` region will execute the call to `omp_set_num_threads(4)` , assigning the value 4 to its respective copy of _nthreads-var_ . " + " Each implicit task generated by an inner `parallel` region will execute the call to `omp_set_num_threads(4)` , assigning the value 4 to its respective copy of _nthreads-var_ ." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The print statement in the outer `parallel` region is executed by only one of the threads in the team. So it will be executed only once. " + " The print statement in the outer `parallel` region is executed by only one of the threads in the team. So it will be executed only once." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The print statement in an inner `parallel` region is also executed by only one of the threads in the team. Since we have a total of two inner `parallel` regions, the print statement will be executed twice -- once per inner `parallel` region. " + " The print statement in an inner `parallel` region is also executed by only one of the threads in the team. Since we have a total of two inner `parallel` regions, the print statement will be executed twice -- once per inner `parallel` region." ] }, { @@ -76,7 +76,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_icv.1.c " + "%load ../sources/Example_icv.1.c" ] }, { @@ -85,14 +85,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_icv.1.f " + "%load ../sources/Example_icv.1.f" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---end--- " + "---end---" ] } ], @@ -110,4 +110,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/notebook/Examples_init_lock.ipynb b/notebook/Examples_init_lock.ipynb index 416f7ae..cb0f115 100644 --- a/notebook/Examples_init_lock.ipynb +++ b/notebook/Examples_init_lock.ipynb @@ -4,14 +4,14 @@ "cell_type": "markdown", "metadata": {}, "source": [ - " #### The `omp_init_lock` Routine " + " #### The `omp_init_lock` Routine" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example demonstrates how to initialize an array of locks in a `parallel` region by using `omp_init_lock` . " + " The following example demonstrates how to initialize an array of locks in a `parallel` region by using `omp_init_lock` ." ] }, { @@ -20,7 +20,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_init_lock.1.cpp " + "%load ../sources/Example_init_lock.1.cpp" ] }, { @@ -29,14 +29,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_init_lock.1.f " + "%load ../sources/Example_init_lock.1.f" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---end--- " + "---end---" ] } ], @@ -54,4 +54,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/notebook/Examples_init_lock_with_hint.ipynb b/notebook/Examples_init_lock_with_hint.ipynb index 919c418..009009a 100644 --- a/notebook/Examples_init_lock_with_hint.ipynb +++ b/notebook/Examples_init_lock_with_hint.ipynb @@ -5,14 +5,14 @@ "metadata": {}, "source": [ " \n", -" #### The `omp_init_lock_with_hint` Routine " +" #### The `omp_init_lock_with_hint` Routine" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example demonstrates how to initialize an array of locks in a `parallel` region by using `omp_init_lock_with_hint` . Note, hints are combined with an `|` or `+` operator in C/C++ and a `+` operator in Fortran. " + " The following example demonstrates how to initialize an array of locks in a `parallel` region by using `omp_init_lock_with_hint` . Note, hints are combined with an `|` or `+` operator in C/C++ and a `+` operator in Fortran." ] }, { @@ -21,7 +21,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_init_lock_with_hint.1.cpp " + "%load ../sources/Example_init_lock_with_hint.1.cpp" ] }, { @@ -30,14 +30,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_init_lock_with_hint.1.f " + "%load ../sources/Example_init_lock_with_hint.1.f" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---end--- " + "---end---" ] } ], @@ -55,4 +55,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/notebook/Examples_lastprivate.ipynb b/notebook/Examples_lastprivate.ipynb index 339f446..1df880b 100644 --- a/notebook/Examples_lastprivate.ipynb +++ b/notebook/Examples_lastprivate.ipynb @@ -4,14 +4,14 @@ "cell_type": "markdown", "metadata": {}, "source": [ - " ### The `lastprivate` Clause " + " ### The `lastprivate` Clause" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " Correct execution sometimes depends on the value that the last iteration of a loop assigns to a variable. Such programs must list all such variables in a `lastprivate` clause so that the values of the variables are the same as when the loop is executed sequentially. " + " Correct execution sometimes depends on the value that the last iteration of a loop assigns to a variable. Such programs must list all such variables in a `lastprivate` clause so that the values of the variables are the same as when the loop is executed sequentially." ] }, { @@ -20,7 +20,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_lastprivate.1.c " + "%load ../sources/Example_lastprivate.1.c" ] }, { @@ -29,14 +29,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_lastprivate.1.f " + "%load ../sources/Example_lastprivate.1.f" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---end--- " + "---end---" ] } ], @@ -54,4 +54,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/notebook/Examples_linear_in_loop.ipynb b/notebook/Examples_linear_in_loop.ipynb index 05fc557..1707780 100644 --- a/notebook/Examples_linear_in_loop.ipynb +++ b/notebook/Examples_linear_in_loop.ipynb @@ -4,14 +4,14 @@ "cell_type": "markdown", "metadata": {}, "source": [ - " ### `linear` Clause in Loop Constructs " + " ### `linear` Clause in Loop Constructs" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example shows the use of the `linear` clause in a loop construct to allow the proper parallelization of a loop that contains an induction variable ( _j_ ). At the end of the execution of the loop construct, the original variable _j_ is updated with the value _N/2_ from the last iteration of the loop. " + " The following example shows the use of the `linear` clause in a loop construct to allow the proper parallelization of a loop that contains an induction variable ( _j_ ). At the end of the execution of the loop construct, the original variable _j_ is updated with the value _N/2_ from the last iteration of the loop." ] }, { @@ -20,7 +20,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_linear_in_loop.1.c " + "%load ../sources/Example_linear_in_loop.1.c" ] }, { @@ -29,14 +29,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_linear_in_loop.1.f90 " + "%load ../sources/Example_linear_in_loop.1.f90" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---end--- " + "---end---" ] } ], @@ -54,4 +54,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/notebook/Examples_lock_owner.ipynb b/notebook/Examples_lock_owner.ipynb index 16ff0b9..cede008 100644 --- a/notebook/Examples_lock_owner.ipynb +++ b/notebook/Examples_lock_owner.ipynb @@ -4,21 +4,21 @@ "cell_type": "markdown", "metadata": {}, "source": [ - " #### Ownership of Locks " + " #### Ownership of Locks" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " Ownership of locks has changed since OpenMP 2.5. In OpenMP 2.5, locks are owned by threads; so a lock released by the `omp_unset_lock` routine must be owned by the same thread executing the routine. Beginning with OpenMP 3.0, locks are owned by task regions; so a lock released by the `omp_unset_lock` routine in a task region must be owned by the same task region. " + " Ownership of locks has changed since OpenMP 2.5. In OpenMP 2.5, locks are owned by threads; so a lock released by the `omp_unset_lock` routine must be owned by the same thread executing the routine. Beginning with OpenMP 3.0, locks are owned by task regions; so a lock released by the `omp_unset_lock` routine in a task region must be owned by the same task region." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " This change in ownership requires extra care when using locks. The following program is conforming in OpenMP 2.5 because the thread that releases the lock `lck` in the parallel region is the same thread that acquired the lock in the sequential part of the program (master thread of parallel region and the initial thread are the same). However, it is not conforming beginning with OpenMP 3.0, because the task region that releases the lock `lck` is different from the task region that acquires the lock. " + " This change in ownership requires extra care when using locks. The following program is conforming in OpenMP 2.5 because the thread that releases the lock `lck` in the parallel region is the same thread that acquired the lock in the sequential part of the program (master thread of parallel region and the initial thread are the same). However, it is not conforming beginning with OpenMP 3.0, because the task region that releases the lock `lck` is different from the task region that acquires the lock." ] }, { @@ -27,7 +27,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_lock_owner.1.c " + "%load ../sources/Example_lock_owner.1.c" ] }, { @@ -36,14 +36,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_lock_owner.1.f " + "%load ../sources/Example_lock_owner.1.f" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---end--- " + "---end---" ] } ], @@ -61,4 +61,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/notebook/Examples_locks.ipynb b/notebook/Examples_locks.ipynb index d1aeef6..35f5477 100644 --- a/notebook/Examples_locks.ipynb +++ b/notebook/Examples_locks.ipynb @@ -4,21 +4,21 @@ "cell_type": "markdown", "metadata": {}, "source": [ - " ### Lock Routines " + " ### Lock Routines" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " This section is about the use of lock routines for synchronization. " + " This section is about the use of lock routines for synchronization." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---end--- " + "---end---" ] } ], @@ -36,4 +36,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/notebook/Examples_master.ipynb b/notebook/Examples_master.ipynb index 2e3d800..997c2ac 100644 --- a/notebook/Examples_master.ipynb +++ b/notebook/Examples_master.ipynb @@ -4,14 +4,14 @@ "cell_type": "markdown", "metadata": {}, "source": [ - " ### The `master` Construct " + " ### The `master` Construct" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example demonstrates the master construct . In the example, the master keeps track of how many iterations have been executed and prints out a progress report. The other threads skip the master region without waiting. " + " The following example demonstrates the master construct . In the example, the master keeps track of how many iterations have been executed and prints out a progress report. The other threads skip the master region without waiting." ] }, { @@ -20,7 +20,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_master.1.c " + "%load ../sources/Example_master.1.c" ] }, { @@ -29,14 +29,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_master.1.f " + "%load ../sources/Example_master.1.f" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---end--- " + "---end---" ] } ], @@ -54,4 +54,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/notebook/Examples_mem_model.ipynb b/notebook/Examples_mem_model.ipynb index 6b0a0ab..01d4d3e 100644 --- a/notebook/Examples_mem_model.ipynb +++ b/notebook/Examples_mem_model.ipynb @@ -4,21 +4,21 @@ "cell_type": "markdown", "metadata": {}, "source": [ - " ### The OpenMP Memory Model " + " ### The OpenMP Memory Model" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " In the following example, at Print 1, the value of _x_ could be either 2 or 5, depending on the timing of the threads, and the implementation of the assignment to _x_ . There are two reasons that the value at Print 1 might not be 5. First, Print 1 might be executed before the assignment to _x_ is executed. Second, even if Print 1 is executed after the assignment, the value 5 is not guaranteed to be seen by thread 1 because a flush may not have been executed by thread 0 since the assignment. " + " In the following example, at Print 1, the value of _x_ could be either 2 or 5, depending on the timing of the threads, and the implementation of the assignment to _x_ . There are two reasons that the value at Print 1 might not be 5. First, Print 1 might be executed before the assignment to _x_ is executed. Second, even if Print 1 is executed after the assignment, the value 5 is not guaranteed to be seen by thread 1 because a flush may not have been executed by thread 0 since the assignment." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The barrier after Print 1 contains implicit flushes on all threads, as well as a thread synchronization, so the programmer is guaranteed that the value 5 will be printed by both Print 2 and Print 3. " + " The barrier after Print 1 contains implicit flushes on all threads, as well as a thread synchronization, so the programmer is guaranteed that the value 5 will be printed by both Print 2 and Print 3." ] }, { @@ -27,7 +27,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_mem_model.1.c " + "%load ../sources/Example_mem_model.1.c" ] }, { @@ -36,14 +36,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_mem_model.1.f90 " + "%load ../sources/Example_mem_model.1.f90" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example demonstrates why synchronization is difficult to perform correctly through variables. The value of flag is undefined in both prints on thread 1 and the value of data is only well-defined in the second print. " + " The following example demonstrates why synchronization is difficult to perform correctly through variables. The value of flag is undefined in both prints on thread 1 and the value of data is only well-defined in the second print." ] }, { @@ -52,7 +52,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_mem_model.2.c " + "%load ../sources/Example_mem_model.2.c" ] }, { @@ -61,14 +61,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_mem_model.2.f " + "%load ../sources/Example_mem_model.2.f" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The next example demonstrates why synchronization is difficult to perform correctly through variables. Because the _write_ (1)- _flush_ (1)- _flush_ (2)- _read_ (2) sequence cannot be guaranteed in the example, the statements on thread 0 and thread 1 may execute in either order. " + " The next example demonstrates why synchronization is difficult to perform correctly through variables. Because the _write_ (1)- _flush_ (1)- _flush_ (2)- _read_ (2) sequence cannot be guaranteed in the example, the statements on thread 0 and thread 1 may execute in either order." ] }, { @@ -77,7 +77,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_mem_model.3.c " + "%load ../sources/Example_mem_model.3.c" ] }, { @@ -86,14 +86,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_mem_model.3.f " + "%load ../sources/Example_mem_model.3.f" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---end--- " + "---end---" ] } ], @@ -111,4 +111,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/notebook/Examples_nestable_lock.ipynb b/notebook/Examples_nestable_lock.ipynb index daa2965..3e7316c 100644 --- a/notebook/Examples_nestable_lock.ipynb +++ b/notebook/Examples_nestable_lock.ipynb @@ -4,14 +4,14 @@ "cell_type": "markdown", "metadata": {}, "source": [ - " #### Nestable Lock Routines " + " #### Nestable Lock Routines" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example demonstrates how a nestable lock can be used to synchronize updates both to a whole structure and to one of its members. " + " The following example demonstrates how a nestable lock can be used to synchronize updates both to a whole structure and to one of its members." ] }, { @@ -20,7 +20,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_nestable_lock.1.c " + "%load ../sources/Example_nestable_lock.1.c" ] }, { @@ -29,14 +29,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_nestable_lock.1.f " + "%load ../sources/Example_nestable_lock.1.f" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---end--- " + "---end---" ] } ], @@ -54,4 +54,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/notebook/Examples_nested_loop.ipynb b/notebook/Examples_nested_loop.ipynb index 9e9e29a..3388eb9 100644 --- a/notebook/Examples_nested_loop.ipynb +++ b/notebook/Examples_nested_loop.ipynb @@ -4,14 +4,14 @@ "cell_type": "markdown", "metadata": {}, "source": [ - " ### Nested Loop Constructs " + " ### Nested Loop Constructs" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example of loop construct nesting is conforming because the inner and outer loop regions bind to different `parallel` regions: " + " The following example of loop construct nesting is conforming because the inner and outer loop regions bind to different `parallel` regions:" ] }, { @@ -20,7 +20,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_nested_loop.1.c " + "%load ../sources/Example_nested_loop.1.c" ] }, { @@ -29,14 +29,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_nested_loop.1.f " + "%load ../sources/Example_nested_loop.1.f" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following variation of the preceding example is also conforming: " + " The following variation of the preceding example is also conforming:" ] }, { @@ -45,7 +45,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_nested_loop.2.c " + "%load ../sources/Example_nested_loop.2.c" ] }, { @@ -54,14 +54,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_nested_loop.2.f " + "%load ../sources/Example_nested_loop.2.f" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---end--- " + "---end---" ] } ], @@ -79,4 +79,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/notebook/Examples_nesting_restrict.ipynb b/notebook/Examples_nesting_restrict.ipynb index 41d29b5..52b4689 100644 --- a/notebook/Examples_nesting_restrict.ipynb +++ b/notebook/Examples_nesting_restrict.ipynb @@ -4,21 +4,21 @@ "cell_type": "markdown", "metadata": {}, "source": [ - " ### Restrictions on Nesting of Regions " + " ### Restrictions on Nesting of Regions" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The examples in this section illustrate the region nesting rules. " + " The examples in this section illustrate the region nesting rules. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example is non-conforming because the inner and outer loop regions are closely nested: " + " The following example is non-conforming because the inner and outer loop regions are closely nested:" ] }, { @@ -27,7 +27,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_nesting_restrict.1.c " + "%load ../sources/Example_nesting_restrict.1.c" ] }, { @@ -36,14 +36,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_nesting_restrict.1.f " + "%load ../sources/Example_nesting_restrict.1.f" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following orphaned version of the preceding example is also non-conforming: " + " The following orphaned version of the preceding example is also non-conforming:" ] }, { @@ -52,7 +52,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_nesting_restrict.2.c " + "%load ../sources/Example_nesting_restrict.2.c" ] }, { @@ -61,14 +61,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_nesting_restrict.2.f " + "%load ../sources/Example_nesting_restrict.2.f" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example is non-conforming because the loop and `single` regions are closely nested: " + " The following example is non-conforming because the loop and `single` regions are closely nested:" ] }, { @@ -77,7 +77,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_nesting_restrict.3.c " + "%load ../sources/Example_nesting_restrict.3.c" ] }, { @@ -86,14 +86,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_nesting_restrict.3.f " + "%load ../sources/Example_nesting_restrict.3.f" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example is non-conforming because a `barrier` region cannot be closely nested inside a loop region: " + " The following example is non-conforming because a `barrier` region cannot be closely nested inside a loop region:" ] }, { @@ -102,7 +102,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_nesting_restrict.4.c " + "%load ../sources/Example_nesting_restrict.4.c" ] }, { @@ -111,14 +111,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_nesting_restrict.4.f " + "%load ../sources/Example_nesting_restrict.4.f" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example is non-conforming because the `barrier` region cannot be closely nested inside the `critical` region. If this were permitted, it would result in deadlock due to the fact that only one thread at a time can enter the `critical` region: " + " The following example is non-conforming because the `barrier` region cannot be closely nested inside the `critical` region. If this were permitted, it would result in deadlock due to the fact that only one thread at a time can enter the `critical` region:" ] }, { @@ -127,7 +127,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_nesting_restrict.5.c " + "%load ../sources/Example_nesting_restrict.5.c" ] }, { @@ -136,14 +136,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_nesting_restrict.5.f " + "%load ../sources/Example_nesting_restrict.5.f" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example is non-conforming because the `barrier` region cannot be closely nested inside the `single` region. If this were permitted, it would result in deadlock due to the fact that only one thread executes the `single` region: " + " The following example is non-conforming because the `barrier` region cannot be closely nested inside the `single` region. If this were permitted, it would result in deadlock due to the fact that only one thread executes the `single` region:" ] }, { @@ -152,7 +152,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_nesting_restrict.6.c " + "%load ../sources/Example_nesting_restrict.6.c" ] }, { @@ -161,14 +161,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_nesting_restrict.6.f " + "%load ../sources/Example_nesting_restrict.6.f" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---end--- " + "---end---" ] } ], @@ -186,4 +186,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/notebook/Examples_nowait.ipynb b/notebook/Examples_nowait.ipynb index 7902e82..d44cc29 100644 --- a/notebook/Examples_nowait.ipynb +++ b/notebook/Examples_nowait.ipynb @@ -4,14 +4,14 @@ "cell_type": "markdown", "metadata": {}, "source": [ - " ### The `nowait` Clause " + " ### The `nowait` Clause" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " If there are multiple independent loops within a `parallel` region, you can use the `nowait` clause to avoid the implied barrier at the end of the loop construct, as follows: " + " If there are multiple independent loops within a `parallel` region, you can use the `nowait` clause to avoid the implied barrier at the end of the loop construct, as follows:" ] }, { @@ -20,7 +20,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_nowait.1.c " + "%load ../sources/Example_nowait.1.c" ] }, { @@ -29,21 +29,21 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_nowait.1.f " + "%load ../sources/Example_nowait.1.f" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " In the following example, static scheduling distributes the same logical iteration numbers to the threads that execute the three loop regions. This allows the `nowait` clause to be used, even though there is a data dependence between the loops. The dependence is satisfied as long the same thread executes the same logical iteration numbers in each loop. " + " In the following example, static scheduling distributes the same logical iteration numbers to the threads that execute the three loop regions. This allows the `nowait` clause to be used, even though there is a data dependence between the loops. The dependence is satisfied as long the same thread executes the same logical iteration numbers in each loop." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " Note that the iteration count of the loops must be the same. The example satisfies this requirement, since the iteration space of the first two loops is from `0` to `n-1` (from `1` to `N` in the Fortran version), while the iteration space of the last loop is from `1` to `n` ( `2` to `N+1` in the Fortran version). " + " Note that the iteration count of the loops must be the same. The example satisfies this requirement, since the iteration space of the first two loops is from `0` to `n-1` (from `1` to `N` in the Fortran version), while the iteration space of the last loop is from `1` to `n` ( `2` to `N+1` in the Fortran version)." ] }, { @@ -52,7 +52,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_nowait.2.c " + "%load ../sources/Example_nowait.2.c" ] }, { @@ -61,14 +61,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_nowait.2.f90 " + "%load ../sources/Example_nowait.2.f90" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---end--- " + "---end---" ] } ], @@ -86,4 +86,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/notebook/Examples_nthrs_dynamic.ipynb b/notebook/Examples_nthrs_dynamic.ipynb index d5d4852..a4a3153 100644 --- a/notebook/Examples_nthrs_dynamic.ipynb +++ b/notebook/Examples_nthrs_dynamic.ipynb @@ -4,21 +4,21 @@ "cell_type": "markdown", "metadata": {}, "source": [ - " ### Interaction Between the `num_threads` Clause and `omp_set_dynamic` " + " ### Interaction Between the `num_threads` Clause and `omp_set_dynamic` " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example demonstrates the `num_threads` clause and the effect of the `omp_set_dynamic` routine on it. " + " The following example demonstrates the `num_threads` clause and the effect of the `omp_set_dynamic` routine on it." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The call to the `omp_set_dynamic` routine with argument `0` in C/C++, or `.FALSE.` in Fortran, disables the dynamic adjustment of the number of threads in OpenMP implementations that support it. In this case, 10 threads are provided. Note that in case of an error the OpenMP implementation is free to abort the program or to supply any number of threads available. " + " The call to the `omp_set_dynamic` routine with argument `0` in C/C++, or `.FALSE.` in Fortran, disables the dynamic adjustment of the number of threads in OpenMP implementations that support it. In this case, 10 threads are provided. Note that in case of an error the OpenMP implementation is free to abort the program or to supply any number of threads available." ] }, { @@ -27,7 +27,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_nthrs_dynamic.1.c " + "%load ../sources/Example_nthrs_dynamic.1.c" ] }, { @@ -36,14 +36,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_nthrs_dynamic.1.f " + "%load ../sources/Example_nthrs_dynamic.1.f" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The call to the `omp_set_dynamic` routine with a non-zero argument in C/C++, or `.TRUE.` in Fortran, allows the OpenMP implementation to choose any number of threads between 1 and 10. " + " The call to the `omp_set_dynamic` routine with a non-zero argument in C/C++, or `.TRUE.` in Fortran, allows the OpenMP implementation to choose any number of threads between 1 and 10." ] }, { @@ -52,7 +52,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_nthrs_dynamic.2.c " + "%load ../sources/Example_nthrs_dynamic.2.c" ] }, { @@ -61,21 +61,21 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_nthrs_dynamic.2.f " + "%load ../sources/Example_nthrs_dynamic.2.f" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " It is good practice to set the _dyn-var_ ICV explicitly by calling the `omp_set_dynamic` routine, as its default setting is implementation defined. " + " It is good practice to set the _dyn-var_ ICV explicitly by calling the `omp_set_dynamic` routine, as its default setting is implementation defined." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---end--- " + "---end---" ] } ], @@ -93,4 +93,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/notebook/Examples_nthrs_nesting.ipynb b/notebook/Examples_nthrs_nesting.ipynb index 6f1e2d8..023e663 100644 --- a/notebook/Examples_nthrs_nesting.ipynb +++ b/notebook/Examples_nthrs_nesting.ipynb @@ -4,14 +4,14 @@ "cell_type": "markdown", "metadata": {}, "source": [ - " ### Controlling the Number of Threads on Multiple Nesting Levels " + " ### Controlling the Number of Threads on Multiple Nesting Levels" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following examples demonstrate how to use the `OMP_NUM_THREADS` environment variable to control the number of threads on multiple nesting levels: " + " The following examples demonstrate how to use the `OMP_NUM_THREADS` environment variable to control the number of threads on multiple nesting levels:" ] }, { @@ -20,7 +20,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_nthrs_nesting.1.c " + "%load ../sources/Example_nthrs_nesting.1.c" ] }, { @@ -29,14 +29,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_nthrs_nesting.1.f " + "%load ../sources/Example_nthrs_nesting.1.f" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---end--- " + "---end---" ] } ], @@ -54,4 +54,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/notebook/Examples_ordered.ipynb b/notebook/Examples_ordered.ipynb index c702067..40f9d55 100644 --- a/notebook/Examples_ordered.ipynb +++ b/notebook/Examples_ordered.ipynb @@ -4,14 +4,14 @@ "cell_type": "markdown", "metadata": {}, "source": [ - " ### The `ordered` Clause and the `ordered` Construct " + " ### The `ordered` Clause and the `ordered` Construct" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " Ordered constructs are useful for sequentially ordering the output from work that is done in parallel. The following program prints out the indices in sequential order: " + " Ordered constructs are useful for sequentially ordering the output from work that is done in parallel. The following program prints out the indices in sequential order:" ] }, { @@ -20,7 +20,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_ordered.1.c " + "%load ../sources/Example_ordered.1.c" ] }, { @@ -29,14 +29,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_ordered.1.f " + "%load ../sources/Example_ordered.1.f" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " It is possible to have multiple `ordered` constructs within a loop region with the `ordered` clause specified. The first example is non-conforming because all iterations execute two `ordered` regions. An iteration of a loop must not execute more than one `ordered` region: " + " It is possible to have multiple `ordered` constructs within a loop region with the `ordered` clause specified. The first example is non-conforming because all iterations execute two `ordered` regions. An iteration of a loop must not execute more than one `ordered` region:" ] }, { @@ -45,7 +45,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_ordered.2.c " + "%load ../sources/Example_ordered.2.c" ] }, { @@ -54,14 +54,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_ordered.2.f " + "%load ../sources/Example_ordered.2.f" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following is a conforming example with more than one `ordered` construct. Each iteration will execute only one `ordered` region: " + " The following is a conforming example with more than one `ordered` construct. Each iteration will execute only one `ordered` region:" ] }, { @@ -70,7 +70,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_ordered.3.c " + "%load ../sources/Example_ordered.3.c" ] }, { @@ -79,14 +79,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_ordered.3.f " + "%load ../sources/Example_ordered.3.f" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---end--- " + "---end---" ] } ], @@ -104,4 +104,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/notebook/Examples_parallel.ipynb b/notebook/Examples_parallel.ipynb index 645bc65..7dc91f3 100644 --- a/notebook/Examples_parallel.ipynb +++ b/notebook/Examples_parallel.ipynb @@ -4,14 +4,14 @@ "cell_type": "markdown", "metadata": {}, "source": [ - " ### The `parallel` Construct " + " ### The `parallel` Construct" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The `parallel` construct can be used in coarse-grain parallel programs. In the following example, each thread in the `parallel` region decides what part of the global array _x_ to work on, based on the thread number: " + " The `parallel` construct can be used in coarse-grain parallel programs. In the following example, each thread in the `parallel` region decides what part of the global array _x_ to work on, based on the thread number:" ] }, { @@ -20,7 +20,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_parallel.1.c " + "%load ../sources/Example_parallel.1.c" ] }, { @@ -29,14 +29,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_parallel.1.f " + "%load ../sources/Example_parallel.1.f" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---end--- " + "---end---" ] } ], @@ -54,4 +54,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/notebook/Examples_ploop.ipynb b/notebook/Examples_ploop.ipynb index 211ce4c..d3c117a 100644 --- a/notebook/Examples_ploop.ipynb +++ b/notebook/Examples_ploop.ipynb @@ -4,14 +4,14 @@ "cell_type": "markdown", "metadata": {}, "source": [ - " ### A Simple Parallel Loop " + " ### A Simple Parallel Loop" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example demonstrates how to parallelize a simple loop using the parallel loop construct. The loop iteration variable is private by default, so it is not necessary to specify it explicitly in a `private` clause. " + " The following example demonstrates how to parallelize a simple loop using the parallel loop construct. The loop iteration variable is private by default, so it is not necessary to specify it explicitly in a `private` clause." ] }, { @@ -20,7 +20,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_ploop.1.c " + "%load ../sources/Example_ploop.1.c" ] }, { @@ -29,14 +29,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_ploop.1.f " + "%load ../sources/Example_ploop.1.f" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---end--- " + "---end---" ] } ], @@ -54,4 +54,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/notebook/Examples_pra_iterator.ipynb b/notebook/Examples_pra_iterator.ipynb index 6e1a8d3..5675158 100644 --- a/notebook/Examples_pra_iterator.ipynb +++ b/notebook/Examples_pra_iterator.ipynb @@ -4,7 +4,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - " ### Parallel Random Access Iterator Loop " + " ### Parallel Random Access Iterator Loop" ] }, { @@ -13,14 +13,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_cppspecificstart " + "%load ../sources/Example_cppspecificstart" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example shows a parallel random access iterator loop. " + " The following example shows a parallel random access iterator loop." ] }, { @@ -29,7 +29,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_cppnexamplepra_iterator1 " + "%load ../sources/Example_cppnexamplepra_iterator1" ] }, { @@ -38,14 +38,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_cppspecificend " + "%load ../sources/Example_cppspecificend" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---end--- " + "---end---" ] } ], @@ -63,4 +63,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/notebook/Examples_private.ipynb b/notebook/Examples_private.ipynb index 4af810c..f59764f 100644 --- a/notebook/Examples_private.ipynb +++ b/notebook/Examples_private.ipynb @@ -4,14 +4,14 @@ "cell_type": "markdown", "metadata": {}, "source": [ - " ### The `private` Clause " + " ### The `private` Clause" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " In the following example, the values of original list items _i_ and _j_ are retained on exit from the `parallel` region, while the private list items _i_ and _j_ are modified within the `parallel` construct. " + " In the following example, the values of original list items _i_ and _j_ are retained on exit from the `parallel` region, while the private list items _i_ and _j_ are modified within the `parallel` construct. " ] }, { @@ -20,7 +20,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_private.1.c " + "%load ../sources/Example_private.1.c" ] }, { @@ -29,7 +29,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_private.1.f " + "%load ../sources/Example_private.1.f" ] }, { @@ -38,7 +38,7 @@ "source": [ " In the following example, all uses of the variable _a_ within the loop construct in the routine _f_ refer to a private list \n", "* _a_ , while it is unspecified whether references to _a_ in the routine _g_ are to a private list \n", -"* or the original list item. " +"* or the original list item." ] }, { @@ -47,7 +47,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_private.2.c " + "%load ../sources/Example_private.2.c" ] }, { @@ -56,7 +56,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_private.2.f " + "%load ../sources/Example_private.2.f" ] }, { @@ -64,7 +64,7 @@ "metadata": {}, "source": [ " The following example demonstrates that a list \n", -"* that appears in a `private` clause in a `parallel` construct may also appear in a `private` clause in an enclosed worksharing construct, which results in an additional private copy. " +"* that appears in a `private` clause in a `parallel` construct may also appear in a `private` clause in an enclosed worksharing construct, which results in an additional private copy." ] }, { @@ -73,7 +73,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_private.3.c " + "%load ../sources/Example_private.3.c" ] }, { @@ -82,14 +82,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_private.3.f " + "%load ../sources/Example_private.3.f" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---end--- " + "---end---" ] } ], @@ -107,4 +107,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/notebook/Examples_psections.ipynb b/notebook/Examples_psections.ipynb index ce59625..8a03236 100644 --- a/notebook/Examples_psections.ipynb +++ b/notebook/Examples_psections.ipynb @@ -4,14 +4,14 @@ "cell_type": "markdown", "metadata": {}, "source": [ - " ### The `parallel` `sections` Construct " + " ### The `parallel` `sections` Construct" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " In the following example routines `XAXIS` , `YAXIS` , and `ZAXIS` can be executed concurrently. The first `section` directive is optional. Note that all `section` directives need to appear in the `parallel sections` construct. " + " In the following example routines `XAXIS` , `YAXIS` , and `ZAXIS` can be executed concurrently. The first `section` directive is optional. Note that all `section` directives need to appear in the `parallel sections` construct." ] }, { @@ -20,7 +20,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_psections.1.c " + "%load ../sources/Example_psections.1.c" ] }, { @@ -29,14 +29,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_psections.1.f " + "%load ../sources/Example_psections.1.f" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---end--- " + "---end---" ] } ], @@ -54,4 +54,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/notebook/Examples_reduction.ipynb b/notebook/Examples_reduction.ipynb index d53a7fb..20353a3 100644 --- a/notebook/Examples_reduction.ipynb +++ b/notebook/Examples_reduction.ipynb @@ -4,14 +4,14 @@ "cell_type": "markdown", "metadata": {}, "source": [ - " ### The `reduction` Clause " + " ### The `reduction` Clause" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example demonstrates the `reduction` clause ; note that some reductions can be expressed in the loop in several ways, as shown for the `max` and `min` reductions below: " + " The following example demonstrates the `reduction` clause ; note that some reductions can be expressed in the loop in several ways, as shown for the `max` and `min` reductions below:" ] }, { @@ -20,7 +20,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_reduction.1.c " + "%load ../sources/Example_reduction.1.c" ] }, { @@ -29,14 +29,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_reduction.1.f90 " + "%load ../sources/Example_reduction.1.f90" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " A common implementation of the preceding example is to treat it as if it had been written as follows: " + " A common implementation of the preceding example is to treat it as if it had been written as follows:" ] }, { @@ -45,21 +45,21 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_reduction.2.c " + "%load ../sources/Example_reduction.2.c" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " fortranspecificstartffreenexample{reduction}{2} " + " fortranspecificstartffreenexample{reduction}{2}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following program is non-conforming because the reduction is on the emph{intrinsic procedure name} `MAX` but that name has been redefined to be the variable named `MAX` . " + " The following program is non-conforming because the reduction is on the emph{intrinsic procedure name} `MAX` but that name has been redefined to be the variable named `MAX` ." ] }, { @@ -68,7 +68,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_ffreenexamplereduction3 " + "%load ../sources/Example_ffreenexamplereduction3" ] }, { @@ -76,14 +76,14 @@ "metadata": {}, "source": [ " \n", -" blue line floater at top of this page for 'Fortran, cont.' [t!] linewitharrows{-1}{dashed}{Fortran (cont.)}{8em} " +" blue line floater at top of this page for 'Fortran, cont.' [t!] linewitharrows{-1}{dashed}{Fortran (cont.)}{8em} " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following conforming program performs the reduction using the emph{intrinsic procedure name} `MAX` even though the intrinsic `MAX` has been renamed to `REN` . " + " The following conforming program performs the reduction using the emph{intrinsic procedure name} `MAX` even though the intrinsic `MAX` has been renamed to `REN` ." ] }, { @@ -92,14 +92,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_ffreenexamplereduction4 " + "%load ../sources/Example_ffreenexamplereduction4" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following conforming program performs the reduction using _intrinsic procedure name_ `MAX` even though the intrinsic `MAX` has been renamed to `MIN` . " + " The following conforming program performs the reduction using _intrinsic procedure name_ `MAX` even though the intrinsic `MAX` has been renamed to `MIN` ." ] }, { @@ -108,14 +108,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_ffreenexamplereduction5 " + "%load ../sources/Example_ffreenexamplereduction5" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " fortranspecificend " + " fortranspecificend" ] }, { @@ -123,7 +123,7 @@ "metadata": {}, "source": [ " The following example is non-conforming because the initialization ( `a = 0` ) of the original list \n", -"* `a` is not synchronized with the update of `a` as a result of the reduction computation in the `for` loop. Therefore, the example may print an incorrect value for `a` . " +"* `a` is not synchronized with the update of `a` as a result of the reduction computation in the `for` loop. Therefore, the example may print an incorrect value for `a` ." ] }, { @@ -131,7 +131,7 @@ "metadata": {}, "source": [ " To avoid this problem, the initialization of the original list \n", -"* `a` should complete before any update of `a` as a result of the `reduction` clause. This can be achieved by adding an explicit barrier after the assignment `a = 0` , or by enclosing the assignment `a = 0` in a `single` directive (which has an implied barrier), or by initializing `a` before the start of the `parallel` region. " +"* `a` should complete before any update of `a` as a result of the `reduction` clause. This can be achieved by adding an explicit barrier after the assignment `a = 0` , or by enclosing the assignment `a = 0` in a `single` directive (which has an implied barrier), or by initializing `a` before the start of the `parallel` region." ] }, { @@ -140,7 +140,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_reduction.6.c " + "%load ../sources/Example_reduction.6.c" ] }, { @@ -149,14 +149,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_reduction.6.f " + "%load ../sources/Example_reduction.6.f" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example demonstrates the reduction of array _a_ . In C/C++ this is illustrated by the explicit use of an array section _a[0:N]_ in the `reduction` clause. The corresponding Fortran example uses array syntax supported in the base language. As of the OpenMP 4.5 specification the explicit use of array section in the `reduction` clause in Fortran is not permitted. But this oversight will be fixed in the next release of the specification. " + " The following example demonstrates the reduction of array _a_ . In C/C++ this is illustrated by the explicit use of an array section _a[0:N]_ in the `reduction` clause. The corresponding Fortran example uses array syntax supported in the base language. As of the OpenMP 4.5 specification the explicit use of array section in the `reduction` clause in Fortran is not permitted. But this oversight will be fixed in the next release of the specification." ] }, { @@ -165,7 +165,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_reduction.7.c " + "%load ../sources/Example_reduction.7.c" ] }, { @@ -174,14 +174,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_reduction.7.f90 " + "%load ../sources/Example_reduction.7.f90" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---end--- " + "---end---" ] } ], @@ -199,4 +199,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/notebook/Examples_set_dynamic_nthrs.ipynb b/notebook/Examples_set_dynamic_nthrs.ipynb index 7be90ea..500d9a9 100644 --- a/notebook/Examples_set_dynamic_nthrs.ipynb +++ b/notebook/Examples_set_dynamic_nthrs.ipynb @@ -4,28 +4,28 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "section{The `omp_set_dynamic` and " + "section{The `omp_set_dynamic` and " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " `omp_set_num_threads` Routines} " + " `omp_set_num_threads` Routines}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " Some programs rely on a fixed, prespecified number of threads to execute correctly. Because the default setting for the dynamic adjustment of the number of threads is implementation defined, such programs can choose to turn off the dynamic threads capability and set the number of threads explicitly to ensure portability. The following example shows how to do this using `omp_set_dynamic` , and `omp_set_num_threads` . " + " Some programs rely on a fixed, prespecified number of threads to execute correctly. Because the default setting for the dynamic adjustment of the number of threads is implementation defined, such programs can choose to turn off the dynamic threads capability and set the number of threads explicitly to ensure portability. The following example shows how to do this using `omp_set_dynamic` , and `omp_set_num_threads` ." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " In this example, the program executes correctly only if it is executed by 16 threads. If the implementation is not capable of supporting 16 threads, the behavior of this example is implementation defined. Note that the number of threads executing a `parallel` region remains constant during the region, regardless of the dynamic threads setting. The dynamic threads mechanism determines the number of threads to use at the start of the `parallel` region and keeps it constant for the duration of the region. " + " In this example, the program executes correctly only if it is executed by 16 threads. If the implementation is not capable of supporting 16 threads, the behavior of this example is implementation defined. Note that the number of threads executing a `parallel` region remains constant during the region, regardless of the dynamic threads setting. The dynamic threads mechanism determines the number of threads to use at the start of the `parallel` region and keeps it constant for the duration of the region." ] }, { @@ -34,7 +34,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_set_dynamic_nthrs.1.c " + "%load ../sources/Example_set_dynamic_nthrs.1.c" ] }, { @@ -43,14 +43,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_set_dynamic_nthrs.1.f " + "%load ../sources/Example_set_dynamic_nthrs.1.f" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---end--- " + "---end---" ] } ], @@ -68,4 +68,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/notebook/Examples_simple_lock.ipynb b/notebook/Examples_simple_lock.ipynb index b57b5fd..97b3e7a 100644 --- a/notebook/Examples_simple_lock.ipynb +++ b/notebook/Examples_simple_lock.ipynb @@ -4,21 +4,21 @@ "cell_type": "markdown", "metadata": {}, "source": [ - " #### Simple Lock Routines " + " #### Simple Lock Routines" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " In the following example, the lock routines cause the threads to be idle while waiting for entry to the first critical section, but to do other work while waiting for entry to the second. The `omp_set_lock` function blocks, but the `omp_test_lock` function does not, allowing the work in `skip` to be done. " + " In the following example, the lock routines cause the threads to be idle while waiting for entry to the first critical section, but to do other work while waiting for entry to the second. The `omp_set_lock` function blocks, but the `omp_test_lock` function does not, allowing the work in `skip` to be done. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " Note that the argument to the lock routines should have type `omp_lock_t` , and that there is no need to flush it. " + " Note that the argument to the lock routines should have type `omp_lock_t` , and that there is no need to flush it. " ] }, { @@ -27,14 +27,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_simple_lock.1.c " + "%load ../sources/Example_simple_lock.1.c" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " Note that there is no need to flush the lock variable. " + " Note that there is no need to flush the lock variable. " ] }, { @@ -43,14 +43,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_simple_lock.1.f " + "%load ../sources/Example_simple_lock.1.f" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---end--- " + "---end---" ] } ], @@ -68,4 +68,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/notebook/Examples_single.ipynb b/notebook/Examples_single.ipynb index fe4c761..ef54dcc 100644 --- a/notebook/Examples_single.ipynb +++ b/notebook/Examples_single.ipynb @@ -4,14 +4,14 @@ "cell_type": "markdown", "metadata": {}, "source": [ - " ### The `single` Construct " + " ### The `single` Construct" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example demonstrates the `single` construct. In the example, only one thread prints each of the progress messages. All other threads will skip the `single` region and stop at the barrier at the end of the `single` construct until all threads in the team have reached the barrier. If other threads can proceed without waiting for the thread executing the `single` region, a `nowait` clause can be specified, as is done in the third `single` construct in this example. The user must not make any assumptions as to which thread will execute a `single` region. " + " The following example demonstrates the `single` construct. In the example, only one thread prints each of the progress messages. All other threads will skip the `single` region and stop at the barrier at the end of the `single` construct until all threads in the team have reached the barrier. If other threads can proceed without waiting for the thread executing the `single` region, a `nowait` clause can be specified, as is done in the third `single` construct in this example. The user must not make any assumptions as to which thread will execute a `single` region." ] }, { @@ -20,7 +20,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_single.1.c " + "%load ../sources/Example_single.1.c" ] }, { @@ -29,14 +29,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_single.1.f " + "%load ../sources/Example_single.1.f" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---end--- " + "---end---" ] } ], @@ -54,4 +54,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/notebook/Examples_standalone.ipynb b/notebook/Examples_standalone.ipynb index a9b1087..7adcded 100644 --- a/notebook/Examples_standalone.ipynb +++ b/notebook/Examples_standalone.ipynb @@ -4,21 +4,21 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "section{Placement of `flush` , `barrier` , `taskwait` " + "section{Placement of `flush` , `barrier` , `taskwait` " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " and `taskyield` Directives} " + " and `taskyield` Directives}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example is non-conforming, because the `flush` , `barrier` , `taskwait` , and `taskyield` directives are stand-alone directives and cannot be the immediate substatement of an `if` statement. " + " The following example is non-conforming, because the `flush` , `barrier` , `taskwait` , and `taskyield` directives are stand-alone directives and cannot be the immediate substatement of an `if` statement. " ] }, { @@ -27,14 +27,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_standalone.1.c " + "%load ../sources/Example_standalone.1.c" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example is non-conforming, because the `flush` , `barrier` , `taskwait` , and `taskyield` directives are stand-alone directives and cannot be the action statement of an `if` statement or a labeled branch target. " + " The following example is non-conforming, because the `flush` , `barrier` , `taskwait` , and `taskyield` directives are stand-alone directives and cannot be the action statement of an `if` statement or a labeled branch target." ] }, { @@ -43,14 +43,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_standalone.1.f90 " + "%load ../sources/Example_standalone.1.f90" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following version of the above example is conforming because the `flush` , `barrier` , `taskwait` , and `taskyield` directives are enclosed in a compound statement. " + " The following version of the above example is conforming because the `flush` , `barrier` , `taskwait` , and `taskyield` directives are enclosed in a compound statement. " ] }, { @@ -59,14 +59,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_standalone.2.c " + "%load ../sources/Example_standalone.2.c" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example is conforming because the `flush` , `barrier` , `taskwait` , and `taskyield` directives are enclosed in an `if` construct or follow the labeled branch target. " + " The following example is conforming because the `flush` , `barrier` , `taskwait` , and `taskyield` directives are enclosed in an `if` construct or follow the labeled branch target." ] }, { @@ -75,14 +75,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_standalone.2.f90 " + "%load ../sources/Example_standalone.2.f90" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---end--- " + "---end---" ] } ], @@ -100,4 +100,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/notebook/Examples_target.ipynb b/notebook/Examples_target.ipynb index f8c034e..21343ae 100644 --- a/notebook/Examples_target.ipynb +++ b/notebook/Examples_target.ipynb @@ -4,21 +4,21 @@ "cell_type": "markdown", "metadata": {}, "source": [ - " ### `target` Construct " + " ### `target` Construct" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " #### `target` Construct on `parallel` Construct " + " #### `target` Construct on `parallel` Construct" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " This following example shows how the `target` construct offloads a code region to a target device. The variables _p_ , _v1_ , _v2_ , and _N_ are implicitly mapped to the target device. " + " This following example shows how the `target` construct offloads a code region to a target device. The variables _p_ , _v1_ , _v2_ , and _N_ are implicitly mapped to the target device." ] }, { @@ -27,7 +27,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_target.1.c " + "%load ../sources/Example_target.1.c" ] }, { @@ -36,21 +36,21 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_target.1.f90 " + "%load ../sources/Example_target.1.f90" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " #### `target` Construct with `map` Clause " + " #### `target` Construct with `map` Clause" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " This following example shows how the `target` construct offloads a code region to a target device. The variables _p_ , _v1_ and _v2_ are explicitly mapped to the target device using the `map` clause. The variable _N_ is implicitly mapped to the target device. " + " This following example shows how the `target` construct offloads a code region to a target device. The variables _p_ , _v1_ and _v2_ are explicitly mapped to the target device using the `map` clause. The variable _N_ is implicitly mapped to the target device." ] }, { @@ -59,7 +59,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_target.2.c " + "%load ../sources/Example_target.2.c" ] }, { @@ -68,35 +68,35 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_target.2.f90 " + "%load ../sources/Example_target.2.f90" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " #### `map` Clause with `to` / `from` map-types " + " #### `map` Clause with `to` / `from` map-types" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example shows how the `target` construct offloads a code region to a target device. In the `map` clause, the `to` and `from` map-types define the mapping between the original (host) data and the target (device) data. The `to` map-type specifies that the data will only be read on the device, and the `from` map-type specifies that the data will only be written to on the device. By specifying a guaranteed access on the device, data transfers can be reduced for the `target` region. " + " The following example shows how the `target` construct offloads a code region to a target device. In the `map` clause, the `to` and `from` map-types define the mapping between the original (host) data and the target (device) data. The `to` map-type specifies that the data will only be read on the device, and the `from` map-type specifies that the data will only be written to on the device. By specifying a guaranteed access on the device, data transfers can be reduced for the `target` region." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The `to` map-type indicates that at the start of the `target` region the variables _v1_ and _v2_ are initialized with the values of the corresponding variables on the host device, and at the end of the `target` region the variables _v1_ and _v2_ are not assigned to their corresponding variables on the host device. " + " The `to` map-type indicates that at the start of the `target` region the variables _v1_ and _v2_ are initialized with the values of the corresponding variables on the host device, and at the end of the `target` region the variables _v1_ and _v2_ are not assigned to their corresponding variables on the host device." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The `from` map-type indicates that at the start of the `target` region the variable _p_ is not initialized with the value of the corresponding variable on the host device, and at the end of the `target` region the variable _p_ is assigned to the corresponding variable on the host device. " + " The `from` map-type indicates that at the start of the `target` region the variable _p_ is not initialized with the value of the corresponding variable on the host device, and at the end of the `target` region the variable _p_ is assigned to the corresponding variable on the host device." ] }, { @@ -105,14 +105,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_target.3.c " + "%load ../sources/Example_target.3.c" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The `to` and `from` map-types allow programmers to optimize data motion. Since data for the _v_ arrays are not returned, and data for the _p_ array are not transferred to the device, only one-half of the data is moved, compared to the default behavior of an implicit mapping. " + " The `to` and `from` map-types allow programmers to optimize data motion. Since data for the _v_ arrays are not returned, and data for the _p_ array are not transferred to the device, only one-half of the data is moved, compared to the default behavior of an implicit mapping." ] }, { @@ -121,21 +121,21 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_target.3.f90 " + "%load ../sources/Example_target.3.f90" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " #### `map` Clause with Array Sections " + " #### `map` Clause with Array Sections" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example shows how the `target` construct offloads a code region to a target device. In the `map` clause, map-types are used to optimize the mapping of variables to the target device. Because variables _p_ , _v1_ and _v2_ are pointers, array section notation must be used to map the arrays. The notation `:N` is equivalent to `0:N` . " + " The following example shows how the `target` construct offloads a code region to a target device. In the `map` clause, map-types are used to optimize the mapping of variables to the target device. Because variables _p_ , _v1_ and _v2_ are pointers, array section notation must be used to map the arrays. The notation `:N` is equivalent to `0:N` ." ] }, { @@ -144,14 +144,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_target.4.c " + "%load ../sources/Example_target.4.c" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " In C, the length of the pointed-to array must be specified. In Fortran the extent of the array is known and the length need not be specified. A section of the array can be specified with the usual Fortran syntax, as shown in the following example. The value 1 is assumed for the lower bound for array section _v2(:N)_ . " + " In C, the length of the pointed-to array must be specified. In Fortran the extent of the array is known and the length need not be specified. A section of the array can be specified with the usual Fortran syntax, as shown in the following example. The value 1 is assumed for the lower bound for array section _v2(:N)_ ." ] }, { @@ -160,14 +160,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_target.4.f90 " + "%load ../sources/Example_target.4.f90" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " A more realistic situation in which an assumed-size array is passed to `vec_mult` requires that the length of the arrays be specified, because the compiler does not know the size of the storage. A section of the array must be specified with the usual Fortran syntax, as shown in the following example. The value 1 is assumed for the lower bound for array section _v2(:N)_ . " + " A more realistic situation in which an assumed-size array is passed to `vec_mult` requires that the length of the arrays be specified, because the compiler does not know the size of the storage. A section of the array must be specified with the usual Fortran syntax, as shown in the following example. The value 1 is assumed for the lower bound for array section _v2(:N)_ ." ] }, { @@ -176,35 +176,35 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_target.4b.f90 " + "%load ../sources/Example_target.4b.f90" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " #### `target` Construct with `if` Clause " + " #### `target` Construct with `if` Clause" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example shows how the `target` construct offloads a code region to a target device. " + " The following example shows how the `target` construct offloads a code region to a target device." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The `if` clause on the `target` construct indicates that if the variable _N_ is smaller than a given threshold, then the `target` region will be executed by the host device. " + " The `if` clause on the `target` construct indicates that if the variable _N_ is smaller than a given threshold, then the `target` region will be executed by the host device." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The `if` clause on the `parallel` construct indicates that if the variable _N_ is smaller than a second threshold then the `parallel` region is inactive. " + " The `if` clause on the `parallel` construct indicates that if the variable _N_ is smaller than a second threshold then the `parallel` region is inactive." ] }, { @@ -213,7 +213,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_target.5.c " + "%load ../sources/Example_target.5.c" ] }, { @@ -222,21 +222,21 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_target.5.f90 " + "%load ../sources/Example_target.5.f90" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example is a modification of the above _target.5_ code to show the combined `target` and parallel loop directives. It uses the _directive-name_ modifier in multiple `if` clauses to specify the component directive to which it applies. " + " The following example is a modification of the above _target.5_ code to show the combined `target` and parallel loop directives. It uses the _directive-name_ modifier in multiple `if` clauses to specify the component directive to which it applies. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The `if` clause with the `target` modifier applies to the `target` component of the combined directive, and the `if` clause with the `parallel` modifier applies to the `parallel` component of the combined directive. " + " The `if` clause with the `target` modifier applies to the `target` component of the combined directive, and the `if` clause with the `parallel` modifier applies to the `parallel` component of the combined directive. " ] }, { @@ -245,7 +245,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_target.6.c " + "%load ../sources/Example_target.6.c" ] }, { @@ -254,14 +254,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_target.6.f90 " + "%load ../sources/Example_target.6.f90" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---end--- " + "---end---" ] } ], @@ -279,4 +279,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/notebook/Examples_target_data.ipynb b/notebook/Examples_target_data.ipynb index dbb090e..384c6a2 100644 --- a/notebook/Examples_target_data.ipynb +++ b/notebook/Examples_target_data.ipynb @@ -4,21 +4,21 @@ "cell_type": "markdown", "metadata": {}, "source": [ - " ### `target` `data` Construct " + " ### `target` `data` Construct" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " #### Simple `target` `data` Construct " + " #### Simple `target` `data` Construct" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " This example shows how the `target` `data` construct maps variables to a device data environment. The `target` `data` construct creates a new device data environment and maps the variables _v1_ , _v2_ , and _p_ to the new device data environment. The `target` construct enclosed in the `target` `data` region creates a new device data environment, which inherits the variables _v1_ , _v2_ , and _p_ from the enclosing device data environment. The variable _N_ is mapped into the new device data environment from the encountering task's data environment. " + " This example shows how the `target` `data` construct maps variables to a device data environment. The `target` `data` construct creates a new device data environment and maps the variables _v1_ , _v2_ , and _p_ to the new device data environment. The `target` construct enclosed in the `target` `data` region creates a new device data environment, which inherits the variables _v1_ , _v2_ , and _p_ from the enclosing device data environment. The variable _N_ is mapped into the new device data environment from the encountering task's data environment." ] }, { @@ -27,14 +27,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_target_data.1.c " + "%load ../sources/Example_target_data.1.c" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The Fortran code passes a reference and specifies the extent of the arrays in the declaration. No length information is necessary in the map clause, as is required with C/C++ pointers. " + " The Fortran code passes a reference and specifies the extent of the arrays in the declaration. No length information is necessary in the map clause, as is required with C/C++ pointers." ] }, { @@ -43,28 +43,28 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_target_data.1.f90 " + "%load ../sources/Example_target_data.1.f90" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " #### `target` `data` Region Enclosing Multiple `target` Regions " + " #### `target` `data` Region Enclosing Multiple `target` Regions" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following examples show how the `target` `data` construct maps variables to a device data environment of a `target` region. The `target` `data` construct creates a device data environment and encloses `target` regions, which have their own device data environments. The device data environment of the `target` `data` region is inherited by the device data environment of an enclosed `target` region. The `target` `data` construct is used to create variables that will persist throughout the `target` `data` region. " + " The following examples show how the `target` `data` construct maps variables to a device data environment of a `target` region. The `target` `data` construct creates a device data environment and encloses `target` regions, which have their own device data environments. The device data environment of the `target` `data` region is inherited by the device data environment of an enclosed `target` region. The `target` `data` construct is used to create variables that will persist throughout the `target` `data` region." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " In the following example the variables _v1_ and _v2_ are mapped at each `target` construct. Instead of mapping the variable _p_ twice, once at each `target` construct, _p_ is mapped once by the `target` `data` construct. " + " In the following example the variables _v1_ and _v2_ are mapped at each `target` construct. Instead of mapping the variable _p_ twice, once at each `target` construct, _p_ is mapped once by the `target` `data` construct." ] }, { @@ -73,14 +73,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_target_data.2.c " + "%load ../sources/Example_target_data.2.c" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The Fortran code uses reference and specifies the extent of the _p_ , _v1_ and _v2_ arrays. No length information is necessary in the `map` clause, as is required with C/C++ pointers. The arrays _v1_ and _v2_ are mapped at each `target` construct. Instead of mapping the array _p_ twice, once at each target construct, _p_ is mapped once by the `target` `data` construct. " + " The Fortran code uses reference and specifies the extent of the _p_ , _v1_ and _v2_ arrays. No length information is necessary in the `map` clause, as is required with C/C++ pointers. The arrays _v1_ and _v2_ are mapped at each `target` construct. Instead of mapping the array _p_ twice, once at each target construct, _p_ is mapped once by the `target` `data` construct." ] }, { @@ -89,14 +89,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_target_data.2.f90 " + "%load ../sources/Example_target_data.2.f90" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " In the following example, the variable tmp defaults to `tofrom` map-type and is mapped at each `target` construct. The array _Q_ is mapped once at the enclosing `target` `data` region instead of at each `target` construct. " + " In the following example, the variable tmp defaults to `tofrom` map-type and is mapped at each `target` construct. The array _Q_ is mapped once at the enclosing `target` `data` region instead of at each `target` construct. " ] }, { @@ -105,14 +105,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_target_data.3.c " + "%load ../sources/Example_target_data.3.c" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " In the following example the arrays _v1_ and _v2_ are mapped at each `target` construct. Instead of mapping the array _Q_ twice at each `target` construct, _Q_ is mapped once by the `target` `data` construct. Note, the _tmp_ variable is implicitly remapped for each `target` region, mapping the value from the device to the host at the end of the first `target` region, and from the host to the device for the second `target` region. " + " In the following example the arrays _v1_ and _v2_ are mapped at each `target` construct. Instead of mapping the array _Q_ twice at each `target` construct, _Q_ is mapped once by the `target` `data` construct. Note, the _tmp_ variable is implicitly remapped for each `target` region, mapping the value from the device to the host at the end of the first `target` region, and from the host to the device for the second `target` region." ] }, { @@ -121,42 +121,42 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_target_data.3.f90 " + "%load ../sources/Example_target_data.3.f90" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " #### `target` `data` Construct with Orphaned Call " + " #### `target` `data` Construct with Orphaned Call" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following two examples show how the `target` `data` construct maps variables to a device data environment. The `target` `data` construct's device data environment encloses the `target` construct's device data environment in the function `vec_mult()` . " + " The following two examples show how the `target` `data` construct maps variables to a device data environment. The `target` `data` construct's device data environment encloses the `target` construct's device data environment in the function `vec_mult()` ." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " When the type of the variable appearing in an array section is pointer, the pointer variable and the storage location of the corresponding array section are mapped to the device data environment. The pointer variable is treated as if it had appeared in a `map` clause with a map-type of `alloc` . The array section's storage location is mapped according to the map-type in the `map` clause (the default map-type is `tofrom` ). " + " When the type of the variable appearing in an array section is pointer, the pointer variable and the storage location of the corresponding array section are mapped to the device data environment. The pointer variable is treated as if it had appeared in a `map` clause with a map-type of `alloc` . The array section's storage location is mapped according to the map-type in the `map` clause (the default map-type is `tofrom` )." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The `target` construct's device data environment inherits the storage locations of the array sections _v1[0:N]_ , _v2[:n]_ , and _p0[0:N]_ from the enclosing target data construct's device data environment. Neither initialization nor assignment is performed for the array sections in the new device data environment. " + " The `target` construct's device data environment inherits the storage locations of the array sections _v1[0:N]_ , _v2[:n]_ , and _p0[0:N]_ from the enclosing target data construct's device data environment. Neither initialization nor assignment is performed for the array sections in the new device data environment." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The pointer variables _p1_ , _v3_ , and _v4_ are mapped into the target construct's device data environment with an implicit map-type of alloc and they are assigned the address of the storage location associated with their corresponding array sections. Note that the following pairs of array section storage locations are equivalent ( _p0[:N]_ , _p1[:N]_ ), ( _v1[:N]_ , _v3[:N]_ ), and ( _v2[:N]_ , _v4[:N]_ ). " + " The pointer variables _p1_ , _v3_ , and _v4_ are mapped into the target construct's device data environment with an implicit map-type of alloc and they are assigned the address of the storage location associated with their corresponding array sections. Note that the following pairs of array section storage locations are equivalent ( _p0[:N]_ , _p1[:N]_ ), ( _v1[:N]_ , _v3[:N]_ ), and ( _v2[:N]_ , _v4[:N]_ )." ] }, { @@ -165,28 +165,28 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_target_data.4.c " + "%load ../sources/Example_target_data.4.c" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The Fortran code maps the pointers and storage in an identical manner (same extent, but uses indices from 1 to _N_ ). " + " The Fortran code maps the pointers and storage in an identical manner (same extent, but uses indices from 1 to _N_ )." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The `target` construct's device data environment inherits the storage locations of the arrays _v1_ , _v2_ and _p0_ from the enclosing `target` `data` constructs's device data environment. However, in Fortran the associated data of the pointer is known, and the shape is not required. " + " The `target` construct's device data environment inherits the storage locations of the arrays _v1_ , _v2_ and _p0_ from the enclosing `target` `data` constructs's device data environment. However, in Fortran the associated data of the pointer is known, and the shape is not required." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The pointer variables _p1_ , _v3_ , and _v4_ are mapped into the `target` construct's device data environment with an implicit map-type of `alloc` and they are assigned the address of the storage location associated with their corresponding array sections. Note that the following pair of array storage locations are equivalent ( _p0_ , _p1_ ), ( _v1_ , _v3_ ), and ( _v2_ , _v4_ ). " + " The pointer variables _p1_ , _v3_ , and _v4_ are mapped into the `target` construct's device data environment with an implicit map-type of `alloc` and they are assigned the address of the storage location associated with their corresponding array sections. Note that the following pair of array storage locations are equivalent ( _p0_ , _p1_ ), ( _v1_ , _v3_ ), and ( _v2_ , _v4_ )." ] }, { @@ -195,14 +195,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_target_data.4.f90 " + "%load ../sources/Example_target_data.4.f90" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " In the following example, the variables _p1_ , _v3_ , and _v4_ are references to the pointer variables _p0_ , _v1_ and _v2_ respectively. The `target` construct's device data environment inherits the pointer variables _p0_ , _v1_ , and _v2_ from the enclosing `target` `data` construct's device data environment. Thus, _p1_ , _v3_ , and _v4_ are already present in the device data environment. " + " In the following example, the variables _p1_ , _v3_ , and _v4_ are references to the pointer variables _p0_ , _v1_ and _v2_ respectively. The `target` construct's device data environment inherits the pointer variables _p0_ , _v1_ , and _v2_ from the enclosing `target` `data` construct's device data environment. Thus, _p1_ , _v3_ , and _v4_ are already present in the device data environment." ] }, { @@ -211,14 +211,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_target_data.5.cpp " + "%load ../sources/Example_target_data.5.cpp" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " In the following example, the usual Fortran approach is used for dynamic memory. The _p0_ , _v1_ , and _v2_ arrays are allocated in the main program and passed as references from one routine to another. In `vec_mult` , _p1_ , _v3_ and _v4_ are references to the _p0_ , _v1_ , and _v2_ arrays, respectively. The `target` construct's device data environment inherits the arrays _p0_ , _v1_ , and _v2_ from the enclosing target data construct's device data environment. Thus, _p1_ , _v3_ , and _v4_ are already present in the device data environment. " + " In the following example, the usual Fortran approach is used for dynamic memory. The _p0_ , _v1_ , and _v2_ arrays are allocated in the main program and passed as references from one routine to another. In `vec_mult` , _p1_ , _v3_ and _v4_ are references to the _p0_ , _v1_ , and _v2_ arrays, respectively. The `target` construct's device data environment inherits the arrays _p0_ , _v1_ , and _v2_ from the enclosing target data construct's device data environment. Thus, _p1_ , _v3_ , and _v4_ are already present in the device data environment." ] }, { @@ -227,35 +227,35 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_target_data.5.f90 " + "%load ../sources/Example_target_data.5.f90" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " #### `target` `data` Construct with `if` Clause " + " #### `target` `data` Construct with `if` Clause" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following two examples show how the `target` `data` construct maps variables to a device data environment. " + " The following two examples show how the `target` `data` construct maps variables to a device data environment." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " In the following example, the if clause on the `target` `data` construct indicates that if the variable _N_ is smaller than a given threshold, then the `target` `data` construct will not create a device data environment. " + " In the following example, the if clause on the `target` `data` construct indicates that if the variable _N_ is smaller than a given threshold, then the `target` `data` construct will not create a device data environment." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The `target` constructs enclosed in the `target` `data` region must also use an `if` clause on the same condition, otherwise the pointer variable _p_ is implicitly mapped with a map-type of `tofrom` , but the storage location for the array section _p[0:N]_ will not be mapped in the device data environments of the `target` constructs. " + " The `target` constructs enclosed in the `target` `data` region must also use an `if` clause on the same condition, otherwise the pointer variable _p_ is implicitly mapped with a map-type of `tofrom` , but the storage location for the array section _p[0:N]_ will not be mapped in the device data environments of the `target` constructs." ] }, { @@ -264,14 +264,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_target_data.6.c " + "%load ../sources/Example_target_data.6.c" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The `if` clauses work the same way for the following Fortran code. The `target` constructs enclosed in the `target` `data` region should also use an `if` clause with the same condition, so that the `target` `data` region and the `target` region are either both created for the device, or are both ignored. " + " The `if` clauses work the same way for the following Fortran code. The `target` constructs enclosed in the `target` `data` region should also use an `if` clause with the same condition, so that the `target` `data` region and the `target` region are either both created for the device, or are both ignored." ] }, { @@ -280,14 +280,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_target_data.6.f90 " + "%load ../sources/Example_target_data.6.f90" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " In the following example, when the `if` clause conditional expression on the `target` construct evaluates to _false_ , the target region will execute on the host device. However, the `target` `data` construct created an enclosing device data environment that mapped _p[0:N]_ to a device data environment on the default device. At the end of the `target` `data` region the array section _p[0:N]_ will be assigned from the device data environment to the corresponding variable in the data environment of the task that encountered the `target` `data` construct, resulting in undefined values in _p[0:N]_ . " + " In the following example, when the `if` clause conditional expression on the `target` construct evaluates to _false_ , the target region will execute on the host device. However, the `target` `data` construct created an enclosing device data environment that mapped _p[0:N]_ to a device data environment on the default device. At the end of the `target` `data` region the array section _p[0:N]_ will be assigned from the device data environment to the corresponding variable in the data environment of the task that encountered the `target` `data` construct, resulting in undefined values in _p[0:N]_ ." ] }, { @@ -296,14 +296,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_target_data.7.c " + "%load ../sources/Example_target_data.7.c" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The `if` clauses work the same way for the following Fortran code. When the `if` clause conditional expression on the `target` construct evaluates to _false_ , the `target` region will execute on the host device. However, the `target` `data` construct created an enclosing device data environment that mapped the _p_ array (and _v1_ and _v2_ ) to a device data environment on the default target device. At the end of the `target` `data` region the _p_ array will be assigned from the device data environment to the corresponding variable in the data environment of the task that encountered the `target` `data` construct, resulting in undefined values in _p_ . " + " The `if` clauses work the same way for the following Fortran code. When the `if` clause conditional expression on the `target` construct evaluates to _false_ , the `target` region will execute on the host device. However, the `target` `data` construct created an enclosing device data environment that mapped the _p_ array (and _v1_ and _v2_ ) to a device data environment on the default target device. At the end of the `target` `data` region the _p_ array will be assigned from the device data environment to the corresponding variable in the data environment of the task that encountered the `target` `data` construct, resulting in undefined values in _p_ ." ] }, { @@ -312,14 +312,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_target_data.7.f90 " + "%load ../sources/Example_target_data.7.f90" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---end--- " + "---end---" ] } ], @@ -337,4 +337,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/notebook/Examples_target_unstructured_data.ipynb b/notebook/Examples_target_unstructured_data.ipynb index f28f0ce..5cbc42a 100644 --- a/notebook/Examples_target_unstructured_data.ipynb +++ b/notebook/Examples_target_unstructured_data.ipynb @@ -5,14 +5,14 @@ "metadata": {}, "source": [ " \n", -"begin " +"begin " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " ### `target` `enter` `data` and `target` `exit` `data` Constructs " + " ### `target` `enter` `data` and `target` `exit` `data` Constructs" ] }, { @@ -20,28 +20,28 @@ "metadata": {}, "source": [ " \n", -" ### Simple target enter data and target exit data Constructs " +" ### Simple target enter data and target exit data Constructs" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The structured data construct ( `target` ~ `data` ) provides persistent data on a device for subsequent `target` constructs as shown in the `target` ~ `data` examples above. This is accomplished by creating a single `target` ~ `data` region containing `target` constructs. " + " The structured data construct ( `target` ~ `data` ) provides persistent data on a device for subsequent `target` constructs as shown in the `target` ~ `data` examples above. This is accomplished by creating a single `target` ~ `data` region containing `target` constructs." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The unstructured data constructs allow the creation and deletion of data on the device at any appropriate point within the host code, as shown below with the `target` ~ `enter` ~ `data` and `target` ~ `exit` ~ `data` constructs. " + " The unstructured data constructs allow the creation and deletion of data on the device at any appropriate point within the host code, as shown below with the `target` ~ `enter` ~ `data` and `target` ~ `exit` ~ `data` constructs." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following C++ code creates/deletes a vector in a constructor/destructor of a class. The constructor creates a vector with `target` ~ `enter` ~ `data` and uses an `alloc` modifier in the `map` clause to avoid copying values to the device. The destructor deletes the data ( `target` ~ `exit` ~ `data` ) and uses the `delete` modifier in the `map` clause to avoid copying data back to the host. Note, the stand-alone `target` ~ `enter` ~ `data` occurs after the host vector is created, and the `target` ~ `exit` ~ `data` construct occurs before the host data is deleted. " + " The following C++ code creates/deletes a vector in a constructor/destructor of a class. The constructor creates a vector with `target` ~ `enter` ~ `data` and uses an `alloc` modifier in the `map` clause to avoid copying values to the device. The destructor deletes the data ( `target` ~ `exit` ~ `data` ) and uses the `delete` modifier in the `map` clause to avoid copying data back to the host. Note, the stand-alone `target` ~ `enter` ~ `data` occurs after the host vector is created, and the `target` ~ `exit` ~ `data` construct occurs before the host data is deleted." ] }, { @@ -50,14 +50,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_target_unstructured_data.1.cpp " + "%load ../sources/Example_target_unstructured_data.1.cpp" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following C code allocates and frees the data member of a Matrix structure. The `init_matrix` function allocates the memory used in the structure and uses the `target` ~ `enter` ~ `data` directive to map it to the target device. The `free_matrix` function removes the mapped array from the target device and then frees the memory on the host. Note, the stand-alone `target` ~ `enter` ~ `data` occurs after the host memory is allocated, and the `target` ~ `exit` ~ `data` construct occurs before the host data is freed. " + " The following C code allocates and frees the data member of a Matrix structure. The `init_matrix` function allocates the memory used in the structure and uses the `target` ~ `enter` ~ `data` directive to map it to the target device. The `free_matrix` function removes the mapped array from the target device and then frees the memory on the host. Note, the stand-alone `target` ~ `enter` ~ `data` occurs after the host memory is allocated, and the `target` ~ `exit` ~ `data` construct occurs before the host data is freed." ] }, { @@ -66,14 +66,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_target_unstructured_data.1.c " + "%load ../sources/Example_target_unstructured_data.1.c" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following Fortran code allocates and deallocates a module array. The `initialize` subroutine allocates the module array and uses the `target` ~ `enter` ~ `data` directive to map it to the target device. The `finalize` subroutine removes the mapped array from the target device and then deallocates the array on the host. Note, the stand-alone `target` ~ `enter` ~ `data` occurs after the host memory is allocated, and the `target` ~ `exit` ~ `data` construct occurs before the host data is deallocated. " + " The following Fortran code allocates and deallocates a module array. The `initialize` subroutine allocates the module array and uses the `target` ~ `enter` ~ `data` directive to map it to the target device. The `finalize` subroutine removes the mapped array from the target device and then deallocates the array on the host. Note, the stand-alone `target` ~ `enter` ~ `data` occurs after the host memory is allocated, and the `target` ~ `exit` ~ `data` construct occurs before the host data is deallocated." ] }, { @@ -82,7 +82,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_target_unstructured_data.1.f90 " + "%load ../sources/Example_target_unstructured_data.1.f90" ] }, { @@ -90,14 +90,14 @@ "metadata": {}, "source": [ " \n", -"end " +"end" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---end--- " + "---end---" ] } ], @@ -115,4 +115,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/notebook/Examples_target_update.ipynb b/notebook/Examples_target_update.ipynb index 967ac89..88d14cb 100644 --- a/notebook/Examples_target_update.ipynb +++ b/notebook/Examples_target_update.ipynb @@ -4,63 +4,63 @@ "cell_type": "markdown", "metadata": {}, "source": [ - " ### `target` `update` Construct " + " ### `target` `update` Construct" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " #### Simple `target` `data` and `target` `update` Constructs " + " #### Simple `target` `data` and `target` `update` Constructs" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example shows how the `target` `update` construct updates variables in a device data environment. " + " The following example shows how the `target` `update` construct updates variables in a device data environment." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The `target` `data` construct maps array sections _v1[:N]_ and _v2[:N]_ (arrays _v1_ and _v2_ in the Fortran code) into a device data environment. " + " The `target` `data` construct maps array sections _v1[:N]_ and _v2[:N]_ (arrays _v1_ and _v2_ in the Fortran code) into a device data environment." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The task executing on the host device encounters the first `target` region and waits for the completion of the region. " + " The task executing on the host device encounters the first `target` region and waits for the completion of the region." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " After the execution of the first `target` region, the task executing on the host device then assigns new values to _v1[:N]_ and _v2[:N]_ ( _v1_ and _v2_ arrays in Fortran code) in the task's data environment by calling the function `init_again()` . " + " After the execution of the first `target` region, the task executing on the host device then assigns new values to _v1[:N]_ and _v2[:N]_ ( _v1_ and _v2_ arrays in Fortran code) in the task's data environment by calling the function `init_again()` ." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The `target` `update` construct assigns the new values of _v1_ and _v2_ from the task's data environment to the corresponding mapped array sections in the device data environment of the `target` `data` construct. " + " The `target` `update` construct assigns the new values of _v1_ and _v2_ from the task's data environment to the corresponding mapped array sections in the device data environment of the `target` `data` construct." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The task executing on the host device then encounters the second `target` region and waits for the completion of the region. " + " The task executing on the host device then encounters the second `target` region and waits for the completion of the region." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The second `target` region uses the updated values of _v1[:N]_ and _v2[:N]_ . " + " The second `target` region uses the updated values of _v1[:N]_ and _v2[:N]_ ." ] }, { @@ -69,7 +69,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_target_update.1.c " + "%load ../sources/Example_target_update.1.c" ] }, { @@ -78,35 +78,35 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_target_update.1.f90 " + "%load ../sources/Example_target_update.1.f90" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " #### `target` `update` Construct with `if` Clause " + " #### `target` `update` Construct with `if` Clause" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example shows how the `target` `update` construct updates variables in a device data environment. " + " The following example shows how the `target` `update` construct updates variables in a device data environment." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The `target` `data` construct maps array sections _v1[:N]_ and _v2[:N]_ (arrays _v1_ and _v2_ in the Fortran code) into a device data environment. In between the two `target` regions, the task executing on the host device conditionally assigns new values to _v1_ and _v2_ in the task's data environment. The function `maybe_init_again()` returns _true_ if new data is written. " + " The `target` `data` construct maps array sections _v1[:N]_ and _v2[:N]_ (arrays _v1_ and _v2_ in the Fortran code) into a device data environment. In between the two `target` regions, the task executing on the host device conditionally assigns new values to _v1_ and _v2_ in the task's data environment. The function `maybe_init_again()` returns _true_ if new data is written." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " When the conditional expression (the return value of `maybe_init_again()` ) in the `if` clause is _true_ , the `target` `update` construct assigns the new values of _v1_ and _v2_ from the task's data environment to the corresponding mapped array sections in the `target` `data` construct's device data environment. " + " When the conditional expression (the return value of `maybe_init_again()` ) in the `if` clause is _true_ , the `target` `update` construct assigns the new values of _v1_ and _v2_ from the task's data environment to the corresponding mapped array sections in the `target` `data` construct's device data environment." ] }, { @@ -115,7 +115,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_target_update.2.c " + "%load ../sources/Example_target_update.2.c" ] }, { @@ -124,14 +124,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_target_update.2.f90 " + "%load ../sources/Example_target_update.2.f90" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---end--- " + "---end---" ] } ], @@ -149,4 +149,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/notebook/Examples_task_dep.ipynb b/notebook/Examples_task_dep.ipynb index 11bbedf..6b90c93 100644 --- a/notebook/Examples_task_dep.ipynb +++ b/notebook/Examples_task_dep.ipynb @@ -4,21 +4,21 @@ "cell_type": "markdown", "metadata": {}, "source": [ - " ### Task Dependences " + " ### Task Dependences" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " #### Flow Dependence " + " #### Flow Dependence" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " In this example we show a simple flow dependence expressed using the `depend` clause on the `task` construct. " + " In this example we show a simple flow dependence expressed using the `depend` clause on the `task` construct." ] }, { @@ -27,7 +27,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_task_dep.1.c " + "%load ../sources/Example_task_dep.1.c" ] }, { @@ -36,28 +36,28 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_task_dep.1.f90 " + "%load ../sources/Example_task_dep.1.f90" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The program will always print ' x = 2 ' , because the `depend` clauses enforce the ordering of the tasks. If the `depend` clauses had been omitted, then the tasks could execute in any order and the program and the program would have a race condition. " + " The program will always print ' x = 2 ' , because the `depend` clauses enforce the ordering of the tasks. If the `depend` clauses had been omitted, then the tasks could execute in any order and the program and the program would have a race condition." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " #### Anti-dependence " + " #### Anti-dependence" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " In this example we show an anti-dependence expressed using the `depend` clause on the `task` construct. " + " In this example we show an anti-dependence expressed using the `depend` clause on the `task` construct." ] }, { @@ -66,7 +66,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_task_dep.2.c " + "%load ../sources/Example_task_dep.2.c" ] }, { @@ -75,28 +75,28 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_task_dep.2.f90 " + "%load ../sources/Example_task_dep.2.f90" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The program will always print ' x = 1 ' , because the `depend` clauses enforce the ordering of the tasks. If the `depend` clauses had been omitted, then the tasks could execute in any order and the program would have a race condition. " + " The program will always print ' x = 1 ' , because the `depend` clauses enforce the ordering of the tasks. If the `depend` clauses had been omitted, then the tasks could execute in any order and the program would have a race condition." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " #### Output Dependence " + " #### Output Dependence" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " In this example we show an output dependence expressed using the `depend` clause on the `task` construct. " + " In this example we show an output dependence expressed using the `depend` clause on the `task` construct." ] }, { @@ -105,7 +105,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_task_dep.3.c " + "%load ../sources/Example_task_dep.3.c" ] }, { @@ -114,28 +114,28 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_task_dep.3.f90 " + "%load ../sources/Example_task_dep.3.f90" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The program will always print ' x = 2 ' , because the `depend` clauses enforce the ordering of the tasks. If the `depend` clauses had been omitted, then the tasks could execute in any order and the program would have a race condition. " + " The program will always print ' x = 2 ' , because the `depend` clauses enforce the ordering of the tasks. If the `depend` clauses had been omitted, then the tasks could execute in any order and the program would have a race condition." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " #### Concurrent Execution with Dependences " + " #### Concurrent Execution with Dependences" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " In this example we show potentially concurrent execution of tasks using multiple flow dependences expressed using the `depend` clause on the `task` construct. " + " In this example we show potentially concurrent execution of tasks using multiple flow dependences expressed using the `depend` clause on the `task` construct." ] }, { @@ -144,7 +144,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_task_dep.4.c " + "%load ../sources/Example_task_dep.4.c" ] }, { @@ -153,28 +153,28 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_task_dep.4.f90 " + "%load ../sources/Example_task_dep.4.f90" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The last two tasks are dependent on the first task. However there is no dependence between the last two tasks, which may execute in any order (or concurrently if more than one thread is available). Thus, the possible outputs are ' x + 1 = 3. x + 2 = 4. ' and ' x + 2 = 4. x + 1 = 3. ' . If the `depend` clauses had been omitted, then all of the tasks could execute in any order and the program would have a race condition. " + " The last two tasks are dependent on the first task. However there is no dependence between the last two tasks, which may execute in any order (or concurrently if more than one thread is available). Thus, the possible outputs are ' x + 1 = 3. x + 2 = 4. ' and ' x + 2 = 4. x + 1 = 3. ' . If the `depend` clauses had been omitted, then all of the tasks could execute in any order and the program would have a race condition." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " #### Matrix multiplication " + " #### Matrix multiplication" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " This example shows a task-based blocked matrix multiplication. Matrices are of NxN elements, and the multiplication is implemented using blocks of BSxBS elements. " + " This example shows a task-based blocked matrix multiplication. Matrices are of NxN elements, and the multiplication is implemented using blocks of BSxBS elements." ] }, { @@ -183,7 +183,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_task_dep.5.c " + "%load ../sources/Example_task_dep.5.c" ] }, { @@ -192,14 +192,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_task_dep.5.f90 " + "%load ../sources/Example_task_dep.5.f90" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---end--- " + "---end---" ] } ], @@ -217,4 +217,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/notebook/Examples_task_priority.ipynb b/notebook/Examples_task_priority.ipynb index 4b63587..583b55f 100644 --- a/notebook/Examples_task_priority.ipynb +++ b/notebook/Examples_task_priority.ipynb @@ -4,7 +4,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - " ### Task Priority " + " ### Task Priority" ] }, { @@ -13,21 +13,21 @@ "source": [ " \n", " #### Task Priority \n", -" " +"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " In this example we compute arrays in a matrix through a _compute_array_ routine. Each task has a priority value equal to the value of the loop variable _i_ at the moment of its creation. A higher priority on a task means that a task is a candidate to run sooner. " + " In this example we compute arrays in a matrix through a _compute_array_ routine. Each task has a priority value equal to the value of the loop variable _i_ at the moment of its creation. A higher priority on a task means that a task is a candidate to run sooner." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The creation of tasks occurs in ascending order (according to the iteration space of the loop) but a hint, by means of the `priority` clause, is provided to reverse the execution order. " + " The creation of tasks occurs in ascending order (according to the iteration space of the loop) but a hint, by means of the `priority` clause, is provided to reverse the execution order." ] }, { @@ -36,7 +36,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_task_priority.1.c " + "%load ../sources/Example_task_priority.1.c" ] }, { @@ -45,14 +45,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_task_priority.1.f90 " + "%load ../sources/Example_task_priority.1.f90" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---end--- " + "---end---" ] } ], @@ -70,4 +70,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/notebook/Examples_taskgroup.ipynb b/notebook/Examples_taskgroup.ipynb index 06654c2..49a993e 100644 --- a/notebook/Examples_taskgroup.ipynb +++ b/notebook/Examples_taskgroup.ipynb @@ -4,21 +4,21 @@ "cell_type": "markdown", "metadata": {}, "source": [ - " ### The `taskgroup` Construct " + " ### The `taskgroup` Construct" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " In this example, tasks are grouped and synchronized using the `taskgroup` construct. " + " In this example, tasks are grouped and synchronized using the `taskgroup` construct." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " Initially, one task (the task executing the `start_background_work()` call) is created in the `parallel` region, and later a parallel tree traversal is started (the task executing the root of the recursive `compute_tree()` calls). While synchronizing tasks at the end of each tree traversal, using the `taskgroup` construct ensures that the formerly started background task does not participate in the synchronization, and is left free to execute in parallel. This is opposed to the behaviour of the `taskwait` construct, which would include the background tasks in the synchronization. " + " Initially, one task (the task executing the `start_background_work()` call) is created in the `parallel` region, and later a parallel tree traversal is started (the task executing the root of the recursive `compute_tree()` calls). While synchronizing tasks at the end of each tree traversal, using the `taskgroup` construct ensures that the formerly started background task does not participate in the synchronization, and is left free to execute in parallel. This is opposed to the behaviour of the `taskwait` construct, which would include the background tasks in the synchronization." ] }, { @@ -27,7 +27,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_taskgroup.1.c " + "%load ../sources/Example_taskgroup.1.c" ] }, { @@ -36,14 +36,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_taskgroup.1.f90 " + "%load ../sources/Example_taskgroup.1.f90" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---end--- " + "---end---" ] } ], @@ -61,4 +61,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/notebook/Examples_tasking.ipynb b/notebook/Examples_tasking.ipynb index 13c10c5..6594e18 100644 --- a/notebook/Examples_tasking.ipynb +++ b/notebook/Examples_tasking.ipynb @@ -4,14 +4,14 @@ "cell_type": "markdown", "metadata": {}, "source": [ - " ### The `task` and `taskwait` Constructs " + " ### The `task` and `taskwait` Constructs" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example shows how to traverse a tree-like structure using explicit tasks. Note that the `traverse` function should be called from within a parallel region for the different specified tasks to be executed in parallel. Also note that the tasks will be executed in no specified order because there are no synchronization directives. Thus, assuming that the traversal will be done in post order, as in the sequential code, is wrong. " + " The following example shows how to traverse a tree-like structure using explicit tasks. Note that the `traverse` function should be called from within a parallel region for the different specified tasks to be executed in parallel. Also note that the tasks will be executed in no specified order because there are no synchronization directives. Thus, assuming that the traversal will be done in post order, as in the sequential code, is wrong." ] }, { @@ -20,7 +20,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_tasking.1.c " + "%load ../sources/Example_tasking.1.c" ] }, { @@ -29,14 +29,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_tasking.1.f90 " + "%load ../sources/Example_tasking.1.f90" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " In the next example, we force a postorder traversal of the tree by adding a `taskwait` directive. Now, we can safely assume that the left and right sons have been executed before we process the current node. " + " In the next example, we force a postorder traversal of the tree by adding a `taskwait` directive. Now, we can safely assume that the left and right sons have been executed before we process the current node." ] }, { @@ -45,7 +45,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_tasking.2.c " + "%load ../sources/Example_tasking.2.c" ] }, { @@ -54,14 +54,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_tasking.2.f90 " + "%load ../sources/Example_tasking.2.f90" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example demonstrates how to use the `task` construct to process elements of a linked list in parallel. The thread executing the `single` region generates all of the explicit tasks, which are then executed by the threads in the current team. The pointer _p_ is `firstprivate` by default on the `task` construct so it is not necessary to specify it in a `firstprivate` clause. " + " The following example demonstrates how to use the `task` construct to process elements of a linked list in parallel. The thread executing the `single` region generates all of the explicit tasks, which are then executed by the threads in the current team. The pointer _p_ is `firstprivate` by default on the `task` construct so it is not necessary to specify it in a `firstprivate` clause." ] }, { @@ -70,7 +70,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_tasking.3.c " + "%load ../sources/Example_tasking.3.c" ] }, { @@ -79,14 +79,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_tasking.3.f90 " + "%load ../sources/Example_tasking.3.f90" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The `fib()` function should be called from within a `parallel` region for the different specified tasks to be executed in parallel. Also, only one thread of the `parallel` region should call `fib()` unless multiple concurrent Fibonacci computations are desired. " + " The `fib()` function should be called from within a `parallel` region for the different specified tasks to be executed in parallel. Also, only one thread of the `parallel` region should call `fib()` unless multiple concurrent Fibonacci computations are desired. " ] }, { @@ -95,7 +95,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_tasking.4.c " + "%load ../sources/Example_tasking.4.c" ] }, { @@ -104,21 +104,21 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_tasking.4.f " + "%load ../sources/Example_tasking.4.f" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " Note: There are more efficient algorithms for computing Fibonacci numbers. This classic recursion algorithm is for illustrative purposes. " + " Note: There are more efficient algorithms for computing Fibonacci numbers. This classic recursion algorithm is for illustrative purposes." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example demonstrates a way to generate a large number of tasks with one thread and execute them with the threads in the team. While generating these tasks, the implementation may reach its limit on unassigned tasks. If it does, the implementation is allowed to cause the thread executing the task generating loop to suspend its task at the task scheduling point in the `task` directive, and start executing unassigned tasks. Once the number of unassigned tasks is sufficiently low, the thread may resume execution of the task generating loop. " + " The following example demonstrates a way to generate a large number of tasks with one thread and execute them with the threads in the team. While generating these tasks, the implementation may reach its limit on unassigned tasks. If it does, the implementation is allowed to cause the thread executing the task generating loop to suspend its task at the task scheduling point in the `task` directive, and start executing unassigned tasks. Once the number of unassigned tasks is sufficiently low, the thread may resume execution of the task generating loop." ] }, { @@ -127,7 +127,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_tasking.5.c " + "%load ../sources/Example_tasking.5.c" ] }, { @@ -136,21 +136,21 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_tasking.5.f " + "%load ../sources/Example_tasking.5.f" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example is the same as the previous one, except that the tasks are generated in an untied task. While generating the tasks, the implementation may reach its limit on unassigned tasks. If it does, the implementation is allowed to cause the thread executing the task generating loop to suspend its task at the task scheduling point in the `task` directive, and start executing unassigned tasks. If that thread begins execution of a task that takes a long time to complete, the other threads may complete all the other tasks before it is finished. " + " The following example is the same as the previous one, except that the tasks are generated in an untied task. While generating the tasks, the implementation may reach its limit on unassigned tasks. If it does, the implementation is allowed to cause the thread executing the task generating loop to suspend its task at the task scheduling point in the `task` directive, and start executing unassigned tasks. If that thread begins execution of a task that takes a long time to complete, the other threads may complete all the other tasks before it is finished." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " In this case, since the loop is in an untied task, any other thread is eligible to resume the task generating loop. In the previous examples, the other threads would be forced to idle until the generating thread finishes its long task, since the task generating loop was in a tied task. " + " In this case, since the loop is in an untied task, any other thread is eligible to resume the task generating loop. In the previous examples, the other threads would be forced to idle until the generating thread finishes its long task, since the task generating loop was in a tied task." ] }, { @@ -159,7 +159,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_tasking.6.c " + "%load ../sources/Example_tasking.6.c" ] }, { @@ -168,21 +168,21 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_tasking.6.f " + "%load ../sources/Example_tasking.6.f" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following two examples demonstrate how the scheduling rules illustrated in Section 2.11.3 of the OpenMP 4.0 specification affect the usage of `threadprivate` variables in tasks. A `threadprivate` variable can be modified by another task that is executed by the same thread. Thus, the value of a `threadprivate` variable cannot be assumed to be unchanged across a task scheduling point. In untied tasks, task scheduling points may be added in any place by the implementation. " + " The following two examples demonstrate how the scheduling rules illustrated in Section 2.11.3 of the OpenMP 4.0 specification affect the usage of `threadprivate` variables in tasks. A `threadprivate` variable can be modified by another task that is executed by the same thread. Thus, the value of a `threadprivate` variable cannot be assumed to be unchanged across a task scheduling point. In untied tasks, task scheduling points may be added in any place by the implementation." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " A task switch may occur at a task scheduling point. A single thread may execute both of the task regions that modify `tp` . The parts of these task regions in which `tp` is modified may be executed in any order so the resulting value of `var` can be either 1 or 2. " + " A task switch may occur at a task scheduling point. A single thread may execute both of the task regions that modify `tp` . The parts of these task regions in which `tp` is modified may be executed in any order so the resulting value of `var` can be either 1 or 2." ] }, { @@ -191,7 +191,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_tasking.7.c " + "%load ../sources/Example_tasking.7.c" ] }, { @@ -200,14 +200,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_tasking.7.f " + "%load ../sources/Example_tasking.7.f" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " In this example, scheduling constraints prohibit a thread in the team from executing a new task that modifies `tp` while another such task region tied to the same thread is suspended. Therefore, the value written will persist across the task scheduling point. " + " In this example, scheduling constraints prohibit a thread in the team from executing a new task that modifies `tp` while another such task region tied to the same thread is suspended. Therefore, the value written will persist across the task scheduling point." ] }, { @@ -216,7 +216,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_tasking.8.c " + "%load ../sources/Example_tasking.8.c" ] }, { @@ -225,21 +225,21 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_tasking.8.f " + "%load ../sources/Example_tasking.8.f" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following two examples demonstrate how the scheduling rules illustrated in Section 2.11.3 of the OpenMP 4.0 specification affect the usage of locks and critical sections in tasks. If a lock is held across a task scheduling point, no attempt should be made to acquire the same lock in any code that may be interleaved. Otherwise, a deadlock is possible. " + " The following two examples demonstrate how the scheduling rules illustrated in Section 2.11.3 of the OpenMP 4.0 specification affect the usage of locks and critical sections in tasks. If a lock is held across a task scheduling point, no attempt should be made to acquire the same lock in any code that may be interleaved. Otherwise, a deadlock is possible." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " In the example below, suppose the thread executing task 1 defers task 2. When it encounters the task scheduling point at task 3, it could suspend task 1 and begin task 2 which will result in a deadlock when it tries to enter critical region 1. " + " In the example below, suppose the thread executing task 1 defers task 2. When it encounters the task scheduling point at task 3, it could suspend task 1 and begin task 2 which will result in a deadlock when it tries to enter critical region 1." ] }, { @@ -248,7 +248,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_tasking.9.c " + "%load ../sources/Example_tasking.9.c" ] }, { @@ -257,14 +257,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_tasking.9.f " + "%load ../sources/Example_tasking.9.f" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " In the following example, `lock` is held across a task scheduling point. However, according to the scheduling restrictions, the executing thread can't begin executing one of the non-descendant tasks that also acquires `lock` before the task region is complete. Therefore, no deadlock is possible. " + " In the following example, `lock` is held across a task scheduling point. However, according to the scheduling restrictions, the executing thread can't begin executing one of the non-descendant tasks that also acquires `lock` before the task region is complete. Therefore, no deadlock is possible." ] }, { @@ -273,7 +273,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_tasking.10.c " + "%load ../sources/Example_tasking.10.c" ] }, { @@ -282,14 +282,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_tasking.10.f90 " + "%load ../sources/Example_tasking.10.f90" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following examples illustrate the use of the `mergeable` clause in the `task` construct. In this first example, the `task` construct has been annotated with the `mergeable` clause. The addition of this clause allows the implementation to reuse the data environment (including the ICVs) of the parent task for the task inside `foo` if the task is included or undeferred. Thus, the result of the execution may differ depending on whether the task is merged or not. Therefore the mergeable clause needs to be used with caution. In this example, the use of the mergeable clause is safe. As `x` is a shared variable the outcome does not depend on whether or not the task is merged (that is, the task will always increment the same variable and will always compute the same value for `x` ). " + " The following examples illustrate the use of the `mergeable` clause in the `task` construct. In this first example, the `task` construct has been annotated with the `mergeable` clause. The addition of this clause allows the implementation to reuse the data environment (including the ICVs) of the parent task for the task inside `foo` if the task is included or undeferred. Thus, the result of the execution may differ depending on whether the task is merged or not. Therefore the mergeable clause needs to be used with caution. In this example, the use of the mergeable clause is safe. As `x` is a shared variable the outcome does not depend on whether or not the task is merged (that is, the task will always increment the same variable and will always compute the same value for `x` )." ] }, { @@ -298,7 +298,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_tasking.11.c " + "%load ../sources/Example_tasking.11.c" ] }, { @@ -307,14 +307,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_tasking.11.f90 " + "%load ../sources/Example_tasking.11.f90" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " This second example shows an incorrect use of the `mergeable` clause. In this example, the created task will access different instances of the variable `x` if the task is not merged, as `x` is `firstprivate` , but it will access the same variable `x` if the task is merged. As a result, the behavior of the program is unspecified and it can print two different values for `x` depending on the decisions taken by the implementation. " + " This second example shows an incorrect use of the `mergeable` clause. In this example, the created task will access different instances of the variable `x` if the task is not merged, as `x` is `firstprivate` , but it will access the same variable `x` if the task is merged. As a result, the behavior of the program is unspecified and it can print two different values for `x` depending on the decisions taken by the implementation." ] }, { @@ -323,7 +323,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_tasking.12.c " + "%load ../sources/Example_tasking.12.c" ] }, { @@ -332,21 +332,21 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_tasking.12.f90 " + "%load ../sources/Example_tasking.12.f90" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example shows the use of the `final` clause and the `omp_in_final` API call in a recursive binary search program. To reduce overhead, once a certain depth of recursion is reached the program uses the `final` clause to create only included tasks, which allow additional optimizations. " + " The following example shows the use of the `final` clause and the `omp_in_final` API call in a recursive binary search program. To reduce overhead, once a certain depth of recursion is reached the program uses the `final` clause to create only included tasks, which allow additional optimizations." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The use of the `omp_in_final` API call allows programmers to optimize their code by specifying which parts of the program are not necessary when a task can create only included tasks (that is, the code is inside a `final` task). In this example, the use of a different state variable is not necessary so once the program reaches the part of the computation that is finalized and copying from the parent state to the new state is eliminated. The allocation of `new_state` in the stack could also be avoided but it would make this example less clear. The `final` clause is most effective when used in conjunction with the `mergeable` clause since all tasks created in a `final` task region are included tasks that can be merged if the `mergeable` clause is present. " + " The use of the `omp_in_final` API call allows programmers to optimize their code by specifying which parts of the program are not necessary when a task can create only included tasks (that is, the code is inside a `final` task). In this example, the use of a different state variable is not necessary so once the program reaches the part of the computation that is finalized and copying from the parent state to the new state is eliminated. The allocation of `new_state` in the stack could also be avoided but it would make this example less clear. The `final` clause is most effective when used in conjunction with the `mergeable` clause since all tasks created in a `final` task region are included tasks that can be merged if the `mergeable` clause is present." ] }, { @@ -355,7 +355,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_tasking.13.c " + "%load ../sources/Example_tasking.13.c" ] }, { @@ -364,14 +364,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_tasking.13.f90 " + "%load ../sources/Example_tasking.13.f90" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example illustrates the difference between the `if` and the `final` clauses. The `if` clause has a local effect. In the first nest of tasks, the one that has the `if` clause will be undeferred but the task nested inside that task will not be affected by the `if` clause and will be created as usual. Alternatively, the `final` clause affects all `task` constructs in the `final` task region but not the `final` task itself. In the second nest of tasks, the nested tasks will be created as included tasks. Note also that the conditions for the `if` and `final` clauses are usually the opposite. " + " The following example illustrates the difference between the `if` and the `final` clauses. The `if` clause has a local effect. In the first nest of tasks, the one that has the `if` clause will be undeferred but the task nested inside that task will not be affected by the `if` clause and will be created as usual. Alternatively, the `final` clause affects all `task` constructs in the `final` task region but not the `final` task itself. In the second nest of tasks, the nested tasks will be created as included tasks. Note also that the conditions for the `if` and `final` clauses are usually the opposite." ] }, { @@ -380,7 +380,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_tasking.14.c " + "%load ../sources/Example_tasking.14.c" ] }, { @@ -389,14 +389,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_tasking.14.f90 " + "%load ../sources/Example_tasking.14.f90" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---end--- " + "---end---" ] } ], @@ -414,4 +414,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/notebook/Examples_taskloop.ipynb b/notebook/Examples_taskloop.ipynb index e37d41e..ea3861c 100644 --- a/notebook/Examples_taskloop.ipynb +++ b/notebook/Examples_taskloop.ipynb @@ -4,42 +4,42 @@ "cell_type": "markdown", "metadata": {}, "source": [ - " " + " " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " ### The `taskloop` Construct " + " ### The `taskloop` Construct " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " " + " " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example illustrates how to execute a long running task concurrently with tasks created with a `taskloop` directive for a loop having unbalanced amounts of work for its iterations. The `grainsize` clause specifies that each task is to execute at least 500 iterations of the loop. The `nogroup` clause removes the implicit taskgroup of the `taskloop` construct; the explicit `taskgroup` construct in the example ensures that the function is not exited before the long-running task and the loops have finished execution. cexample{taskloop}{1} " + " The following example illustrates how to execute a long running task concurrently with tasks created with a `taskloop` directive for a loop having unbalanced amounts of work for its iterations. The `grainsize` clause specifies that each task is to execute at least 500 iterations of the loop. The `nogroup` clause removes the implicit taskgroup of the `taskloop` construct; the explicit `taskgroup` construct in the example ensures that the function is not exited before the long-running task and the loops have finished execution. cexample{taskloop}{1} " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " ffreeexample{taskloop}{1} " + " ffreeexample{taskloop}{1} " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---end--- " + "---end---" ] } ], @@ -57,4 +57,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/notebook/Examples_taskyield.ipynb b/notebook/Examples_taskyield.ipynb index 4a6abd4..7e2e812 100644 --- a/notebook/Examples_taskyield.ipynb +++ b/notebook/Examples_taskyield.ipynb @@ -4,14 +4,14 @@ "cell_type": "markdown", "metadata": {}, "source": [ - " ### The `taskyield` Construct " + " ### The `taskyield` Construct" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example illustrates the use of the `taskyield` directive. The tasks in the example compute something useful and then do some computation that must be done in a critical region. By using `taskyield` when a task cannot get access to the `critical` region the implementation can suspend the current task and schedule some other task that can do something useful. " + " The following example illustrates the use of the `taskyield` directive. The tasks in the example compute something useful and then do some computation that must be done in a critical region. By using `taskyield` when a task cannot get access to the `critical` region the implementation can suspend the current task and schedule some other task that can do something useful. " ] }, { @@ -20,7 +20,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_taskyield.1.c " + "%load ../sources/Example_taskyield.1.c" ] }, { @@ -29,14 +29,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_taskyield.1.f90 " + "%load ../sources/Example_taskyield.1.f90" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---end--- " + "---end---" ] } ], @@ -54,4 +54,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/notebook/Examples_teams.ipynb b/notebook/Examples_teams.ipynb index 0ea7046..720ef7c 100644 --- a/notebook/Examples_teams.ipynb +++ b/notebook/Examples_teams.ipynb @@ -4,35 +4,35 @@ "cell_type": "markdown", "metadata": {}, "source": [ - " ### `teams` Constructs " + " ### `teams` Constructs" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "subsection{ `target` and `teams` Constructs with `omp_get_num_teams` " + "subsection{ `target` and `teams` Constructs with `omp_get_num_teams` " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " and `omp_get_team_num` Routines} " + " and `omp_get_team_num` Routines}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example shows how the `target` and `teams` constructs are used to create a league of thread teams that execute a region. The `teams` construct creates a league of at most two teams where the master thread of each team executes the `teams` region. " + " The following example shows how the `target` and `teams` constructs are used to create a league of thread teams that execute a region. The `teams` construct creates a league of at most two teams where the master thread of each team executes the `teams` region." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The `omp_get_num_teams` routine returns the number of teams executing in a `teams` region. The `omp_get_team_num` routine returns the team number, which is an integer between 0 and one less than the value returned by `omp_get_num_teams` . The following example manually distributes a loop across two teams. " + " The `omp_get_num_teams` routine returns the number of teams executing in a `teams` region. The `omp_get_team_num` routine returns the team number, which is an integer between 0 and one less than the value returned by `omp_get_num_teams` . The following example manually distributes a loop across two teams." ] }, { @@ -41,7 +41,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_teams.1.c " + "%load ../sources/Example_teams.1.c" ] }, { @@ -50,42 +50,42 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_teams.1.f90 " + "%load ../sources/Example_teams.1.f90" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " #### `target` , `teams` , and `distribute` Constructs " + " #### `target` , `teams` , and `distribute` Constructs" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example shows how the `target` , `teams` , and `distribute` constructs are used to execute a loop nest in a `target` region. The `teams` construct creates a league and the master thread of each team executes the `teams` region. The `distribute` construct schedules the subsequent loop iterations across the master threads of each team. " + " The following example shows how the `target` , `teams` , and `distribute` constructs are used to execute a loop nest in a `target` region. The `teams` construct creates a league and the master thread of each team executes the `teams` region. The `distribute` construct schedules the subsequent loop iterations across the master threads of each team." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The number of teams in the league is less than or equal to the variable _num_blocks_ . Each team in the league has a number of threads less than or equal to the variable _block_threads_ . The iterations in the outer loop are distributed among the master threads of each team. " + " The number of teams in the league is less than or equal to the variable _num_blocks_ . Each team in the league has a number of threads less than or equal to the variable _block_threads_ . The iterations in the outer loop are distributed among the master threads of each team." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " When a team's master thread encounters the parallel loop construct before the inner loop, the other threads in its team are activated. The team executes the `parallel` region and then workshares the execution of the loop. " + " When a team's master thread encounters the parallel loop construct before the inner loop, the other threads in its team are activated. The team executes the `parallel` region and then workshares the execution of the loop." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " Each master thread executing the `teams` region has a private copy of the variable _sum_ that is created by the `reduction` clause on the `teams` construct. The master thread and all threads in its team have a private copy of the variable _sum_ that is created by the `reduction` clause on the parallel loop construct. The second private _sum_ is reduced into the master thread's private copy of _sum_ created by the `teams` construct. At the end of the `teams` region, each master thread's private copy of _sum_ is reduced into the final _sum_ that is implicitly mapped into the `target` region. " + " Each master thread executing the `teams` region has a private copy of the variable _sum_ that is created by the `reduction` clause on the `teams` construct. The master thread and all threads in its team have a private copy of the variable _sum_ that is created by the `reduction` clause on the parallel loop construct. The second private _sum_ is reduced into the master thread's private copy of _sum_ created by the `teams` construct. At the end of the `teams` region, each master thread's private copy of _sum_ is reduced into the final _sum_ that is implicitly mapped into the `target` region." ] }, { @@ -94,7 +94,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_teams.2.c " + "%load ../sources/Example_teams.2.c" ] }, { @@ -103,28 +103,28 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_teams.2.f90 " + "%load ../sources/Example_teams.2.f90" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " #### `target` `teams` , and Distribute Parallel Loop Constructs " + " #### `target` `teams` , and Distribute Parallel Loop Constructs" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example shows how the `target` `teams` and distribute parallel loop constructs are used to execute a `target` region. The `target` `teams` construct creates a league of teams where the master thread of each team executes the `teams` region. " + " The following example shows how the `target` `teams` and distribute parallel loop constructs are used to execute a `target` region. The `target` `teams` construct creates a league of teams where the master thread of each team executes the `teams` region." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The distribute parallel loop construct schedules the loop iterations across the master threads of each team and then across the threads of each team. " + " The distribute parallel loop construct schedules the loop iterations across the master threads of each team and then across the threads of each team." ] }, { @@ -133,7 +133,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_teams.3.c " + "%load ../sources/Example_teams.3.c" ] }, { @@ -142,49 +142,49 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_teams.3.f90 " + "%load ../sources/Example_teams.3.f90" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "subsection{ `target` `teams` and Distribute Parallel Loop " + "subsection{ `target` `teams` and Distribute Parallel Loop " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " Constructs with Scheduling Clauses} " + " Constructs with Scheduling Clauses}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example shows how the `target` `teams` and distribute parallel loop constructs are used to execute a `target` region. The `teams` construct creates a league of at most eight teams where the master thread of each team executes the `teams` region. The number of threads in each team is less than or equal to 16. " + " The following example shows how the `target` `teams` and distribute parallel loop constructs are used to execute a `target` region. The `teams` construct creates a league of at most eight teams where the master thread of each team executes the `teams` region. The number of threads in each team is less than or equal to 16." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The `distribute` parallel loop construct schedules the subsequent loop iterations across the master threads of each team and then across the threads of each team. " + " The `distribute` parallel loop construct schedules the subsequent loop iterations across the master threads of each team and then across the threads of each team." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The `dist_schedule` clause on the distribute parallel loop construct indicates that loop iterations are distributed to the master thread of each team in chunks of 1024 iterations. " + " The `dist_schedule` clause on the distribute parallel loop construct indicates that loop iterations are distributed to the master thread of each team in chunks of 1024 iterations." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The `schedule` clause indicates that the 1024 iterations distributed to a master thread are then assigned to the threads in its associated team in chunks of 64 iterations. " + " The `schedule` clause indicates that the 1024 iterations distributed to a master thread are then assigned to the threads in its associated team in chunks of 64 iterations." ] }, { @@ -193,7 +193,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_teams.4.c " + "%load ../sources/Example_teams.4.c" ] }, { @@ -202,28 +202,28 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_teams.4.f90 " + "%load ../sources/Example_teams.4.f90" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " #### `target` `teams` and `distribute` `simd` Constructs " + " #### `target` `teams` and `distribute` `simd` Constructs" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example shows how the `target` `teams` and `distribute` `simd` constructs are used to execute a loop in a `target` region. The `target` `teams` construct creates a league of teams where the master thread of each team executes the `teams` region. " + " The following example shows how the `target` `teams` and `distribute` `simd` constructs are used to execute a loop in a `target` region. The `target` `teams` construct creates a league of teams where the master thread of each team executes the `teams` region." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The `distribute` `simd` construct schedules the loop iterations across the master thread of each team and then uses SIMD parallelism to execute the iterations. " + " The `distribute` `simd` construct schedules the loop iterations across the master thread of each team and then uses SIMD parallelism to execute the iterations." ] }, { @@ -232,7 +232,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_teams.5.c " + "%load ../sources/Example_teams.5.c" ] }, { @@ -241,28 +241,28 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_teams.5.f90 " + "%load ../sources/Example_teams.5.f90" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " #### `target` `teams` and Distribute Parallel Loop SIMD Constructs " + " #### `target` `teams` and Distribute Parallel Loop SIMD Constructs" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example shows how the `target` `teams` and the distribute parallel loop SIMD constructs are used to execute a loop in a `target` `teams` region. The `target` `teams` construct creates a league of teams where the master thread of each team executes the `teams` region. " + " The following example shows how the `target` `teams` and the distribute parallel loop SIMD constructs are used to execute a loop in a `target` `teams` region. The `target` `teams` construct creates a league of teams where the master thread of each team executes the `teams` region." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The distribute parallel loop SIMD construct schedules the loop iterations across the master thread of each team and then across the threads of each team where each thread uses SIMD parallelism. " + " The distribute parallel loop SIMD construct schedules the loop iterations across the master thread of each team and then across the threads of each team where each thread uses SIMD parallelism." ] }, { @@ -271,7 +271,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_teams.6.c " + "%load ../sources/Example_teams.6.c" ] }, { @@ -280,14 +280,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_teams.6.f90 " + "%load ../sources/Example_teams.6.f90" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---end--- " + "---end---" ] } ], @@ -305,4 +305,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/notebook/Examples_threadprivate.ipynb b/notebook/Examples_threadprivate.ipynb index a67a907..a1b53df 100644 --- a/notebook/Examples_threadprivate.ipynb +++ b/notebook/Examples_threadprivate.ipynb @@ -4,14 +4,14 @@ "cell_type": "markdown", "metadata": {}, "source": [ - " ### The `threadprivate` Directive " + " ### The `threadprivate` Directive" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following examples demonstrate how to use the `threadprivate` directive to give each thread a separate counter. " + " The following examples demonstrate how to use the `threadprivate` directive to give each thread a separate counter." ] }, { @@ -20,7 +20,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_threadprivate.1.c " + "%load ../sources/Example_threadprivate.1.c" ] }, { @@ -29,14 +29,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_threadprivate.1.f " + "%load ../sources/Example_threadprivate.1.f" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " ccppspecificstart The following example uses `threadprivate` on a static variable: " + " ccppspecificstart The following example uses `threadprivate` on a static variable:" ] }, { @@ -45,14 +45,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_threadprivate.2.c " + "%load ../sources/Example_threadprivate.2.c" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example demonstrates unspecified behavior for the initialization of a `threadprivate` variable. A `threadprivate` variable is initialized once at an unspecified point before its first reference. Because `a` is constructed using the value of `x` (which is modified by the statement `x++` ), the value of `a.val` at the start of the `parallel` region could be either 1 or 2. This problem is avoided for `b` , which uses an auxiliary `const` variable and a copy-constructor. " + " The following example demonstrates unspecified behavior for the initialization of a `threadprivate` variable. A `threadprivate` variable is initialized once at an unspecified point before its first reference. Because `a` is constructed using the value of `x` (which is modified by the statement `x++` ), the value of `a.val` at the start of the `parallel` region could be either 1 or 2. This problem is avoided for `b` , which uses an auxiliary `const` variable and a copy-constructor." ] }, { @@ -61,28 +61,28 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_cppnexamplethreadprivate3 " + "%load ../sources/Example_cppnexamplethreadprivate3" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " ccppspecificend " + " ccppspecificend" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following examples show non-conforming uses and correct uses of the `threadprivate` directive. " + " The following examples show non-conforming uses and correct uses of the `threadprivate` directive. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " fortranspecificstart The following example is non-conforming because the common block is not declared local to the subroutine that refers to it: " + " fortranspecificstart The following example is non-conforming because the common block is not declared local to the subroutine that refers to it:" ] }, { @@ -91,14 +91,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_threadprivate.2.f " + "%load ../sources/Example_threadprivate.2.f" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example is also non-conforming because the common block is not declared local to the subroutine that refers to it: " + " The following example is also non-conforming because the common block is not declared local to the subroutine that refers to it:" ] }, { @@ -107,14 +107,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_threadprivate.3.f " + "%load ../sources/Example_threadprivate.3.f" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example is a correct rewrite of the previous example: " + " The following example is a correct rewrite of the previous example:" ] }, { @@ -123,7 +123,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_threadprivate.4.f " + "%load ../sources/Example_threadprivate.4.f" ] }, { @@ -131,7 +131,7 @@ "metadata": {}, "source": [ " The following is an example of the use of `threadprivate` for local variables: \n", -" blue line floater at top of this page for 'Fortran, cont.' [t!] linewitharrows{-1}{dashed}{Fortran (cont.)}{8em} " +" blue line floater at top of this page for 'Fortran, cont.' [t!] linewitharrows{-1}{dashed}{Fortran (cont.)}{8em} " ] }, { @@ -140,49 +140,49 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_threadprivate.5.f " + "%load ../sources/Example_threadprivate.5.f" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The above program, if executed by two threads, will print one of the following two sets of output: " + " The above program, if executed by two threads, will print one of the following two sets of output: " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " `a = 11 12 13` `ptr = 4` `i = 15` " + " `a = 11 12 13` `ptr = 4` `i = 15` " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " `A is not allocated` `ptr = 4` `i = 5` " + " `A is not allocated` `ptr = 4` `i = 5` " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " or " + " or" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " `A is not allocated` `ptr = 4` `i = 15` " + " `A is not allocated` `ptr = 4` `i = 15` " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " `a = 1 2 3` `ptr = 4` `i = 5` " + " `a = 1 2 3` `ptr = 4` `i = 5` " ] }, { @@ -190,7 +190,7 @@ "metadata": {}, "source": [ " The following is an example of the use of `threadprivate` for module variables: \n", -" blue line floater at top of this page for 'Fortran, cont.' [t!] linewitharrows{-1}{dashed}{Fortran (cont.)}{8em} " +" blue line floater at top of this page for 'Fortran, cont.' [t!] linewitharrows{-1}{dashed}{Fortran (cont.)}{8em} " ] }, { @@ -199,14 +199,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_threadprivate.6.f " + "%load ../sources/Example_threadprivate.6.f" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " fortranspecificend " + " fortranspecificend" ] }, { @@ -215,14 +215,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_cppspecificstart " + "%load ../sources/Example_cppspecificstart" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example illustrates initialization of `threadprivate` variables for class-type `T` . `t1` is default constructed, `t2` is constructed taking a constructor accepting one argument of integer type, `t3` is copy constructed with argument `f()` : " + " The following example illustrates initialization of `threadprivate` variables for class-type `T` . `t1` is default constructed, `t2` is constructed taking a constructor accepting one argument of integer type, `t3` is copy constructed with argument `f()` :" ] }, { @@ -231,14 +231,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_cppnexamplethreadprivate4 " + "%load ../sources/Example_cppnexamplethreadprivate4" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example illustrates the use of `threadprivate` for static class members. The `threadprivate` directive for a static class member must be placed inside the class definition. " + " The following example illustrates the use of `threadprivate` for static class members. The `threadprivate` directive for a static class member must be placed inside the class definition." ] }, { @@ -247,7 +247,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_cppnexamplethreadprivate5 " + "%load ../sources/Example_cppnexamplethreadprivate5" ] }, { @@ -256,14 +256,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_cppspecificend " + "%load ../sources/Example_cppspecificend" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---end--- " + "---end---" ] } ], @@ -281,4 +281,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/notebook/Examples_workshare.ipynb b/notebook/Examples_workshare.ipynb index 2ac951a..8ec09e6 100644 --- a/notebook/Examples_workshare.ipynb +++ b/notebook/Examples_workshare.ipynb @@ -4,28 +4,28 @@ "cell_type": "markdown", "metadata": {}, "source": [ - " ### The `workshare` Construct " + " ### The `workshare` Construct" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " fortranspecificstart " + " fortranspecificstart" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following are examples of the `workshare` construct. " + " The following are examples of the `workshare` construct. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " In the following example, `workshare` spreads work across the threads executing the `parallel` region, and there is a barrier after the last statement. Implementations must enforce Fortran execution rules inside of the `workshare` block. " + " In the following example, `workshare` spreads work across the threads executing the `parallel` region, and there is a barrier after the last statement. Implementations must enforce Fortran execution rules inside of the `workshare` block." ] }, { @@ -34,14 +34,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_workshare.1.f " + "%load ../sources/Example_workshare.1.f" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " In the following example, the barrier at the end of the first `workshare` region is eliminated with a `nowait` clause. Threads doing `CC = DD` immediately begin work on `EE = FF` when they are done with `CC = DD` . " + " In the following example, the barrier at the end of the first `workshare` region is eliminated with a `nowait` clause. Threads doing `CC = DD` immediately begin work on `EE = FF` when they are done with `CC = DD` ." ] }, { @@ -50,7 +50,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_workshare.2.f " + "%load ../sources/Example_workshare.2.f" ] }, { @@ -58,14 +58,14 @@ "metadata": {}, "source": [ " \n", -" blue line floater at top of this page for 'Fortran, cont.' [t!] linewitharrows{-1}{dashed}{Fortran (cont.)}{8em} " +" blue line floater at top of this page for 'Fortran, cont.' [t!] linewitharrows{-1}{dashed}{Fortran (cont.)}{8em} " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example shows the use of an `atomic` directive inside a `workshare` construct. The computation of `SUM(AA)` is workshared, but the update to `R` is atomic. " + " The following example shows the use of an `atomic` directive inside a `workshare` construct. The computation of `SUM(AA)` is workshared, but the update to `R` is atomic." ] }, { @@ -74,28 +74,28 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_workshare.3.f " + "%load ../sources/Example_workshare.3.f" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " Fortran `WHERE` and `FORALL` statements are emph{compound statements}, made up of a emph{control} part and a emph{statement} part. When `workshare` is applied to one of these compound statements, both the control and the statement parts are workshared. The following example shows the use of a `WHERE` statement in a `workshare` construct. " + " Fortran `WHERE` and `FORALL` statements are emph{compound statements}, made up of a emph{control} part and a emph{statement} part. When `workshare` is applied to one of these compound statements, both the control and the statement parts are workshared. The following example shows the use of a `WHERE` statement in a `workshare` construct." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " Each task gets worked on in order by the threads: " + " Each task gets worked on in order by the threads:" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " `AA = BB` then `CC = DD` then `EE .ne. 0` then `FF = 1 / EE` then `GG = HH` " + " `AA = BB` then `CC = DD` then `EE .ne. 0` then `FF = 1 / EE` then `GG = HH` " ] }, { @@ -104,7 +104,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_workshare.4.f " + "%load ../sources/Example_workshare.4.f" ] }, { @@ -112,14 +112,14 @@ "metadata": {}, "source": [ " \n", -" blue line floater at top of this page for 'Fortran, cont.' [t!] linewitharrows{-1}{dashed}{Fortran (cont.)}{8em} " +" blue line floater at top of this page for 'Fortran, cont.' [t!] linewitharrows{-1}{dashed}{Fortran (cont.)}{8em} " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " In the following example, an assignment to a shared scalar variable is performed by one thread in a `workshare` while all other threads in the team wait. " + " In the following example, an assignment to a shared scalar variable is performed by one thread in a `workshare` while all other threads in the team wait." ] }, { @@ -128,14 +128,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_workshare.5.f " + "%load ../sources/Example_workshare.5.f" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example contains an assignment to a private scalar variable, which is performed by one thread in a `workshare` while all other threads wait. It is non-conforming because the private scalar variable is undefined after the assignment statement. " + " The following example contains an assignment to a private scalar variable, which is performed by one thread in a `workshare` while all other threads wait. It is non-conforming because the private scalar variable is undefined after the assignment statement. " ] }, { @@ -144,14 +144,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_workshare.6.f " + "%load ../sources/Example_workshare.6.f" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " Fortran execution rules must be enforced inside a `workshare` construct. In the following example, the same result is produced in the following program fragment regardless of whether the code is executed sequentially or inside an OpenMP program with multiple threads: " + " Fortran execution rules must be enforced inside a `workshare` construct. In the following example, the same result is produced in the following program fragment regardless of whether the code is executed sequentially or inside an OpenMP program with multiple threads:" ] }, { @@ -160,21 +160,21 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_workshare.7.f " + "%load ../sources/Example_workshare.7.f" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " fortranspecificend " + " fortranspecificend" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---end--- " + "---end---" ] } ], @@ -192,4 +192,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/notebook/Examples_worksharing_critical.ipynb b/notebook/Examples_worksharing_critical.ipynb index 059ff71..31dcf90 100644 --- a/notebook/Examples_worksharing_critical.ipynb +++ b/notebook/Examples_worksharing_critical.ipynb @@ -4,14 +4,14 @@ "cell_type": "markdown", "metadata": {}, "source": [ - " ### Worksharing Constructs Inside a `critical` Construct " + " ### Worksharing Constructs Inside a `critical` Construct" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The following example demonstrates using a worksharing construct inside a `critical` construct. This example is conforming because the worksharing `single` region is not closely nested inside the `critical` region. A single thread executes the one and only section in the `sections` region, and executes the `critical` region. The same thread encounters the nested `parallel` region, creates a new team of threads, and becomes the master of the new team. One of the threads in the new team enters the `single` region and increments `i` by `1` . At the end of this example `i` is equal to `2` . " + " The following example demonstrates using a worksharing construct inside a `critical` construct. This example is conforming because the worksharing `single` region is not closely nested inside the `critical` region. A single thread executes the one and only section in the `sections` region, and executes the `critical` region. The same thread encounters the nested `parallel` region, creates a new team of threads, and becomes the master of the new team. One of the threads in the new team enters the `single` region and increments `i` by `1` . At the end of this example `i` is equal to `2` ." ] }, { @@ -20,7 +20,7 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_worksharing_critical.1.c " + "%load ../sources/Example_worksharing_critical.1.c" ] }, { @@ -29,14 +29,14 @@ "metadata": {}, "outputs": [], "source": [ - "%load ../sources/Example_worksharing_critical.1.f " + "%load ../sources/Example_worksharing_critical.1.f" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---end--- " + "---end---" ] } ], @@ -54,4 +54,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/notebook/History.ipynb b/notebook/History.ipynb index 495cc6f..89b881a 100644 --- a/notebook/History.ipynb +++ b/notebook/History.ipynb @@ -4,14 +4,14 @@ "cell_type": "markdown", "metadata": {}, "source": [ - " ## Document Revision History " + " ## Document Revision History" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " ### Changes from 4.0.2 to 4.5.0 " + " ### Changes from 4.0.2 to 4.5.0" ] }, { @@ -34,14 +34,14 @@ "* doacross loop nest () \n", "* locks with hints () \n", "* C/C++ array reduction () \n", -"* C++ reference types in data sharing clauses () " +"* C++ reference types in data sharing clauses () " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " ### Changes from 4.0.1 to 4.0.2 " + " ### Changes from 4.0.1 to 4.0.2" ] }, { @@ -52,14 +52,14 @@ "* Names of examples were changed from numbers to mnemonics \n", "* Added SIMD examples () \n", "* Applied miscellaneous fixes in several source codes \n", -"* Added the revision history " +"* Added the revision history " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " ### Changes from 4.0 to 4.0.1 " + " ### Changes from 4.0 to 4.0.1" ] }, { @@ -68,21 +68,21 @@ "source": [ " Added the following new examples: \n", "* the `proc_bind` clause () \n", -"* the `taskgroup` construct () " +"* the `taskgroup` construct () " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " ### Changes from 3.1 to 4.0 " + " ### Changes from 3.1 to 4.0" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " Beginning with OpenMP 4.0, examples were placed in a separate document from the specification document. " + " Beginning with OpenMP 4.0, examples were placed in a separate document from the specification document." ] }, { @@ -100,14 +100,14 @@ "* array sections in device constructs () \n", "* device runtime routines () \n", "* Fortran ASSOCIATE construct () \n", -"* cancellation constructs () " +"* cancellation constructs () " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---end--- " + "---end---" ] } ], @@ -125,4 +125,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/notebook/Introduction_Chapt.ipynb b/notebook/Introduction_Chapt.ipynb index 3d70b55..6e48124 100644 --- a/notebook/Introduction_Chapt.ipynb +++ b/notebook/Introduction_Chapt.ipynb @@ -39,49 +39,49 @@ " Prefer emph{} to italicize terminology, e.g.: \n", " This is a emph{definition}, not a placeholder. \n", " This is a _var-name_ . \n", -" " +"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "chapter*{Introduction} " + "chapter*{Introduction}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " addcontentsline{toc}{chapter}{protectnumberline{}Introduction} This collection of programming examples supplements the OpenMP API for Shared Memory Parallelization specifications, and is not part of the formal specifications. It assumes familiarity with the OpenMP specifications, and shares the typographical conventions used in that document. " + " addcontentsline{toc}{chapter}{protectnumberline{}Introduction} This collection of programming examples supplements the OpenMP API for Shared Memory Parallelization specifications, and is not part of the formal specifications. It assumes familiarity with the OpenMP specifications, and shares the typographical conventions used in that document." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " notestart noteheader – This first release of the OpenMP Examples reflects the OpenMP Version 4.5 specifications. Additional examples are being developed and will be published in future releases of this document. noteend " + " notestart noteheader – This first release of the OpenMP Examples reflects the OpenMP Version 4.5 specifications. Additional examples are being developed and will be published in future releases of this document. noteend" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The OpenMP API specification provides a model for parallel programming that is portable across shared memory architectures from different vendors. Compilers from numerous vendors support the OpenMP API. " + " The OpenMP API specification provides a model for parallel programming that is portable across shared memory architectures from different vendors. Compilers from numerous vendors support the OpenMP API." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The directives, library routines, and environment variables demonstrated in this document allow users to create and manage parallel programs while permitting portability. The directives extend the C, C++ and Fortran base languages with single program multiple data (SPMD) constructs, tasking constructs, device constructs, worksharing constructs, and synchronization constructs, and they provide support for sharing and privatizing data. The functionality to control the runtime environment is provided by library routines and environment variables. Compilers that support the OpenMP API often include a command line option to the compiler that activates and allows interpretation of all OpenMP directives. " + " The directives, library routines, and environment variables demonstrated in this document allow users to create and manage parallel programs while permitting portability. The directives extend the C, C++ and Fortran base languages with single program multiple data (SPMD) constructs, tasking constructs, device constructs, worksharing constructs, and synchronization constructs, and they provide support for sharing and privatizing data. The functionality to control the runtime environment is provided by library routines and environment variables. Compilers that support the OpenMP API often include a command line option to the compiler that activates and allows interpretation of all OpenMP directives." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " The latest source codes for OpenMP Examples can be downloaded from the `sources` directory at https://github.com/OpenMP/Examples The codes for this OpenMP VER{} Examples document have the tag _vVER_ . " + " The latest source codes for OpenMP Examples can be downloaded from the `sources` directory at https://github.com/OpenMP/Examples The codes for this OpenMP VER{} Examples document have the tag _vVER_ ." ] }, { @@ -89,21 +89,21 @@ "metadata": {}, "source": [ " \n", -" https://github.com/OpenMP/Examples/tree/master/sources " +" https://github.com/OpenMP/Examples/tree/master/sources " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " Complete information about the OpenMP API and a list of the compilers that support the OpenMP API can be found at the OpenMP.org web site " + " Complete information about the OpenMP API and a list of the compilers that support the OpenMP API can be found at the OpenMP.org web site" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " `http://www.openmp.org` " + " `http://www.openmp.org` " ] }, { @@ -111,14 +111,14 @@ "metadata": {}, "source": [ " \n", -" This is the end of introduction.tex of the OpenMP Examples document. " +" This is the end of introduction.tex of the OpenMP Examples document." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---end--- " + "---end---" ] } ], @@ -136,4 +136,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/notebook/Title_Page.ipynb b/notebook/Title_Page.ipynb index 39a8d7b..7e48142 100644 --- a/notebook/Title_Page.ipynb +++ b/notebook/Title_Page.ipynb @@ -99,21 +99,21 @@ "\n", "\n", " \n", -" Title page " +" Title page" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " hspace{-6em} includegraphics[width=0.4textwidth]{openmp-logo.png} " + " hspace{-6em} includegraphics[width=0.4textwidth]{openmp-logo.png} " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " {-0.75in}{0in} Huge textsf{OpenMPApplication ProgrammingInterface} " + " {-0.75in}{0in} Huge textsf{OpenMPApplication ProgrammingInterface}" ] }, { @@ -121,21 +121,21 @@ "metadata": {}, "source": [ " \n", -" An optional subtitle can go here: vspace{0.5in}textsf{Examples}vspace{-0.7in} normalsize " +" An optional subtitle can go here: vspace{0.5in}textsf{Examples}vspace{-0.7in} normalsize" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " vspace{1.0in} " + " vspace{1.0in}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " textbf{Version VER{} -- VERDATE} " + " textbf{Version VER{} -- VERDATE} " ] }, { @@ -143,14 +143,14 @@ "metadata": {}, "source": [ " vspace{2.3in} \n", -"was 3.0 " +"was 3.0" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " Source codes for OpenMP VER{} Examples can be downloaded from https://github.com/OpenMP/Examples/tree/vVER {github}. " + " Source codes for OpenMP VER{} Examples can be downloaded from https://github.com/OpenMP/Examples/tree/vVER {github}." ] }, { @@ -158,14 +158,14 @@ "metadata": {}, "source": [ " {0pt}{1em}setlength{parskip}{0.25baselineskip}\n", -" Copyright © 1997-2016 OpenMP Architecture Review Board. Permission to copy without fee all or part of this material is granted, provided the OpenMP Architecture Review Board copyright notice and the title of this document appear. Notice is given that copying is by permission of OpenMP Architecture Review Board. " +" Copyright © 1997-2016 OpenMP Architecture Review Board. Permission to copy without fee all or part of this material is granted, provided the OpenMP Architecture Review Board copyright notice and the title of this document appear. Notice is given that copying is by permission of OpenMP Architecture Review Board." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " " + " " ] }, { @@ -173,14 +173,14 @@ "metadata": {}, "source": [ " \n", -" Blank page " +" Blank page" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " clearpage thispagestyle{empty} phantom{a} emph{This page intentionally left blank} " + " clearpage thispagestyle{empty} phantom{a} emph{This page intentionally left blank}" ] }, { @@ -189,14 +189,14 @@ "source": [ " \n", "This working version enacted the following tickets: 180, 295, 299, 342, 381, \n", -"and a few other editorial changes. vfill " +"and a few other editorial changes. vfill" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---end--- " + "---end---" ] } ], @@ -214,4 +214,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/notebook/openmp-examples.ipynb b/notebook/openmp-examples.ipynb index 6c35158..6af345e 100644 --- a/notebook/openmp-examples.ipynb +++ b/notebook/openmp-examples.ipynb @@ -51,7 +51,7 @@ " Prefer emph{} to italicize terminology, e.g.: \n", " This is a emph{definition}, not a placeholder. \n", " This is a _var-name_ . \n", -" " +"" ] }, { @@ -59,7 +59,7 @@ "metadata": {}, "source": [ " \n", -" The following says letter size, but the style sheet may change the size documentclass[10pt,letterpaper,twoside,makeidx,hidelinks]{scrreprt} " +" The following says letter size, but the style sheet may change the size documentclass[10pt,letterpaper,twoside,makeidx,hidelinks]{scrreprt}" ] }, { @@ -67,7 +67,7 @@ "metadata": {}, "source": [ " \n", -" Text to appear in the footer on even-numbered pages: newcommand{VER}{4.5.0} newcommand{VERDATE}{November 2016} newcommand{footerText}{OpenMP Examples Version VER{} - VERDATE} " +" Text to appear in the footer on even-numbered pages: newcommand{VER}{4.5.0} newcommand{VERDATE}{November 2016} newcommand{footerText}{OpenMP Examples Version VER{} - VERDATE}" ] }, { @@ -75,28 +75,28 @@ "metadata": {}, "source": [ " \n", -" Unified style sheet for OpenMP documents: input{openmp.sty} " +" Unified style sheet for OpenMP documents: input{openmp.sty}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " pagenumbering{roman} input{Title_Page} " + " pagenumbering{roman} input{Title_Page}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " setcounter{page}{0} setcounter{tocdepth}{2} " + " setcounter{page}{0} setcounter{tocdepth}{2}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " {1.3} tableofcontents " + " {1.3} tableofcontents " ] }, { @@ -104,21 +104,21 @@ "metadata": {}, "source": [ " \n", -" Uncomment the next line to enable line numbering on the main body text: linenumberspagewiselinenumbers " +" Uncomment the next line to enable line numbering on the main body text: linenumberspagewiselinenumbers" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " newpagepagenumbering{arabic} " + " newpagepagenumbering{arabic}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " input{Introduction_Chapt} input{Examples_Chapt} " + " input{Introduction_Chapt} input{Examples_Chapt}" ] }, { @@ -126,7 +126,7 @@ "metadata": {}, "source": [ " setcounter{chapter}{0} \n", -" start chapter numbering here " +" start chapter numbering here" ] }, { @@ -134,21 +134,21 @@ "metadata": {}, "source": [ " input{Chap_parallel_execution} input{Examples_ploop} input{Examples_parallel} input{Examples_nthrs_nesting} input{Examples_nthrs_dynamic} input{Examples_fort_do} input{Examples_nowait} input{Examples_collapse} \n", -" linear Clause 475 input{Examples_linear_in_loop} input{Examples_psections} input{Examples_fpriv_sections} input{Examples_single} input{Examples_workshare} input{Examples_master} input{Examples_pra_iterator} input{Examples_set_dynamic_nthrs} input{Examples_get_nthrs} " +" linear Clause 475 input{Examples_linear_in_loop} input{Examples_psections} input{Examples_fpriv_sections} input{Examples_single} input{Examples_workshare} input{Examples_master} input{Examples_pra_iterator} input{Examples_set_dynamic_nthrs} input{Examples_get_nthrs}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " input{Chap_affinity} input{Examples_affinity} input{Examples_affinity_query} " + " input{Chap_affinity} input{Examples_affinity} input{Examples_affinity_query}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " input{Chap_tasking} input{Examples_tasking} input{Examples_task_priority} input{Examples_task_dep} input{Examples_taskgroup} input{Examples_taskyield} input{Examples_taskloop} " + " input{Chap_tasking} input{Examples_tasking} input{Examples_task_priority} input{Examples_task_dep} input{Examples_taskgroup} input{Examples_taskyield} input{Examples_taskloop}" ] }, { @@ -160,7 +160,7 @@ "Title change of 57.1 and 57.2 \n", "New subsection input{Examples_async_target_nowait} input{Examples_async_target_nowait_depend} input{Examples_array_sections} \n", " Structure Element in map 487 input{Examples_device} \n", -" MemoryRoutine and Device ptr 473 " +" MemoryRoutine and Device ptr 473" ] }, { @@ -170,7 +170,7 @@ " input{Chap_SIMD} input{Examples_SIMD} \n", " Forward Depend 370 \n", " simdlen 476 \n", -" simd linear modifier 480 " +" simd linear modifier 480" ] }, { @@ -184,7 +184,7 @@ " \n", " Hint Clause xxxxxx (included after init_lock) \n", " \n", -" Lock routines with hint " +" Lock routines with hint " ] }, { @@ -195,14 +195,14 @@ " User UDR 287 \n", " C array reduction 377 input{Examples_copyin} input{Examples_copyprivate} input{Examples_cpp_reference} \n", " Fortran 2003 features 482 input{Examples_associate} \n", -"section--> subsection " +"section--> subsection" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " input{Chap_memory_model} input{Examples_mem_model} input{Examples_fort_race} " + " input{Chap_memory_model} input{Examples_mem_model} input{Examples_fort_race}" ] }, { @@ -211,7 +211,7 @@ "source": [ " input{Chap_program_control} input{Examples_cond_comp} input{Examples_icv} \n", " If multi-ifs 471 input{Examples_standalone} input{Examples_cancellation} \n", -" New Section Nested Regions input{Examples_nested_loop} input{Examples_nesting_restrict} " +" New Section Nested Regions input{Examples_nested_loop} input{Examples_nesting_restrict}" ] }, { @@ -220,21 +220,21 @@ "source": [ " setcounter{chapter}{0} \n", " restart chapter numbering with 'letter A' renewcommand{thechapter}{Alph{chapter}}\n", -" appendix input{History} " +" appendix input{History}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " " + " " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---end--- " + "---end---" ] } ], @@ -252,4 +252,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/notebook/tex2notebook.py b/notebook/tex2notebook.py index dc77586..57e1135 100644 --- a/notebook/tex2notebook.py +++ b/notebook/tex2notebook.py @@ -30,7 +30,7 @@ ' },\n' + \ ' "nbformat": 4,\n' + \ ' "nbformat_minor": 2\n' + \ - '}\n' + '}' MB = ' {\n' + \ ' "cell_type": "markdown",\n' + \ @@ -46,9 +46,9 @@ ' "source": [\n' + \ ' "' -E = ' "\n ]\n },\n' -E1 = ' \n ]\n },\n' -E2 = ' "\n ]\n }\n' +E = '"\n ]\n },\n' +E1 = '\n ]\n },\n' +E2 = '"\n ]\n }\n' # Do some changes # ilegal symbols From 7edd422f6dcd8e9b99113028a06bef3fd25747ed Mon Sep 17 00:00:00 2001 From: Kewei Yan Date: Tue, 8 Oct 2019 12:09:04 -0400 Subject: [PATCH 12/21] .py updated2 --- notebook/Chap_SIMD.ipynb | 73 -- notebook/Chap_affinity.ipynb | 170 ----- notebook/Chap_data_environment.ipynb | 121 --- notebook/Chap_devices.ipynb | 81 -- notebook/Chap_memory_model.ipynb | 146 ---- notebook/Chap_parallel_execution.ipynb | 165 ---- notebook/Chap_program_control.ipynb | 151 ---- notebook/Chap_synchronization.ipynb | 90 --- notebook/Chap_tasking.ipynb | 75 -- notebook/Examples_Chapt.ipynb | 50 -- notebook/Examples_SIMD.ipynb | 288 ------- notebook/Examples_affinity.ipynb | 705 ------------------ notebook/Examples_affinity_query.ipynb | 85 --- notebook/Examples_array_sections.ipynb | 139 ---- notebook/Examples_associate.ipynb | 94 --- notebook/Examples_async_target_depend.ipynb | 53 -- notebook/Examples_async_target_nowait.ipynb | 78 -- .../Examples_async_target_nowait_depend.ipynb | 80 -- .../Examples_async_target_with_tasks.ipynb | 124 --- notebook/Examples_atomic.ipynb | 121 --- notebook/Examples_atomic_restrict.ipynb | 105 --- notebook/Examples_barrier_regions.ipynb | 71 -- notebook/Examples_cancellation.ipynb | 96 --- notebook/Examples_carrays_fpriv.ipynb | 124 --- notebook/Examples_collapse.ipynb | 149 ---- notebook/Examples_cond_comp.ipynb | 78 -- notebook/Examples_copyin.ipynb | 57 -- notebook/Examples_copyprivate.ipynb | 135 ---- notebook/Examples_cpp_reference.ipynb | 66 -- notebook/Examples_critical.ipynb | 82 -- notebook/Examples_declare_target.ipynb | 326 -------- notebook/Examples_default_none.ipynb | 71 -- notebook/Examples_device.ipynb | 172 ----- notebook/Examples_doacross.ipynb | 139 ---- notebook/Examples_flush_nolist.ipynb | 57 -- notebook/Examples_fort_do.ipynb | 78 -- notebook/Examples_fort_loopvar.ipynb | 78 -- notebook/Examples_fort_race.ipynb | 62 -- notebook/Examples_fort_sa_private.ipynb | 106 --- notebook/Examples_fort_sp_common.ipynb | 141 ---- notebook/Examples_fpriv_sections.ipynb | 57 -- notebook/Examples_get_nthrs.ipynb | 82 -- notebook/Examples_icv.ipynb | 113 --- notebook/Examples_init_lock.ipynb | 57 -- notebook/Examples_init_lock_with_hint.ipynb | 58 -- notebook/Examples_lastprivate.ipynb | 57 -- notebook/Examples_linear_in_loop.ipynb | 57 -- notebook/Examples_lock_owner.ipynb | 64 -- notebook/Examples_locks.ipynb | 39 - notebook/Examples_master.ipynb | 57 -- notebook/Examples_mem_model.ipynb | 114 --- notebook/Examples_nestable_lock.ipynb | 57 -- notebook/Examples_nested_loop.ipynb | 82 -- notebook/Examples_nesting_restrict.ipynb | 189 ----- notebook/Examples_nowait.ipynb | 89 --- notebook/Examples_nthrs_dynamic.ipynb | 96 --- notebook/Examples_nthrs_nesting.ipynb | 57 -- notebook/Examples_ordered.ipynb | 107 --- notebook/Examples_parallel.ipynb | 57 -- notebook/Examples_ploop.ipynb | 57 -- notebook/Examples_pra_iterator.ipynb | 66 -- notebook/Examples_private.ipynb | 110 --- notebook/Examples_psections.ipynb | 57 -- notebook/Examples_reduction.ipynb | 202 ----- notebook/Examples_set_dynamic_nthrs.ipynb | 71 -- notebook/Examples_simple_lock.ipynb | 71 -- notebook/Examples_single.ipynb | 57 -- notebook/Examples_standalone.ipynb | 103 --- notebook/Examples_target.ipynb | 282 ------- notebook/Examples_target_data.ipynb | 340 --------- .../Examples_target_unstructured_data.ipynb | 118 --- notebook/Examples_target_update.ipynb | 152 ---- notebook/Examples_task_dep.ipynb | 220 ------ notebook/Examples_task_priority.ipynb | 73 -- notebook/Examples_taskgroup.ipynb | 64 -- notebook/Examples_tasking.ipynb | 417 ----------- notebook/Examples_taskloop.ipynb | 60 -- notebook/Examples_taskyield.ipynb | 57 -- notebook/Examples_teams.ipynb | 308 -------- notebook/Examples_threadprivate.ipynb | 284 ------- notebook/Examples_workshare.ipynb | 195 ----- notebook/Examples_worksharing_critical.ipynb | 57 -- notebook/History.ipynb | 128 ---- notebook/Introduction_Chapt.ipynb | 139 ---- notebook/Title_Page.ipynb | 217 ------ notebook/openmp-examples.ipynb | 255 ------- 86 files changed, 10731 deletions(-) delete mode 100644 notebook/Chap_SIMD.ipynb delete mode 100644 notebook/Chap_affinity.ipynb delete mode 100644 notebook/Chap_data_environment.ipynb delete mode 100644 notebook/Chap_devices.ipynb delete mode 100644 notebook/Chap_memory_model.ipynb delete mode 100644 notebook/Chap_parallel_execution.ipynb delete mode 100644 notebook/Chap_program_control.ipynb delete mode 100644 notebook/Chap_synchronization.ipynb delete mode 100644 notebook/Chap_tasking.ipynb delete mode 100644 notebook/Examples_Chapt.ipynb delete mode 100644 notebook/Examples_SIMD.ipynb delete mode 100644 notebook/Examples_affinity.ipynb delete mode 100644 notebook/Examples_affinity_query.ipynb delete mode 100644 notebook/Examples_array_sections.ipynb delete mode 100644 notebook/Examples_associate.ipynb delete mode 100644 notebook/Examples_async_target_depend.ipynb delete mode 100644 notebook/Examples_async_target_nowait.ipynb delete mode 100644 notebook/Examples_async_target_nowait_depend.ipynb delete mode 100644 notebook/Examples_async_target_with_tasks.ipynb delete mode 100644 notebook/Examples_atomic.ipynb delete mode 100644 notebook/Examples_atomic_restrict.ipynb delete mode 100644 notebook/Examples_barrier_regions.ipynb delete mode 100644 notebook/Examples_cancellation.ipynb delete mode 100644 notebook/Examples_carrays_fpriv.ipynb delete mode 100644 notebook/Examples_collapse.ipynb delete mode 100644 notebook/Examples_cond_comp.ipynb delete mode 100644 notebook/Examples_copyin.ipynb delete mode 100644 notebook/Examples_copyprivate.ipynb delete mode 100644 notebook/Examples_cpp_reference.ipynb delete mode 100644 notebook/Examples_critical.ipynb delete mode 100644 notebook/Examples_declare_target.ipynb delete mode 100644 notebook/Examples_default_none.ipynb delete mode 100644 notebook/Examples_device.ipynb delete mode 100644 notebook/Examples_doacross.ipynb delete mode 100644 notebook/Examples_flush_nolist.ipynb delete mode 100644 notebook/Examples_fort_do.ipynb delete mode 100644 notebook/Examples_fort_loopvar.ipynb delete mode 100644 notebook/Examples_fort_race.ipynb delete mode 100644 notebook/Examples_fort_sa_private.ipynb delete mode 100644 notebook/Examples_fort_sp_common.ipynb delete mode 100644 notebook/Examples_fpriv_sections.ipynb delete mode 100644 notebook/Examples_get_nthrs.ipynb delete mode 100644 notebook/Examples_icv.ipynb delete mode 100644 notebook/Examples_init_lock.ipynb delete mode 100644 notebook/Examples_init_lock_with_hint.ipynb delete mode 100644 notebook/Examples_lastprivate.ipynb delete mode 100644 notebook/Examples_linear_in_loop.ipynb delete mode 100644 notebook/Examples_lock_owner.ipynb delete mode 100644 notebook/Examples_locks.ipynb delete mode 100644 notebook/Examples_master.ipynb delete mode 100644 notebook/Examples_mem_model.ipynb delete mode 100644 notebook/Examples_nestable_lock.ipynb delete mode 100644 notebook/Examples_nested_loop.ipynb delete mode 100644 notebook/Examples_nesting_restrict.ipynb delete mode 100644 notebook/Examples_nowait.ipynb delete mode 100644 notebook/Examples_nthrs_dynamic.ipynb delete mode 100644 notebook/Examples_nthrs_nesting.ipynb delete mode 100644 notebook/Examples_ordered.ipynb delete mode 100644 notebook/Examples_parallel.ipynb delete mode 100644 notebook/Examples_ploop.ipynb delete mode 100644 notebook/Examples_pra_iterator.ipynb delete mode 100644 notebook/Examples_private.ipynb delete mode 100644 notebook/Examples_psections.ipynb delete mode 100644 notebook/Examples_reduction.ipynb delete mode 100644 notebook/Examples_set_dynamic_nthrs.ipynb delete mode 100644 notebook/Examples_simple_lock.ipynb delete mode 100644 notebook/Examples_single.ipynb delete mode 100644 notebook/Examples_standalone.ipynb delete mode 100644 notebook/Examples_target.ipynb delete mode 100644 notebook/Examples_target_data.ipynb delete mode 100644 notebook/Examples_target_unstructured_data.ipynb delete mode 100644 notebook/Examples_target_update.ipynb delete mode 100644 notebook/Examples_task_dep.ipynb delete mode 100644 notebook/Examples_task_priority.ipynb delete mode 100644 notebook/Examples_taskgroup.ipynb delete mode 100644 notebook/Examples_tasking.ipynb delete mode 100644 notebook/Examples_taskloop.ipynb delete mode 100644 notebook/Examples_taskyield.ipynb delete mode 100644 notebook/Examples_teams.ipynb delete mode 100644 notebook/Examples_threadprivate.ipynb delete mode 100644 notebook/Examples_workshare.ipynb delete mode 100644 notebook/Examples_worksharing_critical.ipynb delete mode 100644 notebook/History.ipynb delete mode 100644 notebook/Introduction_Chapt.ipynb delete mode 100644 notebook/Title_Page.ipynb delete mode 100644 notebook/openmp-examples.ipynb diff --git a/notebook/Chap_SIMD.ipynb b/notebook/Chap_SIMD.ipynb deleted file mode 100644 index 06f5813..0000000 --- a/notebook/Chap_SIMD.ipynb +++ /dev/null @@ -1,73 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ## SIMD" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Single instruction, multiple data (SIMD) is a form of parallel execution in which the same operation is performed on multiple data elements independently in hardware vector processing units (VPU), also called SIMD units. The addition of two vectors to form a third vector is a SIMD operation. Many processors have SIMD (vector) units that can perform simultaneously 2, 4, 8 or more executions of the same operation (by a single SIMD unit). " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Loops without loop-carried backward dependency (or with dependency preserved using ordered simd) are candidates for vectorization by the compiler for execution with SIMD units. In addition, with state-of-the-art vectorization technology and `declare simd` construct extensions for function vectorization in the OpenMP 4.5 specification, loops with function calls can be vectorized as well. The basic idea is that a scalar function call in a loop can be replaced by a vector version of the function, and the loop can be vectorized simultaneously by combining a loop vectorization ( `simd` directive on the loop) and a function vectorization ( `declare simd` directive on the function)." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " A `simd` construct states that SIMD operations be performed on the data within the loop. A number of clauses are available to provide data-sharing attributes ( `private` , `linear` , `reduction` and `lastprivate` ). Other clauses provide vector length preference/restrictions ( `simdlen` / `safelen` ), loop fusion ( `collapse` ), and data alignment ( `aligned` )." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `declare simd` directive designates that a vector version of the function should also be constructed for execution within loops that contain the function and have a `simd` directive. Clauses provide argument specifications ( `linear` , `uniform` , and `aligned` ), a requested vector length ( `simdlen` ), and designate whether the function is always/never called conditionally in a loop ( `branch` / `inbranch` ). The latter is for optimizing peformance." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Also, the `simd` construct has been combined with the worksharing loop constructs ( `for simd` and `do simd` ) to enable simultaneous thread execution in different SIMD units. \n", -"Hence, the `simd` construct can be \n", -"used alone on a loop to direct vectorization (SIMD execution), or in \n", -"combination with a parallel loop construct to include thread parallelism \n", -"(a parallel loop sequentially followed by a `simd` construct, \n", -"or a combined construct such as `parallel do simd` or \n", -" `parallel for simd` )." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/notebook/Chap_affinity.ipynb b/notebook/Chap_affinity.ipynb deleted file mode 100644 index 94229e4..0000000 --- a/notebook/Chap_affinity.ipynb +++ /dev/null @@ -1,170 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ## OpenMP Affinity" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " OpenMP Affinity consists of a `proc_bind` policy (thread affinity policy) and a specification of places ( ' location units ' or _processors_ that may be cores, hardware threads, sockets, etc.). OpenMP Affinity enables users to bind computations on specific places. The placement will hold for the duration of the parallel region. However, the runtime is free to migrate the OpenMP threads to different cores (hardware threads, sockets, etc.) prescribed within a given place, if two or more cores (hardware threads, sockets, etc.) have been assigned to a given place." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Often the binding can be managed without resorting to explicitly setting places. Without the specification of places in the `OMP_PLACES` variable, the OpenMP runtime will distribute and bind threads using the entire range of processors for the OpenMP program, according to the `OMP_PROC_BIND` environment variable or the `proc_bind` clause. When places are specified, the OMP runtime binds threads to the places according to a default distribution policy, or those specified in the `OMP_PROC_BIND` environment variable or the `proc_bind` clause." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the OpenMP Specifications document a processor refers to an execution unit that is enabled for an OpenMP thread to use. A processor is a core when there is no SMT (Simultaneous Multi-Threading) support or SMT is disabled. When SMT is enabled, a processor is a hardware thread (HW-thread). (This is the usual case; but actually, the execution unit is implementation defined.) Processor numbers are numbered sequentially from 0 to the number of cores less one (without SMT), or 0 to the number HW-threads less one (with SMT). OpenMP places use the processor number to designate binding locations (unless an ' abstract name ' is used.) " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The processors available to a process may be a subset of the system's processors. This restriction may be the result of a wrapper process controlling the execution (such as `numactl` on Linux systems), compiler options, library-specific environment variables, or default kernel settings. For instance, the execution of multiple MPI processes, launched on a single compute node, will each have a subset of processors as determined by the MPI launcher or set by MPI affinity environment variables for the MPI library. \n", -"Forked threads within an MPI process \n", -"(for a hybrid execution of MPI and OpenMP code) inherit the valid \n", -"processor set for execution from the parent process (the initial task region) \n", -"when a parallel region forks threads. The binding policy set in \n", -" `OMP_PROC_BIND` or the `proc_bind` clause will be applied to \n", -"the subset of processors available to _the particular_ MPI process." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"Also, setting an explicit list of processor numbers in the `OMP_PLACES` \n", -"variable before an MPI launch (which involves more than one MPI process) will \n", -"result in unspecified behavior (and doesn't make sense) because the set of \n", -"processors in the places list must not contain processors outside the subset \n", -"of processors for an MPI process. A separate `OMP_PLACES` variable must \n", -"be set for each MPI process, and is usually accomplished by launching a script \n", -"which sets `OMP_PLACES` specifically for the MPI process. " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Threads of a team are positioned onto places in a compact manner, a scattered distribution, or onto the master's place, by setting the `OMP_PROC_BIND` environment variable or the `proc_bind` clause to _close_ , _spread_ , or _master_ , respectively. When `OMP_PROC_BIND` is set to FALSE no binding is enforced; and when the value is TRUE, the binding is implementation defined to a set of places in the `OMP_PLACES` variable or to places defined by the implementation if the `OMP_PLACES` variable is not set." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `OMP_PLACES` variable can also be set to an abstract name ( _threads_ , _cores_ , _sockets_ ) to specify that a place is either a single hardware thread, a core, or a socket, respectively. This description of the `OMP_PLACES` is most useful when the number of threads is equal to the number of hardware thread, cores or sockets. It can also be used with a _close_ or _spread_ distribution policy when the equality doesn't hold." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -" We need an example of using sockets, cores and threads:" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -" case 1 cores:" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -" Hyper-Threads on (2 hardware threads per core) \n", -" 1 socket x 4 cores x 2 HW-threads \n", -" \n", -" export OMP_NUM_THREADS=4 \n", -" export OMP_PLACES=threads \n", -" \n", -" core # 0 1 2 3 \n", -" processor # 0,1 2,3 4,5 6,7 \n", -" thread # 0 * _ _ _ _ _ _ _ #mask for thread 0 \n", -" thread # 1 _ _ * _ _ _ _ _ #mask for thread 1 \n", -" thread # 2 _ _ _ _ * _ _ _ #mask for thread 2 \n", -" thread # 3 _ _ _ _ _ _ * _ #mask for thread 3" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -" case 2 threads: \n", -" \n", -" Hyper-Threads on (2 hardware threads per core) \n", -" 1 socket x 4 cores x 2 HW-threads \n", -" \n", -" export OMP_NUM_THREADS=4 \n", -" export OMP_PLACES=cores \n", -" \n", -" core # 0 1 2 3 \n", -" processor # 0,1 2,3 4,5 6,7 \n", -" thread # 0 * * _ _ _ _ _ _ #mask for thread 0 \n", -" thread # 1 _ _ * * _ _ _ _ #mask for thread 1 \n", -" thread # 2 _ _ _ _ * * _ _ #mask for thread 2 \n", -" thread # 3 _ _ _ _ _ _ * * #mask for thread 3" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -" case 3 sockets: \n", -" \n", -" No Hyper-Threads \n", -" 3 socket x 4 cores \n", -" \n", -" export OMP_NUM_THREADS=3 \n", -" export OMP_PLACES=sockets \n", -" \n", -" socket # 0 1 2 \n", -" processor # 0,1,2,3 4,5,6,7 8,9,10,11 \n", -" thread # 0 * * * * _ _ _ _ _ _ _ _ #mask for thread 0 \n", -" thread # 0 _ _ _ _ * * * * _ _ _ _ #mask for thread 1 \n", -" thread # 0 _ _ _ _ _ _ _ _ * * * * #mask for thread 2" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/notebook/Chap_data_environment.ipynb b/notebook/Chap_data_environment.ipynb deleted file mode 100644 index 84e83d7..0000000 --- a/notebook/Chap_data_environment.ipynb +++ /dev/null @@ -1,121 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ## Data Environment" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The OpenMP _data environment_ contains data attributes of variables and objects. Many constructs (such as `parallel` , `simd` , `task` ) accept clauses to control _data-sharing_ attributes of referenced variables in the construct, where _data-sharing_ applies to whether the attribute of the variable is _shared_ , is _private_ storage, or has special operational characteristics (as found in the `firstprivate` , `lastprivate` , `linear` , or `reduction` clause)." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The data environment for a device (distinguished as a _device data environment_ ) is controlled on the host by _data-mapping_ attributes, which determine the relationship of the data on the host, the _original_ data, and the data on the device, the _corresponding_ data." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " bigskip DATA-SHARING ATTRIBUTES" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Data-sharing attributes of variables can be classified as being _predetermined_ , _explicitly determined_ or _implicitly determined_ ." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Certain variables and objects have predetermined attributes. A commonly found case is the loop iteration variable in associated loops of a `for` or `do` construct. It has a private data-sharing attribute. Variables with predetermined data-sharing attributes can not be listed in a data-sharing clause; but there are some exceptions (mainly concerning loop iteration variables)." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Variables with explicitly determined data-sharing attributes are those that are referenced in a given construct and are listed in a data-sharing attribute clause on the construct. Some of the common data-sharing clauses are: `shared` , `private` , `firstprivate` , `lastprivate` , `linear` , and `reduction` . \n", -" Are these all of them?" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Variables with implicitly determined data-sharing attributes are those that are referenced in a given construct, do not have predetermined data-sharing attributes, and are not listed in a data-sharing attribute clause of an enclosing construct. For a complete list of variables and objects with predetermined and implicitly determined attributes, please refer to the _Data-sharing Attribute Rules for Variables Referenced in a Construct_ subsection of the OpenMP Specifications document. " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " bigskip DATA-MAPPING ATTRIBUTES" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `map` clause on a device construct explictly specifies how the list items in the clause are mapped from the encountering task's data environment (on the host) to the corresponding \n", -"* in the device data environment (on the device). The common _list items_ are arrays, array sections, scalars, pointers, and structure elements (members). " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Procedures and global variables have predetermined data mapping if they appear within the list or block of a `declare target` directive. Also, a C/C++ pointer is mapped as a zero-length array section, as is a C++ variable that is a reference to a pointer. \n", -" Waiting for response from Eric on this." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Without explict mapping, non-scalar and non-pointer variables within the scope of the `target` construct are implicitly mapped with a _map-type_ of `tofrom` . Without explicit mapping, scalar variables within the scope of the `target` construct are not mapped, but have an implicit firstprivate data-sharing attribute. (That is, the value of the original variable is given to a private variable of the same name on the device.) This behavior can be changed with the `defaultmap` clause." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `map` clause can appear on `target` , `target data` and `target enter/exit data` constructs. The operations of creation and removal of device storage as well as assignment of the original list \n", -"* values to the corresponding list items may be complicated when the list \n", -"* appears on multiple constructs or when the host and device storage is shared. In these cases the item's reference count, the number of times it has been referenced (+1 on entry and -1 on exited) in nested (structured) map regions and/or accumulative (unstructured) mappings, determines the operation. Details of the `map` clause and reference count operation are specified in the _map Clause_ subsection of the OpenMP Specifications document." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/notebook/Chap_devices.ipynb b/notebook/Chap_devices.ipynb deleted file mode 100644 index e07dde3..0000000 --- a/notebook/Chap_devices.ipynb +++ /dev/null @@ -1,81 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ## Devices" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `target` construct consists of a `target` directive and an execution region. The `target` region is executed on the default device or the device specified in the `device` clause. " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In OpenMP version 4.0, by default, all variables within the lexical scope of the construct are copied _to_ and _from_ the device, unless the device is the host, or the data exists on the device from a previously executed data-type construct that has created space on the device and possibly copied host data to the device storage." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The constructs that explicitly create storage, transfer data, and free storage on the device are catagorized as structured and unstructured. The `target` `data` construct is structured. It creates a data region around `target` constructs, and is convenient for providing persistent data throughout multiple `target` regions. The `target` `enter` `data` and `target` `exit` `data` constructs are unstructured, because they can occur anywhere and do not support a 'structure' (a region) for enclosing `target` constructs, as does the `target` `data` construct. " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `map` clause is used on `target` constructs and the data-type constructs to map host data. It specifies the device storage and data movement `to` and `from` the device, and controls on the storage duration." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " There is an important change in the OpenMP 4.5 specification that alters the data model for scalar variables and C/C++ pointer variables. The default behavior for scalar variables and C/C++ pointer variables in an 4.5 compliant code is `firstprivate` . Example codes that have been updated to reflect this new behavior are annotated with a description that describes changes required for correct execution. Often it is a simple matter of mapping the variable as `tofrom` to obtain the intended 4.0 behavior." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In OpenMP version 4.5 the mechanism for target execution is specified as occuring through a _target task_ . When the `target` construct is encountered a new _target task_ is generated. The _target task_ completes after the `target` region has executed and all data transfers have finished." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " This new specification does not affect the execution of pre-4.5 code; it is a necessary element for asynchronous execution of the `target` region when using the new `nowait` clause introduced in OpenMP 4.5." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/notebook/Chap_memory_model.ipynb b/notebook/Chap_memory_model.ipynb deleted file mode 100644 index 66926a0..0000000 --- a/notebook/Chap_memory_model.ipynb +++ /dev/null @@ -1,146 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ## Memory Model" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In this chapter, examples illustrate race conditions on access to variables with shared data-sharing attributes. A race condition can exist when two or more threads are involved in accessing a variable in which not all of the accesses are reads; that is, a WaR, RaW or WaW condition exists (R=read, a=after, W=write). A RaR does not produce a race condition. Ensuring thread execution order at the processor level is not enough to avoid race conditions, because the local storage at the processor level (registers, caches, etc.) must be synchronized so that a consistent view of the variable in the memory hierarchy can be seen by the threads accessing the variable." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " OpenMP provides a shared-memory model which allows all threads access to _memory_ (shared data). Each thread also has exclusive access to _threadprivate memory_ (private data). A private variable referenced in an OpenMP directive's structured block is a new version of the original variable (with the same name) for each task (or SIMD lane) within the code block. A private variable is initially undefined (except for variables in `firstprivate` and `linear` clauses), and the original variable value is unaltered by assignments to the private variable, (except for `reduction` , `lastprivate` and `linear` clauses)." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Private variables in an outer `parallel` region can be shared by implicit tasks of an inner `parallel` region (with a `share` clause on the inner `parallel` directive). Likewise, a private variable may be shared in the region of an explicit `task` (through a `shared` clause)." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `flush` directive forces a consistent view of local variables of the thread executing the `flush` . When a list is supplied on the directive, only the items (variables) in the list are guaranteed to be flushed." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Implied flushes exist at prescribed locations of certain constructs. For the complete list of these locations and associated constructs, please refer to the _flush Construct_ section of the OpenMP Specifications document." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -" The following table lists construct in which implied flushes exist, and the \n", -" location of their execution. \n", -" \n", -" \n", -"[hb] \n", -" \n", -" \n", -"caption {Execution Location for Implicit Flushes. } \n", -" { | p{0.6linewidth} | l | } \n", -" hline \n", -" `CONSTRUCT` & makecell{ `EXECUTION` `LOCATION` } \n", -" hline \n", -" `parallel` & upon entry and exit \n", -" hline \n", -" makecell[l]{worksharing hspace{1.5em} `for` , `do` \n", -" hspace{1.5em} `sections` \n", -" hspace{1.5em} `single` \n", -" hspace{1.5em} `workshare` } \n", -" & upon exit \n", -" hline \n", -" `critical` & upon entry and exit \n", -" hline \n", -" `target` & upon entry and exit \n", -" hline \n", -" `barrier` & during \n", -" hline \n", -" `atomic` operation with _seq_cst_ clause & upon entry and exit \n", -" hline \n", -" `ordered` * & upon entry and exit \n", -" hline \n", -" `cancel` ** and `cancellation point` ** & during \n", -" hline \n", -" `target data` & upon entry and exit \n", -" hline \n", -" `target update` + `to` clause, \n", -" `target enter data` & on entry \n", -" hline \n", -" `target update` + `from` clause, \n", -" `target exit data` & on exit \n", -" hline \n", -" `omp_set_lock` & during \n", -" hline \n", -" makecell[l]{ `omp_set/unset_lock` , `omp_test_lock` *** \n", -" `omp_set/unset/test_nest_lock` *** } \n", -" & during \n", -" hline \n", -" task scheduling point & makecell[l]{immediately before and after} \n", -" hline \n", -" \n", -" \n", -"caption {Execution Location for Implicit Flushes. } \n", -" \n", -" \n", -" \n", -" \n", -" \n", -" * without clauses and with `threads` or `depend` clauses newline \n", -" ** when _cancel-var_ ICV is _true_ (cancellation is turned on) and cancellation is activated newline \n", -" *** if the region causes the lock to be set or unset \n", -" \n", -" A flush with a list is implied for non-sequentially consistent `atomic` operations \n", -" ( `atomic` directive without a `seq_cst` clause), where the list \n", -"* is the \n", -" specific storage location accessed atomically (specified as the _x_ variable \n", -" in _atomic Construct_ subsection of the OpenMP Specifications document)." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Examples 1-3 show the difficulty of synchronizing threads through `flush` and `atomic` directives." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/notebook/Chap_parallel_execution.ipynb b/notebook/Chap_parallel_execution.ipynb deleted file mode 100644 index 84fc9d1..0000000 --- a/notebook/Chap_parallel_execution.ipynb +++ /dev/null @@ -1,165 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ## Parallel Execution" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " A single thread, the _initial thread_ , begins sequential execution of an OpenMP enabled program, as if the whole program is in an implicit parallel region consisting of an implicit task executed by the _initial thread_ ." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " A `parallel` construct encloses code, forming a parallel region. An _initial thread_ encountering a `parallel` region forks (creates) a team of threads at the beginning of the `parallel` region, and joins them (removes from execution) at the end of the region. The initial thread becomes the master thread of the team in a `parallel` region with a _thread_ number equal to zero, the other threads are numbered from 1 to number of threads minus 1. A team may be comprised of just a single thread." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Each thread of a team is assigned an implicit task consisting of code within the parallel region. The task that creates a parallel region is suspended while the tasks of the team are executed. A thread is tied to its task; that is, only the thread assigned to the task can execute that task. After completion of the `parallel` region, the master thread resumes execution of the generating task. " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"After the `parallel` region the master thread becomes the initial \n", -"thread again, and continues to execute the _sequential part_ . " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Any task within a `parallel` region is allowed to encounter another `parallel` region to form a nested `parallel` region. The parallelism of a nested `parallel` region (whether it forks additional threads, or is executed serially by the encountering task) can be controlled by the `OMP_NESTED` environment variable or the `omp_set_nested()` API routine with arguments indicating true or false." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The number of threads of a `parallel` region can be set by the `OMP_NUM_THREADS` environment variable, the `omp_set_num_threads()` routine, or on the `parallel` directive with the `num_threads` clause. The routine overrides the environment variable, and the clause overrides all. Use the `OMP_DYNAMIC` or the `omp_set_dynamic()` function to specify that the OpenMP implementation dynamically adjust the number of threads for `parallel` regions. The default setting for dynamic adjustment is implementation defined. When dynamic adjustment is on and the number of threads is specified, the number of threads becomes an upper limit for the number of threads to be provided by the OpenMP runtime." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " WORKSHARING CONSTRUCTS" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " A worksharing construct distributes the execution of the associated region among the members of the team that encounter it. There is an implied barrier at the end of the worksharing region (there is no barrier at the beginning). The worksharing constructs are:" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* loop constructs: { `for` and `do` } \n", -"* `sections` \n", -"* `single` \n", -"* `workshare` " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `for` and `do` constructs (loop constructs) create a region consisting of a loop. A loop controlled by a loop construct is called an _associated_ loop. Nested loops can form a single region when the `collapse` clause (with an integer argument) designates the number of _associated_ loops to be executed in parallel, by forming a 'single iteration space' for the specified number of nested loops. The `ordered` clause can also control multiple associated loops." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " An associated loop must adhere to a 'canonical form' (specified in the _Canonical Loop Form_ of the OpenMP Specifications document) which allows the iteration count (of all associated loops) to be computed before the (outermost) loop is executed. \n", -"[58:27-29]. Most common loops comply with the canonical form, including C++ iterators." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " A `single` construct forms a region in which only one thread (any one of the team) executes the region. The other threads wait at the implied barrier at the end, unless the `nowait` clause is specified." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `sections` construct forms a region that contains one or more structured blocks. Each block of a `sections` directive is constructed with a `section` construct, and executed once by one of the threads (any one) in the team. (If only one block is formed in the region, the `section` construct, which is used to separate blocks, is not required.) The other threads wait at the implied barrier at the end, unless the `nowait` clause is specified." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `workshare` construct is a Fortran feature that consists of a region with a single structure block (section of code). Statements in the `workshare` region are divided into units of work, and executed (once) by threads of the team. " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " bigskip MASTER CONSTRUCT" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `master` construct is not a worksharing construct. The master region is is executed only by the master thread. There is no implicit barrier (and flush) at the end of the `master` region; hence the other threads of the team continue execution beyond code statements beyond the `master` region." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/notebook/Chap_program_control.ipynb b/notebook/Chap_program_control.ipynb deleted file mode 100644 index 1fe190c..0000000 --- a/notebook/Chap_program_control.ipynb +++ /dev/null @@ -1,151 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ## Program Control" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Some specific and elementary concepts of controlling program execution are illustrated in the examples of this chapter. Control can be directly managed with conditional control code (ifdef's with the `_OPENMP` macro, and the Fortran sentinel ( `!$` ) for conditionally compiling). The `if` clause on some constructs can direct the runtime to ignore or alter the behavior of the construct. Of course, the base-language `if` statements can be used to control the 'execution' of stand-alone directives (such as `flush` , `barrier` , `taskwait` , and `taskyield` ). However, the directives must appear in a block structure, and not as a substatement as shown in examples 1 and 2 of this chapter." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " bigskip CANCELLATION" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Cancellation (termination) of the normal sequence of execution for the threads in an OpenMP region can be accomplished with the `cancel` construct. The construct uses a _construct-type-clause_ to set the region-type to activate for the cancellation. That is, inclusion of one of the _construct-type-clause_ names `parallel` , `for` , `do` , `sections` or `taskgroup` on the directive line activates the corresponding region. The `cancel` construct is activated by the first encountering thread, and it continues execution at the end of the named region. The `cancel` construct is also a concellation point for any other thread of the team to also continue execution at the end of the named region. " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Also, once the specified region has been activated for cancellation any thread that encounnters a `cancellation point` construct with the same named region ( _construct-type-clause_ ), continues execution at the end of the region." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " For an activated `cancel taskgroup` construct, the tasks that belong to the taskgroup set of the innermost enclosing taskgroup region will be canceled. " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " A task that encounters the cancel taskgroup construct continues execution at the end of its task region. Any task of the taskgroup that has already begun execution will run to completion, unless it encounters a `cancellation point` ; tasks that have not begun execution 'may' be discarded as completed tasks." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " bigskip CONTROL VARIABLES " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Internal control variables (ICV) are used by implementations to hold values which control the execution of OpenMP regions. Control (and hence the ICVs) may be set as implementation defaults, or set and adjusted through environment variables, clauses, and API functions. Many of the ICV control values are accessible through API function calls. Also, initial ICV values are reported by the runtime if the `OMP_DISPLAY_ENV` environment variable has been set to `TRUE` . " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"As an example, the _nthreads-var_ is the ICV that holds the number of threads \n", -"to be used in a `parallel` region. It can be set with the `OMP_NUM_THREADS` environment variable, \n", -"the `omp_set_num_threads()` API function, or the `num_threads` clause. The default _nthreads-var_ \n", -"value is implementation defined. All of the ICVs are presented in the _Internal Control Variables_ section \n", -"of the _Directives_ chapter of the OpenMP Specifications document. Within the same document section, override \n", -"relationships and scoping information can be found for applying user specifications and understanding the \n", -"extent of the control." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " bigskip NESTED CONSTRUCTS" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Certain combinations of nested constructs are permitted, giving rise to a _combined_ construct consisting of two or more constructs. These can be used when the two (or several) constructs would be used immediately in succession (closely nested). A combined construct can use the clauses of the component constructs without restrictions. A _composite_ construct is a combined construct which has one or more clauses with (an often obviously) modified or restricted meaning, relative to when the constructs are uncombined. \n", -"\n", -"[appear separately (singly)." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"The combined `parallel do` and `parallel for` constructs are formed by combining the `parallel` \n", -"construct with one of the loops constructs `do` or `for` . The \n", -" `parallel do SIMD` and `parallel for SIMD` constructs are composite constructs (composed from \n", -"the parallel loop constructs and the `SIMD` construct), because the `collapse` clause must \n", -"explicitly address the ordering of loop chunking _and_ SIMD 'combined' execution." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Certain nestings are forbidden, and often the reasoning is obvious. Worksharing constructs cannot be nested, and the `barrier` construct cannot be nested inside a worksharing construct, or a `critical` construct. Also, `target` constructs cannot be nested. " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `parallel` construct can be nested, as well as the `task` construct. The parallel execution in the nested `parallel` construct(s) is control by the `OMP_NESTED` and `OMP_MAX_ACTIVE_LEVELS` environment variables, and the `omp_set_nested()` and `omp_set_max_active_levels()` functions." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " More details on nesting can be found in the _Nesting of Regions_ of the _Directives_ chapter in the OpenMP Specifications document." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/notebook/Chap_synchronization.ipynb b/notebook/Chap_synchronization.ipynb deleted file mode 100644 index b8b11bc..0000000 --- a/notebook/Chap_synchronization.ipynb +++ /dev/null @@ -1,90 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ## Synchronization" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `barrier` construct is a stand-alone directive that requires all threads of a team (within a contention group) to execute the barrier and complete execution of all tasks within the region, before continuing past the barrier." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `critical` construct is a directive that contains a structured block. The construct allows only a single thread at a time to execute the structured block (region). Multiple critical regions may exist in a parallel region, and may act cooperatively (only one thread at a time in all `critical` regions), or separately (only one thread at a time in each `critical` regions when a unique name is supplied on each `critical` construct). An optional (lock) `hint` clause may be specified on a named `critical` construct to provide the OpenMP runtime guidance in selection a locking mechanism." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " On a finer scale the `atomic` construct allows only a single thread at a time to have atomic access to a storage location involving a single read, write, update or capture statement, and a limited number of combinations when specifying the `capture` _atomic-clause_ clause. The _atomic-clause_ clause is required for some expression statements, but are not required for `update` statements. Please see the details in the _atomic Construct_ subsection of the _Directives_ chapter in the OpenMP Specifications document." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -" The following three sentences were stolen from the spec. The `ordered` construct either specifies a structured block in a loop, simd, or loop SIMD region that will be executed in the order of the loop iterations. The ordered construct sequentializes and orders the execution of ordered regions while allowing code outside the region to run in parallel." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Since OpenMP 4.5 the `ordered` construct can also be a stand-alone directive that specifies cross-iteration dependences in a doacross loop nest. The `depend` clause uses a `sink` _dependence-type_ , along with a iteration vector argument (vec) to indicate the iteration that satisfies the dependence. The `depend` clause with a `source` _dependence-type_ specifies dependence satisfaction." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `flush` directive is a stand-alone construct that forces a thread's temporal local storage (view) of a variable to memory where a consistent view of the variable storage can be accesses. When the construct is used without a variable list, all the locally thread-visible data as defined by the base language are flushed. A construct with a list applies the flush operation only to the items in the list. The `flush` construct also effectively insures that no memory (load or store) operation for the variable set (list items, or default set) may be reordered across the `flush` directive. " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " General-purpose routines provide mutual exclusion semantics through locks, represented by lock variables. The semantics allows a task to _set_ , and hence _own_ a lock, until it is _unset_ by the task that set it. A _nestable_ lock can be set multiple times by a task, and is used when in code requires nested control of locks. A _simple lock_ can only be set once by the owning task. There are specific calls for the two types of locks, and the variable of a specific lock type cannot be used by the other lock type. " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Any explicit task will observe the synchronization prescribed in a `barrier` construct and an implied barrier. Also, additional synchronizations are available for tasks. All children of a task will wait at a `taskwait` (for their siblings to complete). A `taskgroup` construct creates a region in which the current task is suspended at the end of the region until all sibling tasks, and their descendants, have completed. Scheduling constraints on task execution can be prescribed by the `depend` clause to enforce dependence on previously generated tasks. More details on controlling task executions can be found in the _Tasking_ Chapter in the OpenMP Specifications document. \n", -"(DO REF. RIGHT.)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/notebook/Chap_tasking.ipynb b/notebook/Chap_tasking.ipynb deleted file mode 100644 index 067119c..0000000 --- a/notebook/Chap_tasking.ipynb +++ /dev/null @@ -1,75 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ## Tasking" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Tasking constructs provide units of work to a thread for execution. Worksharing constructs do this, too (e.g. `for` , `do` , `sections` , and `singles` constructs); but the work units are tightly controlled by an iteration limit and limited scheduling, or a limited number of `sections` or `single` regions. Worksharing was designed with ' data parallel ' computing in mind. Tasking was designed for ' task parallel ' computing and often involves non-locality or irregularity in memory access." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `task` construct can be used to execute work chunks: in a while loop; while traversing nodes in a list; at nodes in a tree graph; or in a normal loop (with a `taskloop` construct). Unlike the statically scheduled loop iterations of worksharing, a task is often enqueued, and then dequeued for execution by any of the threads of the team within a parallel region. The generation of tasks can be from a single generating thread (creating sibling tasks), or from multiple generators in a recursive graph tree traversals. \n", -"(creating a parent-descendents hierarchy of tasks, see example 4 and 7 below). A `taskloop` construct bundles iterations of an associated loop into tasks, and provides similar controls found in the `task` construct." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Sibling tasks are synchronized by the `taskwait` construct, and tasks and their descendent tasks can be synchronized by containing them in a `taskgroup` region. Ordered execution is accomplished by specifying dependences with a `depend` clause. Also, priorities can be specified as hints to the scheduler through a `priority` clause." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Various clauses can be used to manage and optimize task generation, as well as reduce the overhead of execution and to relinquish control of threads for work balance and forward progress. " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Once a thread starts executing a task, it is the designated thread for executing the task to completion, even though it may leave the execution at a scheduling point and return later. The thread is tied to the task. Scheduling points can be introduced with the `taskyield` construct. With an `untied` clause any other thread is allowed to continue the task. An `if` clause with a _true_ expression allows the generating thread to immediately execute the task as an undeferred task. By including the data environment of the generating task into the generated task with the `mergeable` and `final` clauses, task generation overhead can be reduced." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " A complete list of the tasking constructs and details of their clauses can be found in the _Tasking Constructs_ chapter of the OpenMP Specifications, in the _OpenMP Application Programming Interface_ section." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/notebook/Examples_Chapt.ipynb b/notebook/Examples_Chapt.ipynb deleted file mode 100644 index f37c20e..0000000 --- a/notebook/Examples_Chapt.ipynb +++ /dev/null @@ -1,50 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "chapter*{Examples}" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " addcontentsline{toc}{chapter}{protectnumberline{}Examples} The following are examples of the OpenMP API directives, constructs, and routines. ccppspecificstart A statement following a directive is compound only when necessary, and a non-compound statement is indented with respect to a directive preceding it. ccppspecificend" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Each example is labeled as _ename.seqno.ext_ , where _ename_ is the example name, _seqno_ is the sequence number in a section, and _ext_ is the source file extension to indicate the code type and source form. _ext_ is one of the following: \n", -"* _c_ -- C code, \n", -"* _cpp_ -- C++ code, \n", -"* _f_ -- Fortran code in fixed form, and \n", -"* _f90_ -- Fortran code in free form. " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/notebook/Examples_SIMD.ipynb b/notebook/Examples_SIMD.ipynb deleted file mode 100644 index cbf4e95..0000000 --- a/notebook/Examples_SIMD.ipynb +++ /dev/null @@ -1,288 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -" ### `simd` and `declare` `simd` Constructs" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example illustrates the basic use of the `simd` construct to assure the compiler that the loop can be vectorized." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_SIMD.1.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_SIMD.1.f90" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " When a function can be inlined within a loop the compiler has an opportunity to vectorize the loop. By guaranteeing SIMD behavior of a function's operations, characterizing the arguments of the function and privatizing temporary variables of the loop, the compiler can often create faster, vector code for the loop. In the examples below the `declare` `simd` construct is used on the _add1_ and _add2_ functions to enable creation of their corresponding SIMD function versions for execution within the associated SIMD loop. The functions characterize two different approaches of accessing data within the function: by a single variable and as an element in a data array, respectively. The _add3_ C function uses dereferencing." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `declare` `simd` constructs also illustrate the use of `uniform` and `linear` clauses. The `uniform(fact)` clause indicates that the variable _fact_ is invariant across the SIMD lanes. In the _add2_ function _a_ and _b_ are included in the `unform` list because the C pointer and the Fortran array references are constant. The _i_ index used in the _add2_ function is included in a `linear` clause with a constant-linear-step of 1, to guarantee a unity increment of the associated loop. In the `declare` `simd` construct for the _add3_ C function the `linear(a,b:1)` clause instructs the compiler to generate unit-stride loads across the SIMD lanes; otherwise, costly emph{gather} instructions would be generated for the unknown sequence of access of the pointer dereferences." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the `simd` constructs for the loops the `private(tmp)` clause is necessary to assure that the each vector operation has its own _tmp_ variable." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_SIMD.2.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_SIMD.2.f90" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " A thread that encounters a SIMD construct executes a vectorized code of the iterations. Similar to the concerns of a worksharing loop a loop vectorized with a SIMD construct must assure that temporary and reduction variables are privatized and declared as reductions with clauses. The example below illustrates the use of `private` and `reduction` clauses in a SIMD construct." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_SIMD.3.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_SIMD.3.f90" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " A `safelen(N)` clause in a `simd` construct assures the compiler that there are no loop-carried dependencies for vectors of size _N_ or below. If the `safelen` clause is not specified, then the default safelen value is the number of loop iterations. The `safelen(16)` clause in the example below guarantees that the vector code is safe for vectors up to and including size 16. In the loop, _m_ can be 16 or greater, for correct code execution. If the value of _m_ is less than 16, the behavior is undefined." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_SIMD.4.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_SIMD.4.f90" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following SIMD construct instructs the compiler to collapse the _i_ and _j_ loops into a single SIMD loop in which SIMD chunks are executed by threads of the team. Within the workshared loop chunks of a thread, the SIMD chunks are executed in the lanes of the vector units." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_SIMD.5.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_SIMD.5.f90" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"\n", -"\n", -" section ### `inbranch` and `notinbranch` Clauses" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following examples illustrate the use of the `declare` `simd` construct with the `inbranch` and `notinbranch` clauses. The `notinbranch` clause informs the compiler that the function _foo_ is never called conditionally in the SIMD loop of the function _myaddint_ . On the other hand, the `inbranch` clause for the function goo indicates that the function is always called conditionally in the SIMD loop inside the function _myaddfloat_ ." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_SIMD.6.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_SIMD.6.f90" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the code below, the function _fib()_ is called in the main program and also recursively called in the function _fib()_ within an `if` condition. The compiler creates a masked vector version and a non-masked vector version for the function _fib()_ while retaining the original scalar version of the _fib()_ function." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_SIMD.7.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_SIMD.7.f90" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"\n", -"\n", -" section ### Loop-Carried Lexical Forward Dependence" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example tests the restriction on an SIMD loop with the loop-carried lexical forward-dependence. This dependence must be preserved for the correct execution of SIMD loops." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " A loop can be vectorized even though the iterations are not completely independent when it has loop-carried dependences that are forward lexical dependences, indicated in the code below by the read of _A[j+1]_ and the write to _A[j]_ in C/C++ code (or _A(j+1)_ and _A(j)_ in Fortran). That is, the read of _A[j+1]_ (or _A(j+1)_ in Fortran) before the write to _A[j]_ (or _A(j)_ in Fortran) ordering must be preserved for each iteration in _j_ for valid SIMD code generation." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " This test assures that the compiler preserves the loop carried lexical forward-dependence for generating a correct SIMD code." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_SIMD.8.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_SIMD.8.f90" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/notebook/Examples_affinity.ipynb b/notebook/Examples_affinity.ipynb deleted file mode 100644 index 6a29705..0000000 --- a/notebook/Examples_affinity.ipynb +++ /dev/null @@ -1,705 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### The `proc_bind` Clause" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following examples demonstrate how to use the `proc_bind` clause to control the thread binding for a team of threads in a `parallel` region. The machine architecture is depicted in the figure below. It consists of two sockets, each equipped with a quad-core processor and configured to execute two hardware threads simultaneously on each core. These examples assume a contiguous core numbering starting from 0, such that the hardware threads 0,1 form the first physical core." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " {figs/proc_bind_fig.pdf}} \n", -" fi" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following equivalent place list declarations consist of eight places (which we designate as p0 to p7):" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " `OMP_PLACES= ' {0,1},{2,3},{4,5},{6,7},{8,9},{10,11},{12,13},{14,15} ' ` " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " or" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " `OMP_PLACES= ' {0:2}:8:2 ' ` " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### Spread Affinity Policy" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows the result of the `spread` affinity policy on the partition list when the number of threads is less than or equal to the number of places in the parent's place partition, for the machine architecture depicted above. Note that the threads are bound to the first place of each subpartition." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_affinity.1.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_affinity.1.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " It is unspecified on which place the master thread is initially started. If the master thread is initially started on p0, the following placement of threads will be applied in the parallel region:" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* thread 0 executes on p0 with the place partition p0,p1" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* thread 1 executes on p2 with the place partition p2,p3" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* thread 2 executes on p4 with the place partition p4,p5" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* thread 3 executes on p6 with the place partition p6,p7 " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " If the master thread would initially be started on p2, the placement of threads and distribution of the place partition would be as follows:" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* thread 0 executes on p2 with the place partition p2,p3" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* thread 1 executes on p4 with the place partition p4,p5" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* thread 2 executes on p6 with the place partition p6,p7" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* thread 3 executes on p0 with the place partition p0,p1 " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example illustrates the `spread` thread affinity policy when the number of threads is greater than the number of places in the parent's place partition." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Let _T_ be the number of threads in the team, and _P_ be the number of places in the parent's place partition. The first _T/P_ threads of the team (including the master thread) execute on the parent's place. The next _T/P_ threads execute on the next place in the place partition, and so on, with wrap around. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_affinity.2.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_affinity.2.f90" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " It is unspecified on which place the master thread is initially started. If the master thread is initially started on p0, the following placement of threads will be applied in the parallel region:" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* threads 0,1 execute on p0 with the place partition p0" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* threads 2,3 execute on p1 with the place partition p1" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* threads 4,5 execute on p2 with the place partition p2" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* threads 6,7 execute on p3 with the place partition p3" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* threads 8,9 execute on p4 with the place partition p4" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* threads 10,11 execute on p5 with the place partition p5" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* threads 12,13 execute on p6 with the place partition p6" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* threads 14,15 execute on p7 with the place partition p7 " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " If the master thread would initially be started on p2, the placement of threads and distribution of the place partition would be as follows:" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* threads 0,1 execute on p2 with the place partition p2" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* threads 2,3 execute on p3 with the place partition p3" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* threads 4,5 execute on p4 with the place partition p4" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* threads 6,7 execute on p5 with the place partition p5" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* threads 8,9 execute on p6 with the place partition p6" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* threads 10,11 execute on p7 with the place partition p7" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* threads 12,13 execute on p0 with the place partition p0" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* threads 14,15 execute on p1 with the place partition p1 " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### Close Affinity Policy" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows the result of the `close` affinity policy on the partition list when the number of threads is less than or equal to the number of places in parent's place partition, for the machine architecture depicted above. The place partition is not changed by the `close` policy." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_affinity.3.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_affinity.3.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " It is unspecified on which place the master thread is initially started. If the master thread is initially started on p0, the following placement of threads will be applied in the `parallel` region:" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* thread 0 executes on p0 with the place partition p0-p7" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* thread 1 executes on p1 with the place partition p0-p7" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* thread 2 executes on p2 with the place partition p0-p7" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* thread 3 executes on p3 with the place partition p0-p7 " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " If the master thread would initially be started on p2, the placement of threads and distribution of the place partition would be as follows:" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* thread 0 executes on p2 with the place partition p0-p7" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* thread 1 executes on p3 with the place partition p0-p7" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* thread 2 executes on p4 with the place partition p0-p7" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* thread 3 executes on p5 with the place partition p0-p7 " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example illustrates the `close` thread affinity policy when the number of threads is greater than the number of places in the parent's place partition." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Let _T_ be the number of threads in the team, and _P_ be the number of places in the parent's place partition. The first _T/P_ threads of the team (including the master thread) execute on the parent's place. The next _T/P_ threads execute on the next place in the place partition, and so on, with wrap around. The place partition is not changed by the `close` policy." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_affinity.4.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_affinity.4.f90" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " It is unspecified on which place the master thread is initially started. If the master thread is initially running on p0, the following placement of threads will be applied in the parallel region:" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* threads 0,1 execute on p0 with the place partition p0-p7" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* threads 2,3 execute on p1 with the place partition p0-p7" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* threads 4,5 execute on p2 with the place partition p0-p7" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* threads 6,7 execute on p3 with the place partition p0-p7" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* threads 8,9 execute on p4 with the place partition p0-p7" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* threads 10,11 execute on p5 with the place partition p0-p7" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* threads 12,13 execute on p6 with the place partition p0-p7" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* threads 14,15 execute on p7 with the place partition p0-p7 " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " If the master thread would initially be started on p2, the placement of threads and distribution of the place partition would be as follows:" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* threads 0,1 execute on p2 with the place partition p0-p7" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* threads 2,3 execute on p3 with the place partition p0-p7" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* threads 4,5 execute on p4 with the place partition p0-p7" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* threads 6,7 execute on p5 with the place partition p0-p7" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* threads 8,9 execute on p6 with the place partition p0-p7" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* threads 10,11 execute on p7 with the place partition p0-p7" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* threads 12,13 execute on p0 with the place partition p0-p7" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* threads 14,15 execute on p1 with the place partition p0-p7 " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### Master Affinity Policy" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows the result of the `master` affinity policy on the partition list for the machine architecture depicted above. The place partition is not changed by the master policy." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_affinity.5.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_affinity.5.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " It is unspecified on which place the master thread is initially started. If the master thread is initially running on p0, the following placement of threads will be applied in the parallel region:" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* threads 0-3 execute on p0 with the place partition p0-p7 " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " If the master thread would initially be started on p2, the placement of threads and distribution of the place partition would be as follows:" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* threads 0-3 execute on p2 with the place partition p0-p7 " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/notebook/Examples_affinity_query.ipynb b/notebook/Examples_affinity_query.ipynb deleted file mode 100644 index 32880f6..0000000 --- a/notebook/Examples_affinity_query.ipynb +++ /dev/null @@ -1,85 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Affinity Query Functions" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the example below a team of threads is generated on each socket of the system, using nested parallelism. Several query functions are used to gather information to support the creation of the teams and to obtain socket and thread numbers." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " For proper execution of the code, the user must create a place partition, such that each place is a listing of the core numbers for a socket. For example, in a 2 socket system with 8 cores in each socket, and sequential numbering in the socket for the core numbers, the `OMP_PLACES` variable would be set to '{0:8},{8:8}', using the place syntax { _lower_bound_ : _length_ : _stride_ }, and the default stride of 1." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The code determines the number of sockets ( _n_sockets_ ) using the `omp_get_num_places()` query function. In this example each place is constructed with a list of each socket's core numbers, hence the number of places is equal to the number of sockets. " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The outer parallel region forms a team of threads, and each thread executes on a socket (place) because the `proc_bind` clause uses `spread` in the outer `parallel` construct. Next, in the _socket_init_ function, an inner parallel region creates a team of threads equal to the number of elements (core numbers) from the place of the parent thread. Because the outer `parallel` construct uses a `spread` affinity policy, each of its threads inherits a subpartition of the original partition. Hence, the `omp_get_place_num_procs` query function returns the number of elements (here procs = cores) in the subpartition of the thread. After each parent thread creates its nested parallel region on the section, the socket number and thread number are reported." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Note: Portable tools like hwloc (Portable HardWare LOCality package), which support many common operating systems, can be used to determine the configuration of a system. On some systems there are utilities, files or user guides that provide configuration information. For instance, the socket number and proc_id's for a socket can be found in the /proc/cpuinfo text file on Linux systems." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_affinity.6.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_affinity.6.f90" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/notebook/Examples_array_sections.ipynb b/notebook/Examples_array_sections.ipynb deleted file mode 100644 index fdbc4e4..0000000 --- a/notebook/Examples_array_sections.ipynb +++ /dev/null @@ -1,139 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Array Sections in Device Constructs" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following examples show the usage of array sections in `map` clauses on `target` and `target` `data` constructs." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " This example shows the invalid usage of two seperate sections of the same array inside of a `target` construct." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_array_sections.1.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_array_sections.1.f90" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " This example shows the invalid usage of two separate sections of the same array inside of a `target` construct." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_array_sections.2.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_array_sections.2.f90" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " This example shows the valid usage of two separate sections of the same array inside of a `target` construct." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_array_sections.3.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_array_sections.3.f90" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " This example shows the valid usage of a wholly contained array section of an already mapped array section inside of a `target` construct." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_array_sections.4.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_array_sections.4.f90" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/notebook/Examples_associate.ipynb b/notebook/Examples_associate.ipynb deleted file mode 100644 index 006ed1b..0000000 --- a/notebook/Examples_associate.ipynb +++ /dev/null @@ -1,94 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Fortran `ASSOCIATE` Construct" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " fortranspecificstart" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following is an invalid example of specifying an associate name on a data-sharing attribute clause. The constraint in the Data Sharing Attribute Rules section in the OpenMP 4.0 API Specifications states that an associate name preserves the association with the selector established at the `ASSOCIATE` statement. The associate name _b_ is associated with the shared variable _a_ . With the predetermined data-sharing attribute rule, the associate name _b_ is not allowed to be specified on the `private` clause." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_associate.1.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In next example, within the `parallel` construct, the association name _thread_id_ is associated with the private copy of _i_ . The print statement should output the unique thread number." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_associate.2.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example illustrates the effect of specifying a selector name on a data-sharing attribute clause. The associate name _u_ is associated with _v_ and the variable _v_ is specified on the `private` clause of the `parallel` construct. The construct association is established prior to the `parallel` region. The association between _u_ and the original _v_ is retained (see the Data Sharing Attribute Rules section in the OpenMP 4.0 API Specifications). Inside the `parallel` region, _v_ has the value of -1 and _u_ has the value of the original _v_ ." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_ffreenexampleassociate3" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " fortranspecificend" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/notebook/Examples_async_target_depend.ipynb b/notebook/Examples_async_target_depend.ipynb deleted file mode 100644 index bad2686..0000000 --- a/notebook/Examples_async_target_depend.ipynb +++ /dev/null @@ -1,53 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Asynchronous `target` Execution and Dependences" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Asynchronous execution of a `target` region can be accomplished by creating an explicit task around the `target` region. Examples with explicit tasks are shown at the beginning of this section. " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " As of OpenMP 4.5 and beyond the `nowait` clause can be used on the `target` directive for asynchronous execution. Examples with `nowait` clauses follow the explicit `task` examples." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " This section also shows the use of `depend` clauses to order executions through dependences." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/notebook/Examples_async_target_nowait.ipynb b/notebook/Examples_async_target_nowait.ipynb deleted file mode 100644 index 8ce16db..0000000 --- a/notebook/Examples_async_target_nowait.ipynb +++ /dev/null @@ -1,78 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### `nowait` Clause on `target` Construct" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows how to execute code asynchronously on a device without an explicit task. The `nowait` clause on a `target` construct allows the thread of the _target task_ to perform other work while waiting for the `target` region execution to complete. Hence, the the `target` region can execute asynchronously on the device (without requiring a host thread to idle while waiting for the _target task_ execution to complete)." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In this example the product of two vectors (arrays), _v1_ and _v2_ , is formed. One half of the operations is performed on the device, and the last half on the host, concurrently." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " After a team of threads is formed the master thread generates the _target task_ while the other threads can continue on, without a barrier, to the execution of the host portion of the vector product. The completion of the _target task_ (asynchronous target execution) is guaranteed by the synchronization in the implicit barrier at the end of the host vector-product worksharing loop region. See the `barrier` glossary entry in the OpenMP specification for details." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The host loop scheduling is `dynamic` , to balance the host thread executions, since one thread is being used for offload generation. In the situation where little time is spent by the _target task_ in setting up and tearing down the the target execution, `static` scheduling may be desired. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_async_target.3.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_async_target.3.f90" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/notebook/Examples_async_target_nowait_depend.ipynb b/notebook/Examples_async_target_nowait_depend.ipynb deleted file mode 100644 index ecf7cec..0000000 --- a/notebook/Examples_async_target_nowait_depend.ipynb +++ /dev/null @@ -1,80 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"begin #### Asynchronous `target` with `nowait` and `depend` Clauses" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " More details on dependences can be found in , Task Dependences. In this example, there are three flow dependences. In the first two dependences the target task does not execute until the preceding explicit tasks have finished. These dependences are produced by arrays _v1_ and _v2_ with the `out` dependence type in the first two tasks, and the `in` dependence type in the target task. " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The last dependence is produced by array _p_ with the `out` dependence type in the target task, and the `in` dependence type in the last task. The last task does not execute until the target task finishes. " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `nowait` clause on the `target` construct creates a deferrable _target task_ , allowing the encountering task to continue execution without waiting for the completion of the _target task_ ." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_async_target.4.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_async_target.4.f90" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"end" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/notebook/Examples_async_target_with_tasks.ipynb b/notebook/Examples_async_target_with_tasks.ipynb deleted file mode 100644 index f0303fc..0000000 --- a/notebook/Examples_async_target_with_tasks.ipynb +++ /dev/null @@ -1,124 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### Asynchronous `target` with Tasks" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows how the `task` and `target` constructs are used to execute multiple `target` regions asynchronously. The task that encounters the `task` construct generates an explicit task that contains a `target` region. The thread executing the explicit task encounters a task scheduling point while waiting for the execution of the `target` region to complete, allowing the thread to switch back to the execution of the encountering task or one of the previously generated explicit tasks." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_async_target.1.c" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The Fortran version has an interface block that contains the `declare` `target` . An identical statement exists in the function declaration (not shown here)." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_async_target.1.f90" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows how the `task` and `target` constructs are used to execute multiple `target` regions asynchronously. The task dependence ensures that the storage is allocated and initialized on the device before it is accessed." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_async_target.2.c" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The Fortran example below is similar to the C version above. Instead of pointers, though, it uses the convenience of Fortran allocatable arrays on the device. In order to preserve the arrays allocated on the device across multiple `target` regions, a `target` ~ `data` region is used in this case." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " If there is no shape specified for an allocatable array in a `map` clause, only the array descriptor (also called a dope vector) is mapped. That is, device space is created for the descriptor, and it is initially populated with host values. In this case, the _v1_ and _v2_ arrays will be in a non-associated state on the device. When space for _v1_ and _v2_ is allocated on the device in the first `target` region the addresses to the space will be included in their descriptors." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " At the end of the first `target` region, the arrays _v1_ and _v2_ are preserved on the device for access in the second `target` region. At the end of the second `target` region, the data in array _p_ is copied back, the arrays _v1_ and _v2_ are not." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " A `depend` clause is used in the `task` directive to provide a wait at the beginning of the second `target` region, to insure that there is no race condition with _v1_ and _v2_ in the two tasks. It would be noncompliant to use _v1_ and/or _v2_ in lieu of _N_ in the `depend` clauses, because the use of non-allocated allocatable arrays as list items in a `depend` clause would lead to unspecified behavior. " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " noteheader{--} This example is not strictly compliant with the OpenMP 4.5 specification since the allocation status of allocatable arrays _v1_ and _v2_ is changed inside the `target` region, which is not allowed. (See the restrictions for the `map` clause in the _Data-mapping Attribute Rules and Clauses_ section of the specification.) However, the intention is to relax the restrictions on mapping of allocatable variables in the next release of the specification so that the example will be compliant." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_async_target.2.f90" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/notebook/Examples_atomic.ipynb b/notebook/Examples_atomic.ipynb deleted file mode 100644 index b252e0e..0000000 --- a/notebook/Examples_atomic.ipynb +++ /dev/null @@ -1,121 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### The `atomic` Construct" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example avoids race conditions (simultaneous updates of an element of _x_ by multiple threads) by using the `atomic` construct ." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The advantage of using the `atomic` construct in this example is that it allows updates of two different elements of _x_ to occur in parallel. If a `critical` construct were used instead, then all updates to elements of _x_ would be executed serially (though not in any guaranteed order)." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Note that the `atomic` directive applies only to the statement immediately following it. As a result, elements of _y_ are not updated atomically in this example." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_atomic.1.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_atomic.1.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example illustrates the `read` and `write` clauses for the `atomic` directive. These clauses ensure that the given variable is read or written, respectively, as a whole. Otherwise, some other thread might read or write part of the variable while the current thread was reading or writing another part of the variable. Note that most hardware provides atomic reads and writes for some set of properly aligned variables of specific sizes, but not necessarily for all the variable types supported by the OpenMP API." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_atomic.2.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_atomic.2.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example illustrates the `capture` clause for the `atomic` directive. In this case the value of a variable is captured, and then the variable is incremented. These operations occur atomically. This particular example could be implemented using the fetch-and-add instruction available on many kinds of hardware. The example also shows a way to implement a spin lock using the `capture` and `read` clauses." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_atomic.3.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_atomic.3.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/notebook/Examples_atomic_restrict.ipynb b/notebook/Examples_atomic_restrict.ipynb deleted file mode 100644 index 5b15dd5..0000000 --- a/notebook/Examples_atomic_restrict.ipynb +++ /dev/null @@ -1,105 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Restrictions on the `atomic` Construct" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following non-conforming examples illustrate the restrictions on the `atomic` construct. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_atomic_restrict.1.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_atomic_restrict.1.f" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_atomic_restrict.2.c" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " fortranspecificstart The following example is non-conforming because `I` and `R` reference the same location but have different types." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_atomic_restrict.2.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Although the following example might work on some implementations, this is also non-conforming:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_atomic_restrict.3.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " fortranspecificend" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/notebook/Examples_barrier_regions.ipynb b/notebook/Examples_barrier_regions.ipynb deleted file mode 100644 index 721ac64..0000000 --- a/notebook/Examples_barrier_regions.ipynb +++ /dev/null @@ -1,71 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Binding of `barrier` Regions" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The binding rules call for a `barrier` region to bind to the closest enclosing `parallel` region. " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the following example, the call from the main program to _sub2_ is conforming because the `barrier` region (in _sub3_ ) binds to the `parallel` region in _sub2_ . The call from the main program to _sub1_ is conforming because the `barrier` region binds to the `parallel` region in subroutine _sub2_ ." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The call from the main program to _sub3_ is conforming because the `barrier` region binds to the implicit inactive `parallel` region enclosing the sequential part. Also note that the `barrier` region in _sub3_ when called from _sub2_ only synchronizes the team of threads in the enclosing `parallel` region and not all the threads created in _sub1_ ." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_barrier_regions.1.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_barrier_regions.1.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/notebook/Examples_cancellation.ipynb b/notebook/Examples_cancellation.ipynb deleted file mode 100644 index fdf781e..0000000 --- a/notebook/Examples_cancellation.ipynb +++ /dev/null @@ -1,96 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Cancellation Constructs" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows how the `cancel` directive can be used to terminate an OpenMP region. Although the `cancel` construct terminates the OpenMP worksharing region, programmers must still track the exception through the pointer ex and issue a cancellation for the `parallel` region if an exception has been raised. The master thread checks the exception pointer to make sure that the exception is properly handled in the sequential part. If cancellation of the `parallel` region has been requested, some threads might have executed `phase_1()` . However, it is guaranteed that none of the threads executed `phase_2()` ." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_cancellation.1.cpp" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example illustrates the use of the `cancel` construct in error handling. If there is an error condition from the `allocate` statement, the cancellation is activated. The encountering thread sets the shared variable `err` and other threads of the binding thread set proceed to the end of the worksharing construct after the cancellation has been activated. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_cancellation.1.f90" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows how to cancel a parallel search on a binary tree as soon as the search value has been detected. The code creates a task to descend into the child nodes of the current tree node. If the search value has been found, the code remembers the tree node with the found value through an `atomic` write to the result variable and then cancels execution of all search tasks. The function `search_tree_parallel` groups all search tasks into a single task group to control the effect of the `cancel taskgroup` directive. The _level_ argument is used to create undeferred tasks after the first ten levels of the tree." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_cancellation.2.c" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following is the equivalent parallel search example in Fortran." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_cancellation.2.f90" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/notebook/Examples_carrays_fpriv.ipynb b/notebook/Examples_carrays_fpriv.ipynb deleted file mode 100644 index b6e9fc0..0000000 --- a/notebook/Examples_carrays_fpriv.ipynb +++ /dev/null @@ -1,124 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### C/C++ Arrays in a `firstprivate` Clause" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ccppspecificstart" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example illustrates the size and value of list items of array or pointer type in a `firstprivate` clause . The size of new list items is based on the type of the corresponding original list item, as determined by the base language." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In this example:" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* The type of `A` is array of two arrays of two ints." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* The type of `B` is adjusted to pointer to array of `n` ints, because it is a function parameter." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* The type of `C` is adjusted to pointer to int, because it is a function parameter." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* The type of `D` is array of two arrays of two ints." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* The type of `E` is array of `n` arrays of `n` ints. " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Note that `B` and `E` involve variable length array types." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The new items of array type are initialized as if each integer element of the original array is assigned to the corresponding element of the new array. Those of pointer type are initialized as if by assignment from the original \n", -"* to the new item." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_carrays_fpriv.1.c" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ccppspecificend" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/notebook/Examples_collapse.ipynb b/notebook/Examples_collapse.ipynb deleted file mode 100644 index 1a93c70..0000000 --- a/notebook/Examples_collapse.ipynb +++ /dev/null @@ -1,149 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### The `collapse` Clause" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the following example, the `k` and `j` loops are associated with the loop construct. So the iterations of the `k` and `j` loops are collapsed into one loop with a larger iteration space, and that loop is then divided among the threads in the current team. Since the `i` loop is not associated with the loop construct, it is not collapsed, and the `i` loop is executed sequentially in its entirety in every iteration of the collapsed `k` and `j` loop. " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The variable `j` can be omitted from the `private` clause when the `collapse` clause is used since it is implicitly private. However, if the `collapse` clause is omitted then `j` will be shared if it is omitted from the `private` clause. In either case, `k` is implicitly private and could be omitted from the `private` clause." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_collapse.1.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_collapse.1.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the next example, the `k` and `j` loops are associated with the loop construct. So the iterations of the `k` and `j` loops are collapsed into one loop with a larger iteration space, and that loop is then divided among the threads in the current team." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The sequential execution of the iterations in the `k` and `j` loops determines the order of the iterations in the collapsed iteration space. This implies that in the sequentially last iteration of the collapsed iteration space, `k` will have the value `2` and `j` will have the value `3` . Since `klast` and `jlast` are `lastprivate` , their values are assigned by the sequentially last iteration of the collapsed `k` and `j` loop. This example prints: `2 3` ." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_collapse.2.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_collapse.2.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The next example illustrates the interaction of the `collapse` and `ordered` clauses." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the example, the loop construct has both a `collapse` clause and an `ordered` clause. The `collapse` clause causes the iterations of the `k` and `j` loops to be collapsed into one loop with a larger iteration space, and that loop is divided among the threads in the current team. An `ordered` clause is added to the loop construct, because an ordered region binds to the loop region arising from the loop construct." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " According to Section 2.12.8 of the OpenMP 4.0 specification, a thread must not execute more than one ordered region that binds to the same loop region. So the `collapse` clause is required for the example to be conforming. With the `collapse` clause, the iterations of the `k` and `j` loops are collapsed into one loop, and therefore only one ordered region will bind to the collapsed `k` and `j` loop. Without the `collapse` clause, there would be two ordered regions that bind to each iteration of the `k` loop (one arising from the first iteration of the `j` loop, and the other arising from the second iteration of the `j` loop)." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The code prints" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " `0 1 1` `0 1 2` `0 2 1` `1 2 2` `1 3 1` `1 3 2` " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_collapse.3.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_collapse.3.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/notebook/Examples_cond_comp.ipynb b/notebook/Examples_cond_comp.ipynb deleted file mode 100644 index 8bb4087..0000000 --- a/notebook/Examples_cond_comp.ipynb +++ /dev/null @@ -1,78 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Conditional Compilation" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ccppspecificstart The following example illustrates the use of conditional compilation using the OpenMP macro `_OPENMP` . With OpenMP compilation, the `_OPENMP` macro becomes defined." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_cond_comp.1.c" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ccppspecificend" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " fortranspecificstart The following example illustrates the use of the conditional compilation sentinel. With OpenMP compilation, the conditional compilation sentinel `!$` is recognized and treated as two spaces. In fixed form source, statements guarded by the sentinel must start after column 6." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_cond_comp.1.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " fortranspecificend" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/notebook/Examples_copyin.ipynb b/notebook/Examples_copyin.ipynb deleted file mode 100644 index 04c740b..0000000 --- a/notebook/Examples_copyin.ipynb +++ /dev/null @@ -1,57 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### The `copyin` Clause" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `copyin` clause is used to initialize threadprivate data upon entry to a `parallel` region. The value of the threadprivate variable in the master thread is copied to the threadprivate variable of each other team member." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_copyin.1.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_copyin.1.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/notebook/Examples_copyprivate.ipynb b/notebook/Examples_copyprivate.ipynb deleted file mode 100644 index e9e36ea..0000000 --- a/notebook/Examples_copyprivate.ipynb +++ /dev/null @@ -1,135 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### The `copyprivate` Clause" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `copyprivate` clause can be used to broadcast values acquired by a single thread directly to all instances of the private variables in the other threads. In this example, if the routine is called from the sequential part, its behavior is not affected by the presence of the directives. If it is called from a `parallel` region, then the actual arguments with which `a` and `b` are associated must be private. " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The thread that executes the structured block associated with the `single` construct broadcasts the values of the private variables `a` , `b` , `x` , and `y` from its implicit task's data environment to the data environments of the other implicit tasks in the thread team. The broadcast completes before any of the threads have left the barrier at the end of the construct." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_copyprivate.1.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_copyprivate.1.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In this example, assume that the input must be performed by the master thread. Since the `master` construct does not support the `copyprivate` clause, it cannot broadcast the input value that is read. However, `copyprivate` is used to broadcast an address where the input value is stored." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_copyprivate.2.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_copyprivate.2.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Suppose that the number of lock variables required within a `parallel` region cannot easily be determined prior to entering it. The `copyprivate` clause can be used to provide access to shared lock variables that are allocated within that `parallel` region." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_copyprivate.3.c" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " fortranspecificstartfnexample{copyprivate}{3}" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Note that the effect of the `copyprivate` clause on a variable with the `allocatable` attribute is different than on a variable with the `pointer` attribute. The value of `A` is copied (as if by intrinsic assignment) and the pointer `B` is copied (as if by pointer assignment) to the corresponding list items in the other implicit tasks belonging to the `parallel` region. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_copyprivate.4.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " fortranspecificend" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/notebook/Examples_cpp_reference.ipynb b/notebook/Examples_cpp_reference.ipynb deleted file mode 100644 index b15f073..0000000 --- a/notebook/Examples_cpp_reference.ipynb +++ /dev/null @@ -1,66 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### C++ Reference in Data-Sharing Clauses" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_cppspecificstart" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " C++ reference types are allowed in data-sharing attribute clauses as of OpenMP 4.5, except for the `threadprivate` , `copyin` and `copyprivate` clauses. (See the Data-Sharing Attribute Clauses Section of the 4.5 OpenMP specification.) When a variable with C++ reference type is privatized, the object the reference refers to is privatized in addition to the reference itself. The following example shows the use of reference types in data-sharing clauses in the usual way. Additionally it shows how the data-sharing of formal arguments with a C++ reference type on an orphaned task generating construct is determined implicitly. (See the Data-sharing Attribute Rules for Variables Referenced in a Construct Section of the 4.5 OpenMP specification.)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_cppnexamplecpp_reference1" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_cppspecificend" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/notebook/Examples_critical.ipynb b/notebook/Examples_critical.ipynb deleted file mode 100644 index cc352e4..0000000 --- a/notebook/Examples_critical.ipynb +++ /dev/null @@ -1,82 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### The `critical` Construct" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example includes several `critical` constructs. The example illustrates a queuing model in which a task is dequeued and worked on. To guard against multiple threads dequeuing the same task, the dequeuing operation must be in a `critical` region. Because the two queues in this example are independent, they are protected by `critical` constructs with different names, _xaxis_ and _yaxis_ ." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_critical.1.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_critical.1.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example extends the previous example by adding the `hint` clause to the `critical` constructs." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_critical.2.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_critical.2.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/notebook/Examples_declare_target.ipynb b/notebook/Examples_declare_target.ipynb deleted file mode 100644 index 3129697..0000000 --- a/notebook/Examples_declare_target.ipynb +++ /dev/null @@ -1,326 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### `declare` `target` Construct" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### `declare` `target` and `end` `declare` `target` for a Function" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows how the `declare` `target` directive is used to indicate that the corresponding call inside a `target` region is to a `fib` function that can execute on the default target device." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " A version of the function is also available on the host device. When the `if` clause conditional expression on the `target` construct evaluates to _false_ , the `target` region (thus `fib` ) will execute on the host device." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " For C/C++ codes the declaration of the function `fib` appears between the `declare` `target` and `end` `declare` `target` directives." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_declare_target.1.c" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The Fortran `fib` subroutine contains a `declare` `target` declaration to indicate to the compiler to create an device executable version of the procedure. The subroutine name has not been included on the `declare` `target` directive and is, therefore, implicitly assumed." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The program uses the `module_fib` module, which presents an explicit interface to the compiler with the `declare` `target` declarations for processing the `fib` call." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_declare_target.1.f90" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The next Fortran example shows the use of an external subroutine. Without an explicit interface (through module use or an interface block) the `declare` `target` declarations within a external subroutine are unknown to the main program unit; therefore, a `declare` `target` must be provided within the program scope for the compiler to determine that a target binary should be available." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_declare_target.2.f90" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### `declare` `target` Construct for Class Type" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_cppspecificstart" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows how the `declare` `target` and `end` `declare` `target` directives are used to enclose the declaration of a variable _varY_ with a class type `typeY` . The member function `typeY::foo()` cannot be accessed on a target device because its declaration did not appear between `declare` `target` and `end` `declare` `target` directives." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_cppnexampledeclare_target2" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_cppspecificend" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### `declare` `target` and `end` `declare` `target` for Variables" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following examples show how the `declare` `target` and `end` `declare` `target` directives are used to indicate that global variables are mapped to the implicit device data environment of each target device." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the following example, the declarations of the variables _p_ , _v1_ , and _v2_ appear between `declare` `target` and `end` `declare` `target` directives indicating that the variables are mapped to the implicit device data environment of each target device. The `target` `update` directive is then used to manage the consistency of the variables _p_ , _v1_ , and _v2_ between the data environment of the encountering host device task and the implicit device data environment of the default target device." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_declare_target.3.c" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The Fortran version of the above C code uses a different syntax. Fortran modules use a list syntax on the `declare` `target` directive to declare mapped variables." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_declare_target.3.f90" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example also indicates that the function `Pfun()` is available on the target device, as well as the variable _Q_ , which is mapped to the implicit device data environment of each target device. The `target` `update` directive is then used to manage the consistency of the variable _Q_ between the data environment of the encountering host device task and the implicit device data environment of the default target device." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the following example, the function and variable declarations appear between the `declare` `target` and `end` `declare` `target` directives." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_declare_target.4.c" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The Fortran version of the above C code uses a different syntax. In Fortran modules a list syntax on the `declare` `target` directive is used to declare mapped variables and procedures. The _N_ and _Q_ variables are declared as a comma separated list. When the `declare` `target` directive is used to declare just the procedure, the procedure name need not be listed -- it is implicitly assumed, as illustrated in the `Pfun()` function." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_declare_target.4.f90" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### `declare` `target` and `end` `declare` `target` with `declare` `simd` " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows how the `declare` `target` and `end` `declare` `target` directives are used to indicate that a function is available on a target device. The `declare` `simd` directive indicates that there is a SIMD version of the function `P()` that is available on the target device as well as one that is available on the host device." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_declare_target.5.c" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The Fortran version of the above C code uses a different syntax. Fortran modules use a list syntax of the `declare` `target` declaration for the mapping. Here the _N_ and _Q_ variables are declared in the list form as a comma separated list. The function declaration does not use a list and implicitly assumes the function name. In this Fortran example row and column indices are reversed relative to the C/C++ example, as is usual for codes optimized for memory access." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_declare_target.5.f90" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### `declare` ~ `target` Directive with `link` Clause" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the OpenMP 4.5 standard the `declare` ~ `target` directive was extended to allow static data to be mapped, emph{when needed}, through a `link` clause." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Data storage for items listed in the `link` clause becomes available on the device when it is mapped implicitly or explicitly in a `map` clause, and it persists for the scope of the mapping (as specified by a `target` construct, a `target` ~ `data` construct, or `target` ~ `enter/exit` ~ `data` constructs)." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Tip: When all the global data items will not fit on a device and are not needed simultaneously, use the `link` clause and map the data only when it is needed." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following C and Fortran examples show two sets of data (single precision and double precision) that are global on the host for the entire execution on the host; but are only used globally on the device for part of the program execution. The single precision data are allocated and persist only for the first `target` region. Similarly, the double precision data are in scope on the device only for the second `target` region." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_declare_target.6.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_declare_target.6.f90" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/notebook/Examples_default_none.ipynb b/notebook/Examples_default_none.ipynb deleted file mode 100644 index 04d6d8c..0000000 --- a/notebook/Examples_default_none.ipynb +++ /dev/null @@ -1,71 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### The `default(none)` Clause" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example distinguishes the variables that are affected by the `default(none)` clause from those that are not. " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ccppspecificstart Beginning with OpenMP 4.0, variables with `const` -qualified type and no mutable member are no longer predetermined shared. Thus, these variables (variable _c_ in the example) need to be explicitly listed in data-sharing attribute clauses when the `default(none)` clause is specified." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_default_none.1.c" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ccppspecificend" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_default_none.1.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/notebook/Examples_device.ipynb b/notebook/Examples_device.ipynb deleted file mode 100644 index 6edeba5..0000000 --- a/notebook/Examples_device.ipynb +++ /dev/null @@ -1,172 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Device Routines" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### `omp_is_initial_device` Routine" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows how the `omp_is_initial_device` runtime library routine can be used to query if a code is executing on the initial host device or on a target device. The example then sets the number of threads in the `parallel` region based on where the code is executing." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_device.1.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_device.1.f90" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### `omp_get_num_devices` Routine" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows how the `omp_get_num_devices` runtime library routine can be used to determine the number of devices." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_device.2.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_device.2.f90" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "subsection{ `omp_set_default_device` and " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " `omp_get_default_device` Routines}" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows how the `omp_set_default_device` and `omp_get_default_device` runtime library routines can be used to set the default device and determine the default device respectively." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_device.3.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_device.3.f90" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### Target Memory and Device Pointers Routines" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows how to create space on a device, transfer data to and from that space, and free the space, using API calls. The API calls directly execute allocation, copy and free operations on the device, without invoking any mapping through a `target` directive. The `omp_target_alloc` routine allocates space and returns a device pointer for referencing the space in the `omp_target_memcpy` API routine on the host. The `omp_target_free` routine frees the space on the device." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The example also illustrates how to access that space in a `target` region by exposing the device pointer in an `is_device_ptr` clause." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The example creates an array of cosine values on the default device, to be used on the host device. The function fails if a default device is not available." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_device.4.c" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/notebook/Examples_doacross.ipynb b/notebook/Examples_doacross.ipynb deleted file mode 100644 index 9825f52..0000000 --- a/notebook/Examples_doacross.ipynb +++ /dev/null @@ -1,139 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Doacross Loop Nest" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " An `ordered` clause can be used on a loop construct with an integer parameter argument to define the number of associated loops within a _doacross loop nest_ where cross-iteration dependences exist. A `depend` clause on an `ordered` construct within an ordered loop describes the dependences of the _doacross_ loops. " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the code below, the `depend(sink:i-1)` clause defines an _i-1_ to _i_ cross-iteration dependence that specifies a wait point for the completion of computation from iteration _i-1_ before proceeding to the subsequent statements. The `depend(source)` clause indicates the completion of computation from the current iteration ( _i_ ) to satisfy the cross-iteration dependence that arises from the iteration. For this example the same sequential ordering could have been achieved with an `ordered` clause without a parameter, on the loop directive, and a single `ordered` directive without the `depend` clause specified for the statement executing the _bar_ function." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_doacross.1.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_doacross.1.f90" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following code is similar to the previous example but with _doacross loop nest_ extended to two nested loops, _i_ and _j_ , as specified by the `ordered(2)` clause on the loop directive. In the C/C++ code, the _i_ and _j_ loops are the first and second associated loops, respectively, whereas in the Fortran code, the _j_ and _i_ loops are the first and second associated loops, respectively. The `depend(sink:i-1,j)` and `depend(sink:i,j-1)` clauses in the C/C++ code define cross-iteration dependences in two dimensions from iterations ( _i-1, j_ ) and ( _i, j-1_ ) to iteration ( _i, j_ ). Likewise, the `depend(sink:j-1,i)` and `depend(sink:j,i-1)` clauses in the Fortran code define cross-iteration dependences from iterations ( _j-1, i_ ) and ( _j, i-1_ ) to iteration ( _j, i_ )." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_doacross.2.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_doacross.2.f90" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows the incorrect use of the `ordered` directive with a `depend` clause. There are two issues with the code. The first issue is a missing `ordered` ~ `depend(source)` directive, which could cause a deadlock. The second issue is the `depend(sink:i+1,j)` and `depend(sink:i,j+1)` clauses define dependences on lexicographically later source iterations ( _i+1, j_ ) and ( _i, j+1_ ), which could cause a deadlock as well since they may not start to execute until the current iteration completes." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_doacross.3.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_doacross.3.f90" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example illustrates the use of the `collapse` clause for a _doacross loop nest_ . The _i_ and _j_ loops are the associated loops for the collapsed loop as well as for the _doacross loop nest_ . The example also shows a compliant usage of the dependence source directive placed before the corresponding sink directive. Checking the completion of computation from previous iterations at the sink point can occur after the source statement." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_doacross.4.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_doacross.4.f90" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/notebook/Examples_flush_nolist.ipynb b/notebook/Examples_flush_nolist.ipynb deleted file mode 100644 index 585c6f0..0000000 --- a/notebook/Examples_flush_nolist.ipynb +++ /dev/null @@ -1,57 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### The `flush` Construct without a List" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example distinguishes the shared variables affected by a `flush` construct with no list from the shared objects that are not affected:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_flush_nolist.1.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_flush_nolist.1.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/notebook/Examples_fort_do.ipynb b/notebook/Examples_fort_do.ipynb deleted file mode 100644 index 5df04ce..0000000 --- a/notebook/Examples_fort_do.ipynb +++ /dev/null @@ -1,78 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Fortran Restrictions on the `do` Construct" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " fortranspecificstart" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " If an `end do` directive follows a _do-construct_ in which several `DO` statements share a `DO` termination statement, then a `do` directive can only be specified for the outermost of these `DO` statements. The following example contains correct usages of loop constructs:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_fort_do.1.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example is non-conforming because the matching `do` directive for the `end do` does not precede the outermost loop:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_fort_do.2.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " fortranspecificend" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/notebook/Examples_fort_loopvar.ipynb b/notebook/Examples_fort_loopvar.ipynb deleted file mode 100644 index be2576a..0000000 --- a/notebook/Examples_fort_loopvar.ipynb +++ /dev/null @@ -1,78 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Fortran Private Loop Iteration Variables" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " fortranspecificstart" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In general loop iteration variables will be private, when used in the _do-loop_ of a `do` and `parallel do` construct or in sequential loops in a `parallel` construct (see Section 2.7.1 and Section 2.14.1 of the OpenMP 4.0 specification). In the following example of a sequential loop in a `parallel` construct the loop iteration variable _I_ will be private." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_ffreenexamplefort_loopvar1" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In exceptional cases, loop iteration variables can be made shared, as in the following example:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_ffreenexamplefort_loopvar2" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Note however that the use of shared loop iteration variables can easily lead to race conditions. fortranspecificend" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/notebook/Examples_fort_race.ipynb b/notebook/Examples_fort_race.ipynb deleted file mode 100644 index c77abdf..0000000 --- a/notebook/Examples_fort_race.ipynb +++ /dev/null @@ -1,62 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Race Conditions Caused by Implied Copies of Shared Variables in Fortran" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " fortranspecificstart" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example contains a race condition, because the shared variable, which is an array section, is passed as an actual argument to a routine that has an assumed-size array as its dummy argument. The subroutine call passing an array section argument may cause the compiler to copy the argument into a temporary location prior to the call and copy from the temporary location into the original variable when the subroutine returns. This copying would cause races in the `parallel` region." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_ffreenexamplefort_race1" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " fortranspecificend" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/notebook/Examples_fort_sa_private.ipynb b/notebook/Examples_fort_sa_private.ipynb deleted file mode 100644 index 31e9042..0000000 --- a/notebook/Examples_fort_sa_private.ipynb +++ /dev/null @@ -1,106 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Fortran Restrictions on Storage Association with the `private` Clause" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " fortranspecificstart" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following non-conforming examples illustrate the implications of the `private` clause rules with regard to storage association. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_fort_sa_private.1.f" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_fort_sa_private.2.f" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_fort_sa_private.3.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -" blue line floater at top of this page for 'Fortran, cont.' [t!] linewitharrows{-1}{dashed}{Fortran (cont.)}{8em} " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_fort_sa_private.4.f" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_fort_sa_private.5.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " fortranspecificend" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/notebook/Examples_fort_sp_common.ipynb b/notebook/Examples_fort_sp_common.ipynb deleted file mode 100644 index 367e96e..0000000 --- a/notebook/Examples_fort_sp_common.ipynb +++ /dev/null @@ -1,141 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Fortran Restrictions on `shared` and `private` Clauses with Common Blocks" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " fortranspecificstart" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " When a named common block is specified in a `private` , `firstprivate` , or `lastprivate` clause of a construct, none of its members may be declared in another data-sharing attribute clause on that construct. The following examples illustrate this point. " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example is conforming:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_fort_sp_common.1.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example is also conforming:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_fort_sp_common.2.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -" blue line floater at top of this page for 'Fortran, cont.' [t!] linewitharrows{-1}{dashed}{Fortran (cont.)}{8em} " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example is conforming:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_fort_sp_common.3.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example is non-conforming because `x` is a constituent element of `c` :" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_fort_sp_common.4.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example is non-conforming because a common block may not be declared both shared and private:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_fort_sp_common.5.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " fortranspecificend" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/notebook/Examples_fpriv_sections.ipynb b/notebook/Examples_fpriv_sections.ipynb deleted file mode 100644 index 16adcc4..0000000 --- a/notebook/Examples_fpriv_sections.ipynb +++ /dev/null @@ -1,57 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### The `firstprivate` Clause and the `sections` Construct" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the following example of the `sections` construct the `firstprivate` clause is used to initialize the private copy of `section_count` of each thread. The problem is that the `section` constructs modify `section_count` , which breaks the independence of the `section` constructs. When different threads execute each section, both sections will print the value 1. When the same thread executes the two sections, one section will print the value 1 and the other will print the value 2. Since the order of execution of the two sections in this case is unspecified, it is unspecified which section prints which value. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_fpriv_sections.1.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_fpriv_sections.1.f90" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/notebook/Examples_get_nthrs.ipynb b/notebook/Examples_get_nthrs.ipynb deleted file mode 100644 index 5ebddf1..0000000 --- a/notebook/Examples_get_nthrs.ipynb +++ /dev/null @@ -1,82 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### The `omp_get_num_threads` Routine" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the following example, the `omp_get_num_threads` call returns 1 in the sequential part of the code, so `np` will always be equal to 1. To determine the number of threads that will be deployed for the `parallel` region, the call should be inside the `parallel` region." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_get_nthrs.1.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_get_nthrs.1.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows how to rewrite this program without including a query for the number of threads:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_get_nthrs.2.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_get_nthrs.2.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/notebook/Examples_icv.ipynb b/notebook/Examples_icv.ipynb deleted file mode 100644 index d5a5a8b..0000000 --- a/notebook/Examples_icv.ipynb +++ /dev/null @@ -1,113 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Internal Control Variables (ICVs)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " According to Section 2.3 of the OpenMP 4.0 specification, an OpenMP implementation must act as if there are ICVs that control the behavior of the program. This example illustrates two ICVs, _nthreads-var_ and _max-active-levels-var_ . The _nthreads-var_ ICV controls the number of threads requested for encountered parallel regions; there is one copy of this ICV per task. The _max-active-levels-var_ ICV controls the maximum number of nested active parallel regions; there is one copy of this ICV for the whole program." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the following example, the _nest-var_ , _max-active-levels-var_ , _dyn-var_ , and _nthreads-var_ ICVs are modified through calls to the runtime library routines `omp_set_nested` , `omp_set_max_active_levels` , ` omp_set_dynamic` , and `omp_set_num_threads` respectively. These ICVs affect the operation of `parallel` regions. Each implicit task generated by a `parallel` region has its own copy of the _nest-var, dyn-var_ , and _nthreads-var_ ICVs." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the following example, the new value of _nthreads-var_ applies only to the implicit tasks that execute the call to `omp_set_num_threads` . There is one copy of the _max-active-levels-var_ ICV for the whole program and its value is the same for all tasks. This example assumes that nested parallelism is supported." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The outer `parallel` region creates a team of two threads; each of the threads will execute one of the two implicit tasks generated by the outer `parallel` region." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Each implicit task generated by the outer `parallel` region calls `omp_set_num_threads(3)` , assigning the value 3 to its respective copy of _nthreads-var_ . Then each implicit task encounters an inner `parallel` region that creates a team of three threads; each of the threads will execute one of the three implicit tasks generated by that inner `parallel` region." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Since the outer `parallel` region is executed by 2 threads, and the inner by 3, there will be a total of 6 implicit tasks generated by the two inner `parallel` regions." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Each implicit task generated by an inner `parallel` region will execute the call to `omp_set_num_threads(4)` , assigning the value 4 to its respective copy of _nthreads-var_ ." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The print statement in the outer `parallel` region is executed by only one of the threads in the team. So it will be executed only once." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The print statement in an inner `parallel` region is also executed by only one of the threads in the team. Since we have a total of two inner `parallel` regions, the print statement will be executed twice -- once per inner `parallel` region." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_icv.1.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_icv.1.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/notebook/Examples_init_lock.ipynb b/notebook/Examples_init_lock.ipynb deleted file mode 100644 index cb0f115..0000000 --- a/notebook/Examples_init_lock.ipynb +++ /dev/null @@ -1,57 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### The `omp_init_lock` Routine" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example demonstrates how to initialize an array of locks in a `parallel` region by using `omp_init_lock` ." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_init_lock.1.cpp" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_init_lock.1.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/notebook/Examples_init_lock_with_hint.ipynb b/notebook/Examples_init_lock_with_hint.ipynb deleted file mode 100644 index 009009a..0000000 --- a/notebook/Examples_init_lock_with_hint.ipynb +++ /dev/null @@ -1,58 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -" #### The `omp_init_lock_with_hint` Routine" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example demonstrates how to initialize an array of locks in a `parallel` region by using `omp_init_lock_with_hint` . Note, hints are combined with an `|` or `+` operator in C/C++ and a `+` operator in Fortran." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_init_lock_with_hint.1.cpp" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_init_lock_with_hint.1.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/notebook/Examples_lastprivate.ipynb b/notebook/Examples_lastprivate.ipynb deleted file mode 100644 index 1df880b..0000000 --- a/notebook/Examples_lastprivate.ipynb +++ /dev/null @@ -1,57 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### The `lastprivate` Clause" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Correct execution sometimes depends on the value that the last iteration of a loop assigns to a variable. Such programs must list all such variables in a `lastprivate` clause so that the values of the variables are the same as when the loop is executed sequentially." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_lastprivate.1.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_lastprivate.1.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/notebook/Examples_linear_in_loop.ipynb b/notebook/Examples_linear_in_loop.ipynb deleted file mode 100644 index 1707780..0000000 --- a/notebook/Examples_linear_in_loop.ipynb +++ /dev/null @@ -1,57 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### `linear` Clause in Loop Constructs" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows the use of the `linear` clause in a loop construct to allow the proper parallelization of a loop that contains an induction variable ( _j_ ). At the end of the execution of the loop construct, the original variable _j_ is updated with the value _N/2_ from the last iteration of the loop." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_linear_in_loop.1.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_linear_in_loop.1.f90" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/notebook/Examples_lock_owner.ipynb b/notebook/Examples_lock_owner.ipynb deleted file mode 100644 index cede008..0000000 --- a/notebook/Examples_lock_owner.ipynb +++ /dev/null @@ -1,64 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### Ownership of Locks" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Ownership of locks has changed since OpenMP 2.5. In OpenMP 2.5, locks are owned by threads; so a lock released by the `omp_unset_lock` routine must be owned by the same thread executing the routine. Beginning with OpenMP 3.0, locks are owned by task regions; so a lock released by the `omp_unset_lock` routine in a task region must be owned by the same task region." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " This change in ownership requires extra care when using locks. The following program is conforming in OpenMP 2.5 because the thread that releases the lock `lck` in the parallel region is the same thread that acquired the lock in the sequential part of the program (master thread of parallel region and the initial thread are the same). However, it is not conforming beginning with OpenMP 3.0, because the task region that releases the lock `lck` is different from the task region that acquires the lock." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_lock_owner.1.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_lock_owner.1.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/notebook/Examples_locks.ipynb b/notebook/Examples_locks.ipynb deleted file mode 100644 index 35f5477..0000000 --- a/notebook/Examples_locks.ipynb +++ /dev/null @@ -1,39 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Lock Routines" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " This section is about the use of lock routines for synchronization." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/notebook/Examples_master.ipynb b/notebook/Examples_master.ipynb deleted file mode 100644 index 997c2ac..0000000 --- a/notebook/Examples_master.ipynb +++ /dev/null @@ -1,57 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### The `master` Construct" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example demonstrates the master construct . In the example, the master keeps track of how many iterations have been executed and prints out a progress report. The other threads skip the master region without waiting." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_master.1.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_master.1.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/notebook/Examples_mem_model.ipynb b/notebook/Examples_mem_model.ipynb deleted file mode 100644 index 01d4d3e..0000000 --- a/notebook/Examples_mem_model.ipynb +++ /dev/null @@ -1,114 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### The OpenMP Memory Model" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the following example, at Print 1, the value of _x_ could be either 2 or 5, depending on the timing of the threads, and the implementation of the assignment to _x_ . There are two reasons that the value at Print 1 might not be 5. First, Print 1 might be executed before the assignment to _x_ is executed. Second, even if Print 1 is executed after the assignment, the value 5 is not guaranteed to be seen by thread 1 because a flush may not have been executed by thread 0 since the assignment." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The barrier after Print 1 contains implicit flushes on all threads, as well as a thread synchronization, so the programmer is guaranteed that the value 5 will be printed by both Print 2 and Print 3." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_mem_model.1.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_mem_model.1.f90" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example demonstrates why synchronization is difficult to perform correctly through variables. The value of flag is undefined in both prints on thread 1 and the value of data is only well-defined in the second print." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_mem_model.2.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_mem_model.2.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The next example demonstrates why synchronization is difficult to perform correctly through variables. Because the _write_ (1)- _flush_ (1)- _flush_ (2)- _read_ (2) sequence cannot be guaranteed in the example, the statements on thread 0 and thread 1 may execute in either order." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_mem_model.3.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_mem_model.3.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/notebook/Examples_nestable_lock.ipynb b/notebook/Examples_nestable_lock.ipynb deleted file mode 100644 index 3e7316c..0000000 --- a/notebook/Examples_nestable_lock.ipynb +++ /dev/null @@ -1,57 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### Nestable Lock Routines" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example demonstrates how a nestable lock can be used to synchronize updates both to a whole structure and to one of its members." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_nestable_lock.1.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_nestable_lock.1.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/notebook/Examples_nested_loop.ipynb b/notebook/Examples_nested_loop.ipynb deleted file mode 100644 index 3388eb9..0000000 --- a/notebook/Examples_nested_loop.ipynb +++ /dev/null @@ -1,82 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Nested Loop Constructs" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example of loop construct nesting is conforming because the inner and outer loop regions bind to different `parallel` regions:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_nested_loop.1.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_nested_loop.1.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following variation of the preceding example is also conforming:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_nested_loop.2.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_nested_loop.2.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/notebook/Examples_nesting_restrict.ipynb b/notebook/Examples_nesting_restrict.ipynb deleted file mode 100644 index 52b4689..0000000 --- a/notebook/Examples_nesting_restrict.ipynb +++ /dev/null @@ -1,189 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Restrictions on Nesting of Regions" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The examples in this section illustrate the region nesting rules. " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example is non-conforming because the inner and outer loop regions are closely nested:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_nesting_restrict.1.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_nesting_restrict.1.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following orphaned version of the preceding example is also non-conforming:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_nesting_restrict.2.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_nesting_restrict.2.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example is non-conforming because the loop and `single` regions are closely nested:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_nesting_restrict.3.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_nesting_restrict.3.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example is non-conforming because a `barrier` region cannot be closely nested inside a loop region:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_nesting_restrict.4.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_nesting_restrict.4.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example is non-conforming because the `barrier` region cannot be closely nested inside the `critical` region. If this were permitted, it would result in deadlock due to the fact that only one thread at a time can enter the `critical` region:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_nesting_restrict.5.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_nesting_restrict.5.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example is non-conforming because the `barrier` region cannot be closely nested inside the `single` region. If this were permitted, it would result in deadlock due to the fact that only one thread executes the `single` region:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_nesting_restrict.6.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_nesting_restrict.6.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/notebook/Examples_nowait.ipynb b/notebook/Examples_nowait.ipynb deleted file mode 100644 index d44cc29..0000000 --- a/notebook/Examples_nowait.ipynb +++ /dev/null @@ -1,89 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### The `nowait` Clause" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " If there are multiple independent loops within a `parallel` region, you can use the `nowait` clause to avoid the implied barrier at the end of the loop construct, as follows:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_nowait.1.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_nowait.1.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the following example, static scheduling distributes the same logical iteration numbers to the threads that execute the three loop regions. This allows the `nowait` clause to be used, even though there is a data dependence between the loops. The dependence is satisfied as long the same thread executes the same logical iteration numbers in each loop." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Note that the iteration count of the loops must be the same. The example satisfies this requirement, since the iteration space of the first two loops is from `0` to `n-1` (from `1` to `N` in the Fortran version), while the iteration space of the last loop is from `1` to `n` ( `2` to `N+1` in the Fortran version)." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_nowait.2.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_nowait.2.f90" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/notebook/Examples_nthrs_dynamic.ipynb b/notebook/Examples_nthrs_dynamic.ipynb deleted file mode 100644 index a4a3153..0000000 --- a/notebook/Examples_nthrs_dynamic.ipynb +++ /dev/null @@ -1,96 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Interaction Between the `num_threads` Clause and `omp_set_dynamic` " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example demonstrates the `num_threads` clause and the effect of the `omp_set_dynamic` routine on it." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The call to the `omp_set_dynamic` routine with argument `0` in C/C++, or `.FALSE.` in Fortran, disables the dynamic adjustment of the number of threads in OpenMP implementations that support it. In this case, 10 threads are provided. Note that in case of an error the OpenMP implementation is free to abort the program or to supply any number of threads available." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_nthrs_dynamic.1.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_nthrs_dynamic.1.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The call to the `omp_set_dynamic` routine with a non-zero argument in C/C++, or `.TRUE.` in Fortran, allows the OpenMP implementation to choose any number of threads between 1 and 10." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_nthrs_dynamic.2.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_nthrs_dynamic.2.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " It is good practice to set the _dyn-var_ ICV explicitly by calling the `omp_set_dynamic` routine, as its default setting is implementation defined." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/notebook/Examples_nthrs_nesting.ipynb b/notebook/Examples_nthrs_nesting.ipynb deleted file mode 100644 index 023e663..0000000 --- a/notebook/Examples_nthrs_nesting.ipynb +++ /dev/null @@ -1,57 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Controlling the Number of Threads on Multiple Nesting Levels" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following examples demonstrate how to use the `OMP_NUM_THREADS` environment variable to control the number of threads on multiple nesting levels:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_nthrs_nesting.1.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_nthrs_nesting.1.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/notebook/Examples_ordered.ipynb b/notebook/Examples_ordered.ipynb deleted file mode 100644 index 40f9d55..0000000 --- a/notebook/Examples_ordered.ipynb +++ /dev/null @@ -1,107 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### The `ordered` Clause and the `ordered` Construct" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Ordered constructs are useful for sequentially ordering the output from work that is done in parallel. The following program prints out the indices in sequential order:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_ordered.1.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_ordered.1.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " It is possible to have multiple `ordered` constructs within a loop region with the `ordered` clause specified. The first example is non-conforming because all iterations execute two `ordered` regions. An iteration of a loop must not execute more than one `ordered` region:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_ordered.2.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_ordered.2.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following is a conforming example with more than one `ordered` construct. Each iteration will execute only one `ordered` region:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_ordered.3.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_ordered.3.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/notebook/Examples_parallel.ipynb b/notebook/Examples_parallel.ipynb deleted file mode 100644 index 7dc91f3..0000000 --- a/notebook/Examples_parallel.ipynb +++ /dev/null @@ -1,57 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### The `parallel` Construct" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `parallel` construct can be used in coarse-grain parallel programs. In the following example, each thread in the `parallel` region decides what part of the global array _x_ to work on, based on the thread number:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_parallel.1.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_parallel.1.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/notebook/Examples_ploop.ipynb b/notebook/Examples_ploop.ipynb deleted file mode 100644 index d3c117a..0000000 --- a/notebook/Examples_ploop.ipynb +++ /dev/null @@ -1,57 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### A Simple Parallel Loop" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example demonstrates how to parallelize a simple loop using the parallel loop construct. The loop iteration variable is private by default, so it is not necessary to specify it explicitly in a `private` clause." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_ploop.1.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_ploop.1.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/notebook/Examples_pra_iterator.ipynb b/notebook/Examples_pra_iterator.ipynb deleted file mode 100644 index 5675158..0000000 --- a/notebook/Examples_pra_iterator.ipynb +++ /dev/null @@ -1,66 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Parallel Random Access Iterator Loop" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_cppspecificstart" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows a parallel random access iterator loop." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_cppnexamplepra_iterator1" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_cppspecificend" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/notebook/Examples_private.ipynb b/notebook/Examples_private.ipynb deleted file mode 100644 index f59764f..0000000 --- a/notebook/Examples_private.ipynb +++ /dev/null @@ -1,110 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### The `private` Clause" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the following example, the values of original list items _i_ and _j_ are retained on exit from the `parallel` region, while the private list items _i_ and _j_ are modified within the `parallel` construct. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_private.1.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_private.1.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the following example, all uses of the variable _a_ within the loop construct in the routine _f_ refer to a private list \n", -"* _a_ , while it is unspecified whether references to _a_ in the routine _g_ are to a private list \n", -"* or the original list item." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_private.2.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_private.2.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example demonstrates that a list \n", -"* that appears in a `private` clause in a `parallel` construct may also appear in a `private` clause in an enclosed worksharing construct, which results in an additional private copy." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_private.3.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_private.3.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/notebook/Examples_psections.ipynb b/notebook/Examples_psections.ipynb deleted file mode 100644 index 8a03236..0000000 --- a/notebook/Examples_psections.ipynb +++ /dev/null @@ -1,57 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### The `parallel` `sections` Construct" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the following example routines `XAXIS` , `YAXIS` , and `ZAXIS` can be executed concurrently. The first `section` directive is optional. Note that all `section` directives need to appear in the `parallel sections` construct." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_psections.1.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_psections.1.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/notebook/Examples_reduction.ipynb b/notebook/Examples_reduction.ipynb deleted file mode 100644 index 20353a3..0000000 --- a/notebook/Examples_reduction.ipynb +++ /dev/null @@ -1,202 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### The `reduction` Clause" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example demonstrates the `reduction` clause ; note that some reductions can be expressed in the loop in several ways, as shown for the `max` and `min` reductions below:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_reduction.1.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_reduction.1.f90" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " A common implementation of the preceding example is to treat it as if it had been written as follows:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_reduction.2.c" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " fortranspecificstartffreenexample{reduction}{2}" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following program is non-conforming because the reduction is on the emph{intrinsic procedure name} `MAX` but that name has been redefined to be the variable named `MAX` ." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_ffreenexamplereduction3" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -" blue line floater at top of this page for 'Fortran, cont.' [t!] linewitharrows{-1}{dashed}{Fortran (cont.)}{8em} " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following conforming program performs the reduction using the emph{intrinsic procedure name} `MAX` even though the intrinsic `MAX` has been renamed to `REN` ." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_ffreenexamplereduction4" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following conforming program performs the reduction using _intrinsic procedure name_ `MAX` even though the intrinsic `MAX` has been renamed to `MIN` ." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_ffreenexamplereduction5" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " fortranspecificend" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example is non-conforming because the initialization ( `a = 0` ) of the original list \n", -"* `a` is not synchronized with the update of `a` as a result of the reduction computation in the `for` loop. Therefore, the example may print an incorrect value for `a` ." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " To avoid this problem, the initialization of the original list \n", -"* `a` should complete before any update of `a` as a result of the `reduction` clause. This can be achieved by adding an explicit barrier after the assignment `a = 0` , or by enclosing the assignment `a = 0` in a `single` directive (which has an implied barrier), or by initializing `a` before the start of the `parallel` region." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_reduction.6.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_reduction.6.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example demonstrates the reduction of array _a_ . In C/C++ this is illustrated by the explicit use of an array section _a[0:N]_ in the `reduction` clause. The corresponding Fortran example uses array syntax supported in the base language. As of the OpenMP 4.5 specification the explicit use of array section in the `reduction` clause in Fortran is not permitted. But this oversight will be fixed in the next release of the specification." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_reduction.7.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_reduction.7.f90" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/notebook/Examples_set_dynamic_nthrs.ipynb b/notebook/Examples_set_dynamic_nthrs.ipynb deleted file mode 100644 index 500d9a9..0000000 --- a/notebook/Examples_set_dynamic_nthrs.ipynb +++ /dev/null @@ -1,71 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "section{The `omp_set_dynamic` and " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " `omp_set_num_threads` Routines}" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Some programs rely on a fixed, prespecified number of threads to execute correctly. Because the default setting for the dynamic adjustment of the number of threads is implementation defined, such programs can choose to turn off the dynamic threads capability and set the number of threads explicitly to ensure portability. The following example shows how to do this using `omp_set_dynamic` , and `omp_set_num_threads` ." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In this example, the program executes correctly only if it is executed by 16 threads. If the implementation is not capable of supporting 16 threads, the behavior of this example is implementation defined. Note that the number of threads executing a `parallel` region remains constant during the region, regardless of the dynamic threads setting. The dynamic threads mechanism determines the number of threads to use at the start of the `parallel` region and keeps it constant for the duration of the region." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_set_dynamic_nthrs.1.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_set_dynamic_nthrs.1.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/notebook/Examples_simple_lock.ipynb b/notebook/Examples_simple_lock.ipynb deleted file mode 100644 index 97b3e7a..0000000 --- a/notebook/Examples_simple_lock.ipynb +++ /dev/null @@ -1,71 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### Simple Lock Routines" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the following example, the lock routines cause the threads to be idle while waiting for entry to the first critical section, but to do other work while waiting for entry to the second. The `omp_set_lock` function blocks, but the `omp_test_lock` function does not, allowing the work in `skip` to be done. " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Note that the argument to the lock routines should have type `omp_lock_t` , and that there is no need to flush it. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_simple_lock.1.c" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Note that there is no need to flush the lock variable. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_simple_lock.1.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/notebook/Examples_single.ipynb b/notebook/Examples_single.ipynb deleted file mode 100644 index ef54dcc..0000000 --- a/notebook/Examples_single.ipynb +++ /dev/null @@ -1,57 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### The `single` Construct" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example demonstrates the `single` construct. In the example, only one thread prints each of the progress messages. All other threads will skip the `single` region and stop at the barrier at the end of the `single` construct until all threads in the team have reached the barrier. If other threads can proceed without waiting for the thread executing the `single` region, a `nowait` clause can be specified, as is done in the third `single` construct in this example. The user must not make any assumptions as to which thread will execute a `single` region." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_single.1.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_single.1.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/notebook/Examples_standalone.ipynb b/notebook/Examples_standalone.ipynb deleted file mode 100644 index 7adcded..0000000 --- a/notebook/Examples_standalone.ipynb +++ /dev/null @@ -1,103 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "section{Placement of `flush` , `barrier` , `taskwait` " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " and `taskyield` Directives}" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example is non-conforming, because the `flush` , `barrier` , `taskwait` , and `taskyield` directives are stand-alone directives and cannot be the immediate substatement of an `if` statement. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_standalone.1.c" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example is non-conforming, because the `flush` , `barrier` , `taskwait` , and `taskyield` directives are stand-alone directives and cannot be the action statement of an `if` statement or a labeled branch target." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_standalone.1.f90" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following version of the above example is conforming because the `flush` , `barrier` , `taskwait` , and `taskyield` directives are enclosed in a compound statement. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_standalone.2.c" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example is conforming because the `flush` , `barrier` , `taskwait` , and `taskyield` directives are enclosed in an `if` construct or follow the labeled branch target." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_standalone.2.f90" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/notebook/Examples_target.ipynb b/notebook/Examples_target.ipynb deleted file mode 100644 index 21343ae..0000000 --- a/notebook/Examples_target.ipynb +++ /dev/null @@ -1,282 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### `target` Construct" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### `target` Construct on `parallel` Construct" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " This following example shows how the `target` construct offloads a code region to a target device. The variables _p_ , _v1_ , _v2_ , and _N_ are implicitly mapped to the target device." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target.1.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target.1.f90" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### `target` Construct with `map` Clause" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " This following example shows how the `target` construct offloads a code region to a target device. The variables _p_ , _v1_ and _v2_ are explicitly mapped to the target device using the `map` clause. The variable _N_ is implicitly mapped to the target device." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target.2.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target.2.f90" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### `map` Clause with `to` / `from` map-types" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows how the `target` construct offloads a code region to a target device. In the `map` clause, the `to` and `from` map-types define the mapping between the original (host) data and the target (device) data. The `to` map-type specifies that the data will only be read on the device, and the `from` map-type specifies that the data will only be written to on the device. By specifying a guaranteed access on the device, data transfers can be reduced for the `target` region." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `to` map-type indicates that at the start of the `target` region the variables _v1_ and _v2_ are initialized with the values of the corresponding variables on the host device, and at the end of the `target` region the variables _v1_ and _v2_ are not assigned to their corresponding variables on the host device." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `from` map-type indicates that at the start of the `target` region the variable _p_ is not initialized with the value of the corresponding variable on the host device, and at the end of the `target` region the variable _p_ is assigned to the corresponding variable on the host device." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target.3.c" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `to` and `from` map-types allow programmers to optimize data motion. Since data for the _v_ arrays are not returned, and data for the _p_ array are not transferred to the device, only one-half of the data is moved, compared to the default behavior of an implicit mapping." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target.3.f90" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### `map` Clause with Array Sections" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows how the `target` construct offloads a code region to a target device. In the `map` clause, map-types are used to optimize the mapping of variables to the target device. Because variables _p_ , _v1_ and _v2_ are pointers, array section notation must be used to map the arrays. The notation `:N` is equivalent to `0:N` ." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target.4.c" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In C, the length of the pointed-to array must be specified. In Fortran the extent of the array is known and the length need not be specified. A section of the array can be specified with the usual Fortran syntax, as shown in the following example. The value 1 is assumed for the lower bound for array section _v2(:N)_ ." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target.4.f90" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " A more realistic situation in which an assumed-size array is passed to `vec_mult` requires that the length of the arrays be specified, because the compiler does not know the size of the storage. A section of the array must be specified with the usual Fortran syntax, as shown in the following example. The value 1 is assumed for the lower bound for array section _v2(:N)_ ." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target.4b.f90" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### `target` Construct with `if` Clause" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows how the `target` construct offloads a code region to a target device." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `if` clause on the `target` construct indicates that if the variable _N_ is smaller than a given threshold, then the `target` region will be executed by the host device." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `if` clause on the `parallel` construct indicates that if the variable _N_ is smaller than a second threshold then the `parallel` region is inactive." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target.5.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target.5.f90" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example is a modification of the above _target.5_ code to show the combined `target` and parallel loop directives. It uses the _directive-name_ modifier in multiple `if` clauses to specify the component directive to which it applies. " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `if` clause with the `target` modifier applies to the `target` component of the combined directive, and the `if` clause with the `parallel` modifier applies to the `parallel` component of the combined directive. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target.6.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target.6.f90" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/notebook/Examples_target_data.ipynb b/notebook/Examples_target_data.ipynb deleted file mode 100644 index 384c6a2..0000000 --- a/notebook/Examples_target_data.ipynb +++ /dev/null @@ -1,340 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### `target` `data` Construct" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### Simple `target` `data` Construct" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " This example shows how the `target` `data` construct maps variables to a device data environment. The `target` `data` construct creates a new device data environment and maps the variables _v1_ , _v2_ , and _p_ to the new device data environment. The `target` construct enclosed in the `target` `data` region creates a new device data environment, which inherits the variables _v1_ , _v2_ , and _p_ from the enclosing device data environment. The variable _N_ is mapped into the new device data environment from the encountering task's data environment." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target_data.1.c" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The Fortran code passes a reference and specifies the extent of the arrays in the declaration. No length information is necessary in the map clause, as is required with C/C++ pointers." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target_data.1.f90" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### `target` `data` Region Enclosing Multiple `target` Regions" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following examples show how the `target` `data` construct maps variables to a device data environment of a `target` region. The `target` `data` construct creates a device data environment and encloses `target` regions, which have their own device data environments. The device data environment of the `target` `data` region is inherited by the device data environment of an enclosed `target` region. The `target` `data` construct is used to create variables that will persist throughout the `target` `data` region." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the following example the variables _v1_ and _v2_ are mapped at each `target` construct. Instead of mapping the variable _p_ twice, once at each `target` construct, _p_ is mapped once by the `target` `data` construct." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target_data.2.c" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The Fortran code uses reference and specifies the extent of the _p_ , _v1_ and _v2_ arrays. No length information is necessary in the `map` clause, as is required with C/C++ pointers. The arrays _v1_ and _v2_ are mapped at each `target` construct. Instead of mapping the array _p_ twice, once at each target construct, _p_ is mapped once by the `target` `data` construct." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target_data.2.f90" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the following example, the variable tmp defaults to `tofrom` map-type and is mapped at each `target` construct. The array _Q_ is mapped once at the enclosing `target` `data` region instead of at each `target` construct. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target_data.3.c" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the following example the arrays _v1_ and _v2_ are mapped at each `target` construct. Instead of mapping the array _Q_ twice at each `target` construct, _Q_ is mapped once by the `target` `data` construct. Note, the _tmp_ variable is implicitly remapped for each `target` region, mapping the value from the device to the host at the end of the first `target` region, and from the host to the device for the second `target` region." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target_data.3.f90" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### `target` `data` Construct with Orphaned Call" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following two examples show how the `target` `data` construct maps variables to a device data environment. The `target` `data` construct's device data environment encloses the `target` construct's device data environment in the function `vec_mult()` ." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " When the type of the variable appearing in an array section is pointer, the pointer variable and the storage location of the corresponding array section are mapped to the device data environment. The pointer variable is treated as if it had appeared in a `map` clause with a map-type of `alloc` . The array section's storage location is mapped according to the map-type in the `map` clause (the default map-type is `tofrom` )." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `target` construct's device data environment inherits the storage locations of the array sections _v1[0:N]_ , _v2[:n]_ , and _p0[0:N]_ from the enclosing target data construct's device data environment. Neither initialization nor assignment is performed for the array sections in the new device data environment." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The pointer variables _p1_ , _v3_ , and _v4_ are mapped into the target construct's device data environment with an implicit map-type of alloc and they are assigned the address of the storage location associated with their corresponding array sections. Note that the following pairs of array section storage locations are equivalent ( _p0[:N]_ , _p1[:N]_ ), ( _v1[:N]_ , _v3[:N]_ ), and ( _v2[:N]_ , _v4[:N]_ )." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target_data.4.c" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The Fortran code maps the pointers and storage in an identical manner (same extent, but uses indices from 1 to _N_ )." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `target` construct's device data environment inherits the storage locations of the arrays _v1_ , _v2_ and _p0_ from the enclosing `target` `data` constructs's device data environment. However, in Fortran the associated data of the pointer is known, and the shape is not required." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The pointer variables _p1_ , _v3_ , and _v4_ are mapped into the `target` construct's device data environment with an implicit map-type of `alloc` and they are assigned the address of the storage location associated with their corresponding array sections. Note that the following pair of array storage locations are equivalent ( _p0_ , _p1_ ), ( _v1_ , _v3_ ), and ( _v2_ , _v4_ )." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target_data.4.f90" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the following example, the variables _p1_ , _v3_ , and _v4_ are references to the pointer variables _p0_ , _v1_ and _v2_ respectively. The `target` construct's device data environment inherits the pointer variables _p0_ , _v1_ , and _v2_ from the enclosing `target` `data` construct's device data environment. Thus, _p1_ , _v3_ , and _v4_ are already present in the device data environment." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target_data.5.cpp" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the following example, the usual Fortran approach is used for dynamic memory. The _p0_ , _v1_ , and _v2_ arrays are allocated in the main program and passed as references from one routine to another. In `vec_mult` , _p1_ , _v3_ and _v4_ are references to the _p0_ , _v1_ , and _v2_ arrays, respectively. The `target` construct's device data environment inherits the arrays _p0_ , _v1_ , and _v2_ from the enclosing target data construct's device data environment. Thus, _p1_ , _v3_ , and _v4_ are already present in the device data environment." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target_data.5.f90" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### `target` `data` Construct with `if` Clause" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following two examples show how the `target` `data` construct maps variables to a device data environment." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the following example, the if clause on the `target` `data` construct indicates that if the variable _N_ is smaller than a given threshold, then the `target` `data` construct will not create a device data environment." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `target` constructs enclosed in the `target` `data` region must also use an `if` clause on the same condition, otherwise the pointer variable _p_ is implicitly mapped with a map-type of `tofrom` , but the storage location for the array section _p[0:N]_ will not be mapped in the device data environments of the `target` constructs." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target_data.6.c" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `if` clauses work the same way for the following Fortran code. The `target` constructs enclosed in the `target` `data` region should also use an `if` clause with the same condition, so that the `target` `data` region and the `target` region are either both created for the device, or are both ignored." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target_data.6.f90" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the following example, when the `if` clause conditional expression on the `target` construct evaluates to _false_ , the target region will execute on the host device. However, the `target` `data` construct created an enclosing device data environment that mapped _p[0:N]_ to a device data environment on the default device. At the end of the `target` `data` region the array section _p[0:N]_ will be assigned from the device data environment to the corresponding variable in the data environment of the task that encountered the `target` `data` construct, resulting in undefined values in _p[0:N]_ ." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target_data.7.c" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `if` clauses work the same way for the following Fortran code. When the `if` clause conditional expression on the `target` construct evaluates to _false_ , the `target` region will execute on the host device. However, the `target` `data` construct created an enclosing device data environment that mapped the _p_ array (and _v1_ and _v2_ ) to a device data environment on the default target device. At the end of the `target` `data` region the _p_ array will be assigned from the device data environment to the corresponding variable in the data environment of the task that encountered the `target` `data` construct, resulting in undefined values in _p_ ." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target_data.7.f90" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/notebook/Examples_target_unstructured_data.ipynb b/notebook/Examples_target_unstructured_data.ipynb deleted file mode 100644 index 5cbc42a..0000000 --- a/notebook/Examples_target_unstructured_data.ipynb +++ /dev/null @@ -1,118 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"begin " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### `target` `enter` `data` and `target` `exit` `data` Constructs" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -" ### Simple target enter data and target exit data Constructs" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The structured data construct ( `target` ~ `data` ) provides persistent data on a device for subsequent `target` constructs as shown in the `target` ~ `data` examples above. This is accomplished by creating a single `target` ~ `data` region containing `target` constructs." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The unstructured data constructs allow the creation and deletion of data on the device at any appropriate point within the host code, as shown below with the `target` ~ `enter` ~ `data` and `target` ~ `exit` ~ `data` constructs." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following C++ code creates/deletes a vector in a constructor/destructor of a class. The constructor creates a vector with `target` ~ `enter` ~ `data` and uses an `alloc` modifier in the `map` clause to avoid copying values to the device. The destructor deletes the data ( `target` ~ `exit` ~ `data` ) and uses the `delete` modifier in the `map` clause to avoid copying data back to the host. Note, the stand-alone `target` ~ `enter` ~ `data` occurs after the host vector is created, and the `target` ~ `exit` ~ `data` construct occurs before the host data is deleted." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target_unstructured_data.1.cpp" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following C code allocates and frees the data member of a Matrix structure. The `init_matrix` function allocates the memory used in the structure and uses the `target` ~ `enter` ~ `data` directive to map it to the target device. The `free_matrix` function removes the mapped array from the target device and then frees the memory on the host. Note, the stand-alone `target` ~ `enter` ~ `data` occurs after the host memory is allocated, and the `target` ~ `exit` ~ `data` construct occurs before the host data is freed." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target_unstructured_data.1.c" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following Fortran code allocates and deallocates a module array. The `initialize` subroutine allocates the module array and uses the `target` ~ `enter` ~ `data` directive to map it to the target device. The `finalize` subroutine removes the mapped array from the target device and then deallocates the array on the host. Note, the stand-alone `target` ~ `enter` ~ `data` occurs after the host memory is allocated, and the `target` ~ `exit` ~ `data` construct occurs before the host data is deallocated." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target_unstructured_data.1.f90" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"end" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/notebook/Examples_target_update.ipynb b/notebook/Examples_target_update.ipynb deleted file mode 100644 index 88d14cb..0000000 --- a/notebook/Examples_target_update.ipynb +++ /dev/null @@ -1,152 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### `target` `update` Construct" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### Simple `target` `data` and `target` `update` Constructs" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows how the `target` `update` construct updates variables in a device data environment." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `target` `data` construct maps array sections _v1[:N]_ and _v2[:N]_ (arrays _v1_ and _v2_ in the Fortran code) into a device data environment." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The task executing on the host device encounters the first `target` region and waits for the completion of the region." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " After the execution of the first `target` region, the task executing on the host device then assigns new values to _v1[:N]_ and _v2[:N]_ ( _v1_ and _v2_ arrays in Fortran code) in the task's data environment by calling the function `init_again()` ." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `target` `update` construct assigns the new values of _v1_ and _v2_ from the task's data environment to the corresponding mapped array sections in the device data environment of the `target` `data` construct." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The task executing on the host device then encounters the second `target` region and waits for the completion of the region." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The second `target` region uses the updated values of _v1[:N]_ and _v2[:N]_ ." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target_update.1.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target_update.1.f90" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### `target` `update` Construct with `if` Clause" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows how the `target` `update` construct updates variables in a device data environment." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `target` `data` construct maps array sections _v1[:N]_ and _v2[:N]_ (arrays _v1_ and _v2_ in the Fortran code) into a device data environment. In between the two `target` regions, the task executing on the host device conditionally assigns new values to _v1_ and _v2_ in the task's data environment. The function `maybe_init_again()` returns _true_ if new data is written." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " When the conditional expression (the return value of `maybe_init_again()` ) in the `if` clause is _true_ , the `target` `update` construct assigns the new values of _v1_ and _v2_ from the task's data environment to the corresponding mapped array sections in the `target` `data` construct's device data environment." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target_update.2.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_target_update.2.f90" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/notebook/Examples_task_dep.ipynb b/notebook/Examples_task_dep.ipynb deleted file mode 100644 index 6b90c93..0000000 --- a/notebook/Examples_task_dep.ipynb +++ /dev/null @@ -1,220 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Task Dependences" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### Flow Dependence" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In this example we show a simple flow dependence expressed using the `depend` clause on the `task` construct." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_task_dep.1.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_task_dep.1.f90" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The program will always print ' x = 2 ' , because the `depend` clauses enforce the ordering of the tasks. If the `depend` clauses had been omitted, then the tasks could execute in any order and the program and the program would have a race condition." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### Anti-dependence" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In this example we show an anti-dependence expressed using the `depend` clause on the `task` construct." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_task_dep.2.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_task_dep.2.f90" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The program will always print ' x = 1 ' , because the `depend` clauses enforce the ordering of the tasks. If the `depend` clauses had been omitted, then the tasks could execute in any order and the program would have a race condition." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### Output Dependence" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In this example we show an output dependence expressed using the `depend` clause on the `task` construct." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_task_dep.3.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_task_dep.3.f90" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The program will always print ' x = 2 ' , because the `depend` clauses enforce the ordering of the tasks. If the `depend` clauses had been omitted, then the tasks could execute in any order and the program would have a race condition." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### Concurrent Execution with Dependences" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In this example we show potentially concurrent execution of tasks using multiple flow dependences expressed using the `depend` clause on the `task` construct." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_task_dep.4.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_task_dep.4.f90" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The last two tasks are dependent on the first task. However there is no dependence between the last two tasks, which may execute in any order (or concurrently if more than one thread is available). Thus, the possible outputs are ' x + 1 = 3. x + 2 = 4. ' and ' x + 2 = 4. x + 1 = 3. ' . If the `depend` clauses had been omitted, then all of the tasks could execute in any order and the program would have a race condition." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### Matrix multiplication" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " This example shows a task-based blocked matrix multiplication. Matrices are of NxN elements, and the multiplication is implemented using blocks of BSxBS elements." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_task_dep.5.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_task_dep.5.f90" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/notebook/Examples_task_priority.ipynb b/notebook/Examples_task_priority.ipynb deleted file mode 100644 index 583b55f..0000000 --- a/notebook/Examples_task_priority.ipynb +++ /dev/null @@ -1,73 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Task Priority" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -" #### Task Priority \n", -"" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In this example we compute arrays in a matrix through a _compute_array_ routine. Each task has a priority value equal to the value of the loop variable _i_ at the moment of its creation. A higher priority on a task means that a task is a candidate to run sooner." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The creation of tasks occurs in ascending order (according to the iteration space of the loop) but a hint, by means of the `priority` clause, is provided to reverse the execution order." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_task_priority.1.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_task_priority.1.f90" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/notebook/Examples_taskgroup.ipynb b/notebook/Examples_taskgroup.ipynb deleted file mode 100644 index 49a993e..0000000 --- a/notebook/Examples_taskgroup.ipynb +++ /dev/null @@ -1,64 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### The `taskgroup` Construct" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In this example, tasks are grouped and synchronized using the `taskgroup` construct." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Initially, one task (the task executing the `start_background_work()` call) is created in the `parallel` region, and later a parallel tree traversal is started (the task executing the root of the recursive `compute_tree()` calls). While synchronizing tasks at the end of each tree traversal, using the `taskgroup` construct ensures that the formerly started background task does not participate in the synchronization, and is left free to execute in parallel. This is opposed to the behaviour of the `taskwait` construct, which would include the background tasks in the synchronization." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_taskgroup.1.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_taskgroup.1.f90" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/notebook/Examples_tasking.ipynb b/notebook/Examples_tasking.ipynb deleted file mode 100644 index 6594e18..0000000 --- a/notebook/Examples_tasking.ipynb +++ /dev/null @@ -1,417 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### The `task` and `taskwait` Constructs" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows how to traverse a tree-like structure using explicit tasks. Note that the `traverse` function should be called from within a parallel region for the different specified tasks to be executed in parallel. Also note that the tasks will be executed in no specified order because there are no synchronization directives. Thus, assuming that the traversal will be done in post order, as in the sequential code, is wrong." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_tasking.1.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_tasking.1.f90" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the next example, we force a postorder traversal of the tree by adding a `taskwait` directive. Now, we can safely assume that the left and right sons have been executed before we process the current node." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_tasking.2.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_tasking.2.f90" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example demonstrates how to use the `task` construct to process elements of a linked list in parallel. The thread executing the `single` region generates all of the explicit tasks, which are then executed by the threads in the current team. The pointer _p_ is `firstprivate` by default on the `task` construct so it is not necessary to specify it in a `firstprivate` clause." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_tasking.3.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_tasking.3.f90" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `fib()` function should be called from within a `parallel` region for the different specified tasks to be executed in parallel. Also, only one thread of the `parallel` region should call `fib()` unless multiple concurrent Fibonacci computations are desired. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_tasking.4.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_tasking.4.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Note: There are more efficient algorithms for computing Fibonacci numbers. This classic recursion algorithm is for illustrative purposes." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example demonstrates a way to generate a large number of tasks with one thread and execute them with the threads in the team. While generating these tasks, the implementation may reach its limit on unassigned tasks. If it does, the implementation is allowed to cause the thread executing the task generating loop to suspend its task at the task scheduling point in the `task` directive, and start executing unassigned tasks. Once the number of unassigned tasks is sufficiently low, the thread may resume execution of the task generating loop." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_tasking.5.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_tasking.5.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example is the same as the previous one, except that the tasks are generated in an untied task. While generating the tasks, the implementation may reach its limit on unassigned tasks. If it does, the implementation is allowed to cause the thread executing the task generating loop to suspend its task at the task scheduling point in the `task` directive, and start executing unassigned tasks. If that thread begins execution of a task that takes a long time to complete, the other threads may complete all the other tasks before it is finished." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In this case, since the loop is in an untied task, any other thread is eligible to resume the task generating loop. In the previous examples, the other threads would be forced to idle until the generating thread finishes its long task, since the task generating loop was in a tied task." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_tasking.6.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_tasking.6.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following two examples demonstrate how the scheduling rules illustrated in Section 2.11.3 of the OpenMP 4.0 specification affect the usage of `threadprivate` variables in tasks. A `threadprivate` variable can be modified by another task that is executed by the same thread. Thus, the value of a `threadprivate` variable cannot be assumed to be unchanged across a task scheduling point. In untied tasks, task scheduling points may be added in any place by the implementation." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " A task switch may occur at a task scheduling point. A single thread may execute both of the task regions that modify `tp` . The parts of these task regions in which `tp` is modified may be executed in any order so the resulting value of `var` can be either 1 or 2." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_tasking.7.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_tasking.7.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In this example, scheduling constraints prohibit a thread in the team from executing a new task that modifies `tp` while another such task region tied to the same thread is suspended. Therefore, the value written will persist across the task scheduling point." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_tasking.8.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_tasking.8.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following two examples demonstrate how the scheduling rules illustrated in Section 2.11.3 of the OpenMP 4.0 specification affect the usage of locks and critical sections in tasks. If a lock is held across a task scheduling point, no attempt should be made to acquire the same lock in any code that may be interleaved. Otherwise, a deadlock is possible." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the example below, suppose the thread executing task 1 defers task 2. When it encounters the task scheduling point at task 3, it could suspend task 1 and begin task 2 which will result in a deadlock when it tries to enter critical region 1." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_tasking.9.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_tasking.9.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the following example, `lock` is held across a task scheduling point. However, according to the scheduling restrictions, the executing thread can't begin executing one of the non-descendant tasks that also acquires `lock` before the task region is complete. Therefore, no deadlock is possible." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_tasking.10.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_tasking.10.f90" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following examples illustrate the use of the `mergeable` clause in the `task` construct. In this first example, the `task` construct has been annotated with the `mergeable` clause. The addition of this clause allows the implementation to reuse the data environment (including the ICVs) of the parent task for the task inside `foo` if the task is included or undeferred. Thus, the result of the execution may differ depending on whether the task is merged or not. Therefore the mergeable clause needs to be used with caution. In this example, the use of the mergeable clause is safe. As `x` is a shared variable the outcome does not depend on whether or not the task is merged (that is, the task will always increment the same variable and will always compute the same value for `x` )." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_tasking.11.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_tasking.11.f90" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " This second example shows an incorrect use of the `mergeable` clause. In this example, the created task will access different instances of the variable `x` if the task is not merged, as `x` is `firstprivate` , but it will access the same variable `x` if the task is merged. As a result, the behavior of the program is unspecified and it can print two different values for `x` depending on the decisions taken by the implementation." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_tasking.12.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_tasking.12.f90" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows the use of the `final` clause and the `omp_in_final` API call in a recursive binary search program. To reduce overhead, once a certain depth of recursion is reached the program uses the `final` clause to create only included tasks, which allow additional optimizations." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The use of the `omp_in_final` API call allows programmers to optimize their code by specifying which parts of the program are not necessary when a task can create only included tasks (that is, the code is inside a `final` task). In this example, the use of a different state variable is not necessary so once the program reaches the part of the computation that is finalized and copying from the parent state to the new state is eliminated. The allocation of `new_state` in the stack could also be avoided but it would make this example less clear. The `final` clause is most effective when used in conjunction with the `mergeable` clause since all tasks created in a `final` task region are included tasks that can be merged if the `mergeable` clause is present." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_tasking.13.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_tasking.13.f90" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example illustrates the difference between the `if` and the `final` clauses. The `if` clause has a local effect. In the first nest of tasks, the one that has the `if` clause will be undeferred but the task nested inside that task will not be affected by the `if` clause and will be created as usual. Alternatively, the `final` clause affects all `task` constructs in the `final` task region but not the `final` task itself. In the second nest of tasks, the nested tasks will be created as included tasks. Note also that the conditions for the `if` and `final` clauses are usually the opposite." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_tasking.14.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_tasking.14.f90" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/notebook/Examples_taskloop.ipynb b/notebook/Examples_taskloop.ipynb deleted file mode 100644 index ea3861c..0000000 --- a/notebook/Examples_taskloop.ipynb +++ /dev/null @@ -1,60 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### The `taskloop` Construct " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example illustrates how to execute a long running task concurrently with tasks created with a `taskloop` directive for a loop having unbalanced amounts of work for its iterations. The `grainsize` clause specifies that each task is to execute at least 500 iterations of the loop. The `nogroup` clause removes the implicit taskgroup of the `taskloop` construct; the explicit `taskgroup` construct in the example ensures that the function is not exited before the long-running task and the loops have finished execution. cexample{taskloop}{1} " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ffreeexample{taskloop}{1} " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/notebook/Examples_taskyield.ipynb b/notebook/Examples_taskyield.ipynb deleted file mode 100644 index 7e2e812..0000000 --- a/notebook/Examples_taskyield.ipynb +++ /dev/null @@ -1,57 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### The `taskyield` Construct" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example illustrates the use of the `taskyield` directive. The tasks in the example compute something useful and then do some computation that must be done in a critical region. By using `taskyield` when a task cannot get access to the `critical` region the implementation can suspend the current task and schedule some other task that can do something useful. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_taskyield.1.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_taskyield.1.f90" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/notebook/Examples_teams.ipynb b/notebook/Examples_teams.ipynb deleted file mode 100644 index 720ef7c..0000000 --- a/notebook/Examples_teams.ipynb +++ /dev/null @@ -1,308 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### `teams` Constructs" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "subsection{ `target` and `teams` Constructs with `omp_get_num_teams` " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " and `omp_get_team_num` Routines}" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows how the `target` and `teams` constructs are used to create a league of thread teams that execute a region. The `teams` construct creates a league of at most two teams where the master thread of each team executes the `teams` region." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `omp_get_num_teams` routine returns the number of teams executing in a `teams` region. The `omp_get_team_num` routine returns the team number, which is an integer between 0 and one less than the value returned by `omp_get_num_teams` . The following example manually distributes a loop across two teams." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_teams.1.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_teams.1.f90" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### `target` , `teams` , and `distribute` Constructs" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows how the `target` , `teams` , and `distribute` constructs are used to execute a loop nest in a `target` region. The `teams` construct creates a league and the master thread of each team executes the `teams` region. The `distribute` construct schedules the subsequent loop iterations across the master threads of each team." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The number of teams in the league is less than or equal to the variable _num_blocks_ . Each team in the league has a number of threads less than or equal to the variable _block_threads_ . The iterations in the outer loop are distributed among the master threads of each team." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " When a team's master thread encounters the parallel loop construct before the inner loop, the other threads in its team are activated. The team executes the `parallel` region and then workshares the execution of the loop." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Each master thread executing the `teams` region has a private copy of the variable _sum_ that is created by the `reduction` clause on the `teams` construct. The master thread and all threads in its team have a private copy of the variable _sum_ that is created by the `reduction` clause on the parallel loop construct. The second private _sum_ is reduced into the master thread's private copy of _sum_ created by the `teams` construct. At the end of the `teams` region, each master thread's private copy of _sum_ is reduced into the final _sum_ that is implicitly mapped into the `target` region." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_teams.2.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_teams.2.f90" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### `target` `teams` , and Distribute Parallel Loop Constructs" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows how the `target` `teams` and distribute parallel loop constructs are used to execute a `target` region. The `target` `teams` construct creates a league of teams where the master thread of each team executes the `teams` region." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The distribute parallel loop construct schedules the loop iterations across the master threads of each team and then across the threads of each team." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_teams.3.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_teams.3.f90" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "subsection{ `target` `teams` and Distribute Parallel Loop " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Constructs with Scheduling Clauses}" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows how the `target` `teams` and distribute parallel loop constructs are used to execute a `target` region. The `teams` construct creates a league of at most eight teams where the master thread of each team executes the `teams` region. The number of threads in each team is less than or equal to 16." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `distribute` parallel loop construct schedules the subsequent loop iterations across the master threads of each team and then across the threads of each team." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `dist_schedule` clause on the distribute parallel loop construct indicates that loop iterations are distributed to the master thread of each team in chunks of 1024 iterations." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `schedule` clause indicates that the 1024 iterations distributed to a master thread are then assigned to the threads in its associated team in chunks of 64 iterations." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_teams.4.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_teams.4.f90" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### `target` `teams` and `distribute` `simd` Constructs" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows how the `target` `teams` and `distribute` `simd` constructs are used to execute a loop in a `target` region. The `target` `teams` construct creates a league of teams where the master thread of each team executes the `teams` region." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The `distribute` `simd` construct schedules the loop iterations across the master thread of each team and then uses SIMD parallelism to execute the iterations." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_teams.5.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_teams.5.f90" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " #### `target` `teams` and Distribute Parallel Loop SIMD Constructs" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows how the `target` `teams` and the distribute parallel loop SIMD constructs are used to execute a loop in a `target` `teams` region. The `target` `teams` construct creates a league of teams where the master thread of each team executes the `teams` region." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The distribute parallel loop SIMD construct schedules the loop iterations across the master thread of each team and then across the threads of each team where each thread uses SIMD parallelism." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_teams.6.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_teams.6.f90" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/notebook/Examples_threadprivate.ipynb b/notebook/Examples_threadprivate.ipynb deleted file mode 100644 index a1b53df..0000000 --- a/notebook/Examples_threadprivate.ipynb +++ /dev/null @@ -1,284 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### The `threadprivate` Directive" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following examples demonstrate how to use the `threadprivate` directive to give each thread a separate counter." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_threadprivate.1.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_threadprivate.1.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ccppspecificstart The following example uses `threadprivate` on a static variable:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_threadprivate.2.c" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example demonstrates unspecified behavior for the initialization of a `threadprivate` variable. A `threadprivate` variable is initialized once at an unspecified point before its first reference. Because `a` is constructed using the value of `x` (which is modified by the statement `x++` ), the value of `a.val` at the start of the `parallel` region could be either 1 or 2. This problem is avoided for `b` , which uses an auxiliary `const` variable and a copy-constructor." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_cppnexamplethreadprivate3" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ccppspecificend" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following examples show non-conforming uses and correct uses of the `threadprivate` directive. " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " fortranspecificstart The following example is non-conforming because the common block is not declared local to the subroutine that refers to it:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_threadprivate.2.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example is also non-conforming because the common block is not declared local to the subroutine that refers to it:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_threadprivate.3.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example is a correct rewrite of the previous example:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_threadprivate.4.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following is an example of the use of `threadprivate` for local variables: \n", -" blue line floater at top of this page for 'Fortran, cont.' [t!] linewitharrows{-1}{dashed}{Fortran (cont.)}{8em} " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_threadprivate.5.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The above program, if executed by two threads, will print one of the following two sets of output: " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " `a = 11 12 13` `ptr = 4` `i = 15` " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " `A is not allocated` `ptr = 4` `i = 5` " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " or" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " `A is not allocated` `ptr = 4` `i = 15` " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " `a = 1 2 3` `ptr = 4` `i = 5` " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following is an example of the use of `threadprivate` for module variables: \n", -" blue line floater at top of this page for 'Fortran, cont.' [t!] linewitharrows{-1}{dashed}{Fortran (cont.)}{8em} " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_threadprivate.6.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " fortranspecificend" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_cppspecificstart" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example illustrates initialization of `threadprivate` variables for class-type `T` . `t1` is default constructed, `t2` is constructed taking a constructor accepting one argument of integer type, `t3` is copy constructed with argument `f()` :" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_cppnexamplethreadprivate4" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example illustrates the use of `threadprivate` for static class members. The `threadprivate` directive for a static class member must be placed inside the class definition." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_cppnexamplethreadprivate5" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_cppspecificend" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/notebook/Examples_workshare.ipynb b/notebook/Examples_workshare.ipynb deleted file mode 100644 index 8ec09e6..0000000 --- a/notebook/Examples_workshare.ipynb +++ /dev/null @@ -1,195 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### The `workshare` Construct" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " fortranspecificstart" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following are examples of the `workshare` construct. " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the following example, `workshare` spreads work across the threads executing the `parallel` region, and there is a barrier after the last statement. Implementations must enforce Fortran execution rules inside of the `workshare` block." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_workshare.1.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the following example, the barrier at the end of the first `workshare` region is eliminated with a `nowait` clause. Threads doing `CC = DD` immediately begin work on `EE = FF` when they are done with `CC = DD` ." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_workshare.2.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -" blue line floater at top of this page for 'Fortran, cont.' [t!] linewitharrows{-1}{dashed}{Fortran (cont.)}{8em} " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example shows the use of an `atomic` directive inside a `workshare` construct. The computation of `SUM(AA)` is workshared, but the update to `R` is atomic." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_workshare.3.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Fortran `WHERE` and `FORALL` statements are emph{compound statements}, made up of a emph{control} part and a emph{statement} part. When `workshare` is applied to one of these compound statements, both the control and the statement parts are workshared. The following example shows the use of a `WHERE` statement in a `workshare` construct." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Each task gets worked on in order by the threads:" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " `AA = BB` then `CC = DD` then `EE .ne. 0` then `FF = 1 / EE` then `GG = HH` " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_workshare.4.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -" blue line floater at top of this page for 'Fortran, cont.' [t!] linewitharrows{-1}{dashed}{Fortran (cont.)}{8em} " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " In the following example, an assignment to a shared scalar variable is performed by one thread in a `workshare` while all other threads in the team wait." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_workshare.5.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example contains an assignment to a private scalar variable, which is performed by one thread in a `workshare` while all other threads wait. It is non-conforming because the private scalar variable is undefined after the assignment statement. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_workshare.6.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Fortran execution rules must be enforced inside a `workshare` construct. In the following example, the same result is produced in the following program fragment regardless of whether the code is executed sequentially or inside an OpenMP program with multiple threads:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_workshare.7.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " fortranspecificend" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/notebook/Examples_worksharing_critical.ipynb b/notebook/Examples_worksharing_critical.ipynb deleted file mode 100644 index 31dcf90..0000000 --- a/notebook/Examples_worksharing_critical.ipynb +++ /dev/null @@ -1,57 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Worksharing Constructs Inside a `critical` Construct" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The following example demonstrates using a worksharing construct inside a `critical` construct. This example is conforming because the worksharing `single` region is not closely nested inside the `critical` region. A single thread executes the one and only section in the `sections` region, and executes the `critical` region. The same thread encounters the nested `parallel` region, creates a new team of threads, and becomes the master of the new team. One of the threads in the new team enters the `single` region and increments `i` by `1` . At the end of this example `i` is equal to `2` ." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_worksharing_critical.1.c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "%load ../sources/Example_worksharing_critical.1.f" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/notebook/History.ipynb b/notebook/History.ipynb deleted file mode 100644 index 89b881a..0000000 --- a/notebook/History.ipynb +++ /dev/null @@ -1,128 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ## Document Revision History" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Changes from 4.0.2 to 4.5.0" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* Reorganized into chapters of major topics \n", -"* Included file extensions in example labels to indicate source type \n", -"* Applied the explicit `map(tofrom)` for scalar variables in a number of examples to comply with the change of the default behavior for scalar variables from `map(tofrom)` to `firstprivate` in the 4.5 specification \n", -"* Added the following new examples: \n", -"* `linear` clause in loop constructs () \n", -"* task priority () \n", -"* `taskloop` construct () \n", -"* _directive-name_ modifier in multiple `if` clauses on a combined construct () \n", -"* unstructured data mapping () \n", -"* `link` clause for `declare` ~ `target` directive () \n", -"* asynchronous target execution with `nowait` clause () \n", -"* device memory routines and device pointers () \n", -"* doacross loop nest () \n", -"* locks with hints () \n", -"* C/C++ array reduction () \n", -"* C++ reference types in data sharing clauses () " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Changes from 4.0.1 to 4.0.2" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"* Names of examples were changed from numbers to mnemonics \n", -"* Added SIMD examples () \n", -"* Applied miscellaneous fixes in several source codes \n", -"* Added the revision history " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Changes from 4.0 to 4.0.1" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Added the following new examples: \n", -"* the `proc_bind` clause () \n", -"* the `taskgroup` construct () " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " ### Changes from 3.1 to 4.0" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Beginning with OpenMP 4.0, examples were placed in a separate document from the specification document." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Version 4.0 added the following new examples: \n", -"* task dependences () \n", -"* `target` construct () \n", -"* `target` `data` construct () \n", -"* `target` `update` construct () \n", -"* `declare` `target` construct () \n", -"* `teams` constructs () \n", -"* asynchronous execution of a `target` region using tasks () \n", -"* array sections in device constructs () \n", -"* device runtime routines () \n", -"* Fortran ASSOCIATE construct () \n", -"* cancellation constructs () " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/notebook/Introduction_Chapt.ipynb b/notebook/Introduction_Chapt.ipynb deleted file mode 100644 index 6e48124..0000000 --- a/notebook/Introduction_Chapt.ipynb +++ /dev/null @@ -1,139 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -" This is the introduction for the OpenMP Examples document. \n", -" This is an included file. See the master file (openmp-examples.tex) for more information. \n", -" \n", -" When editing this file: \n", -" \n", -" 1. To change formatting, appearance, or style, please edit openmp.sty. \n", -" \n", -" 2. Custom commands and macros are defined in openmp.sty. \n", -" \n", -" 3. Be kind to other editors -- keep a consistent style by copying-and-pasting to \n", -" create new content. \n", -" \n", -" 4. We use semantic markup, e.g. (see openmp.sty for a full list): \n", -" `` \n", -" for bold monospace keywords, code, operators, etc. \n", -" __ \n", -" for italic placeholder names, grammar, etc. \n", -" \n", -" 5. Other recommendations: \n", -" Use the convenience macros defined in openmp.sty for the minor headers \n", -" such as Comments, Syntax, etc. \n", -" \n", -" To keep items together on the same page, prefer the use of \n", -" .... Avoid parbox for text blocks as it interrupts line numbering. \n", -" When possible, avoid filbreak, , newpage, clearpage unless that's \n", -" what you mean. Use needspace{} cautiously for troublesome paragraphs. \n", -" \n", -" Avoid absolute lengths and measures in this file; use relative units when possible. \n", -" Vertical space can be relative to baselineskip or ex units. Horizontal space \n", -" can be relative to linewidth or em units. \n", -" \n", -" Prefer emph{} to italicize terminology, e.g.: \n", -" This is a emph{definition}, not a placeholder. \n", -" This is a _var-name_ . \n", -"" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "chapter*{Introduction}" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " addcontentsline{toc}{chapter}{protectnumberline{}Introduction} This collection of programming examples supplements the OpenMP API for Shared Memory Parallelization specifications, and is not part of the formal specifications. It assumes familiarity with the OpenMP specifications, and shares the typographical conventions used in that document." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " notestart noteheader – This first release of the OpenMP Examples reflects the OpenMP Version 4.5 specifications. Additional examples are being developed and will be published in future releases of this document. noteend" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The OpenMP API specification provides a model for parallel programming that is portable across shared memory architectures from different vendors. Compilers from numerous vendors support the OpenMP API." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The directives, library routines, and environment variables demonstrated in this document allow users to create and manage parallel programs while permitting portability. The directives extend the C, C++ and Fortran base languages with single program multiple data (SPMD) constructs, tasking constructs, device constructs, worksharing constructs, and synchronization constructs, and they provide support for sharing and privatizing data. The functionality to control the runtime environment is provided by library routines and environment variables. Compilers that support the OpenMP API often include a command line option to the compiler that activates and allows interpretation of all OpenMP directives." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " The latest source codes for OpenMP Examples can be downloaded from the `sources` directory at https://github.com/OpenMP/Examples The codes for this OpenMP VER{} Examples document have the tag _vVER_ ." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -" https://github.com/OpenMP/Examples/tree/master/sources " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Complete information about the OpenMP API and a list of the compilers that support the OpenMP API can be found at the OpenMP.org web site" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " `http://www.openmp.org` " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -" This is the end of introduction.tex of the OpenMP Examples document." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/notebook/Title_Page.ipynb b/notebook/Title_Page.ipynb deleted file mode 100644 index 7e48142..0000000 --- a/notebook/Title_Page.ipynb +++ /dev/null @@ -1,217 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -"\n", -" \n", -" Title page" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " hspace{-6em} includegraphics[width=0.4textwidth]{openmp-logo.png} " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " {-0.75in}{0in} Huge textsf{OpenMPApplication ProgrammingInterface}" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -" An optional subtitle can go here: vspace{0.5in}textsf{Examples}vspace{-0.7in} normalsize" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " vspace{1.0in}" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " textbf{Version VER{} -- VERDATE} " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " vspace{2.3in} \n", -"was 3.0" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Source codes for OpenMP VER{} Examples can be downloaded from https://github.com/OpenMP/Examples/tree/vVER {github}." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " {0pt}{1em}setlength{parskip}{0.25baselineskip}\n", -" Copyright © 1997-2016 OpenMP Architecture Review Board. Permission to copy without fee all or part of this material is granted, provided the OpenMP Architecture Review Board copyright notice and the title of this document appear. Notice is given that copying is by permission of OpenMP Architecture Review Board." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -" Blank page" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " clearpage thispagestyle{empty} phantom{a} emph{This page intentionally left blank}" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -"This working version enacted the following tickets: 180, 295, 299, 342, 381, \n", -"and a few other editorial changes. vfill" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/notebook/openmp-examples.ipynb b/notebook/openmp-examples.ipynb deleted file mode 100644 index 6af345e..0000000 --- a/notebook/openmp-examples.ipynb +++ /dev/null @@ -1,255 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -" Welcome to openmp-examples.tex. \n", -" This is the master LaTex file for the OpenMP Examples document. \n", -" \n", -" The files in this set include: \n", -" \n", -" openmp-examples.tex - this file, the master file \n", -" Makefile - makes the document \n", -" openmp.sty - the main style file \n", -" Title_Page.tex - the title page \n", -" openmplogo.png - the logo \n", -" Introduction_Chapt.tex - unnumbered introductory chapter \n", -" Examples_Chapt.tex - unnumbered chapter \n", -" Examples_Sects.tex - examples \n", -" sources/*.c, *.f - C/C++/Fortran example source files \n", -" \n", -" When editing this file: \n", -" \n", -" 1. To change formatting, appearance, or style, please edit openmp.sty. \n", -" \n", -" 2. Custom commands and macros are defined in openmp.sty. \n", -" \n", -" 3. Be kind to other editors -- keep a consistent style by copying-and-pasting to \n", -" create new content. \n", -" \n", -" 4. We use semantic markup, e.g. (see openmp.sty for a full list): \n", -" `` \n", -" for bold monospace keywords, code, operators, etc. \n", -" __ \n", -" for italic placeholder names, grammar, etc. \n", -" \n", -" 5. Other recommendations: \n", -" Use the convenience macros defined in openmp.sty for the minor headers \n", -" such as Comments, Syntax, etc. \n", -" \n", -" To keep items together on the same page, prefer the use of \n", -" .... Avoid parbox for text blocks as it interrupts line numbering. \n", -" When possible, avoid filbreak, , newpage, clearpage unless that's \n", -" what you mean. Use needspace{} cautiously for troublesome paragraphs. \n", -" \n", -" Avoid absolute lengths and measures in this file; use relative units when possible. \n", -" Vertical space can be relative to baselineskip or ex units. Horizontal space \n", -" can be relative to linewidth or em units. \n", -" \n", -" Prefer emph{} to italicize terminology, e.g.: \n", -" This is a emph{definition}, not a placeholder. \n", -" This is a _var-name_ . \n", -"" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -" The following says letter size, but the style sheet may change the size documentclass[10pt,letterpaper,twoside,makeidx,hidelinks]{scrreprt}" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -" Text to appear in the footer on even-numbered pages: newcommand{VER}{4.5.0} newcommand{VERDATE}{November 2016} newcommand{footerText}{OpenMP Examples Version VER{} - VERDATE}" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -" Unified style sheet for OpenMP documents: input{openmp.sty}" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " pagenumbering{roman} input{Title_Page}" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " setcounter{page}{0} setcounter{tocdepth}{2}" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " {1.3} tableofcontents " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", -" Uncomment the next line to enable line numbering on the main body text: linenumberspagewiselinenumbers" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " newpagepagenumbering{arabic}" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " input{Introduction_Chapt} input{Examples_Chapt}" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " setcounter{chapter}{0} \n", -" start chapter numbering here" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " input{Chap_parallel_execution} input{Examples_ploop} input{Examples_parallel} input{Examples_nthrs_nesting} input{Examples_nthrs_dynamic} input{Examples_fort_do} input{Examples_nowait} input{Examples_collapse} \n", -" linear Clause 475 input{Examples_linear_in_loop} input{Examples_psections} input{Examples_fpriv_sections} input{Examples_single} input{Examples_workshare} input{Examples_master} input{Examples_pra_iterator} input{Examples_set_dynamic_nthrs} input{Examples_get_nthrs}" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " input{Chap_affinity} input{Examples_affinity} input{Examples_affinity_query}" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " input{Chap_tasking} input{Examples_tasking} input{Examples_task_priority} input{Examples_task_dep} input{Examples_taskgroup} input{Examples_taskyield} input{Examples_taskloop}" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " input{Chap_devices} input{Examples_target} input{Examples_target_data} input{Examples_target_unstructured_data} input{Examples_target_update} input{Examples_declare_target} \n", -" Link clause 474 input{Examples_teams} input{Examples_async_target_depend} input{Examples_async_target_with_tasks} \n", -"Title change of 57.1 and 57.2 \n", -"New subsection input{Examples_async_target_nowait} input{Examples_async_target_nowait_depend} input{Examples_array_sections} \n", -" Structure Element in map 487 input{Examples_device} \n", -" MemoryRoutine and Device ptr 473" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " input{Chap_SIMD} input{Examples_SIMD} \n", -" Forward Depend 370 \n", -" simdlen 476 \n", -" simd linear modifier 480" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " input{Chap_synchronization} input{Examples_critical} input{Examples_worksharing_critical} input{Examples_barrier_regions} input{Examples_atomic} input{Examples_atomic_restrict} input{Examples_flush_nolist} input{Examples_ordered} \n", -" Doacross loop 405 input{Examples_doacross} input{Examples_locks} input{Examples_init_lock} input{Examples_init_lock_with_hint} input{Examples_lock_owner} input{Examples_simple_lock} input{Examples_nestable_lock} \n", -" \n", -" LOCK with Hints 478 \n", -" \n", -" Hint Clause xxxxxx (included after init_lock) \n", -" \n", -" Lock routines with hint " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " input{Chap_data_environment} input{Examples_threadprivate} input{Examples_default_none} input{Examples_private} input{Examples_fort_loopvar} input{Examples_fort_sp_common} input{Examples_fort_sa_private} input{Examples_carrays_fpriv} input{Examples_lastprivate} input{Examples_reduction} \n", -" User UDR 287 \n", -" C array reduction 377 input{Examples_copyin} input{Examples_copyprivate} input{Examples_cpp_reference} \n", -" Fortran 2003 features 482 input{Examples_associate} \n", -"section--> subsection" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " input{Chap_memory_model} input{Examples_mem_model} input{Examples_fort_race}" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " input{Chap_program_control} input{Examples_cond_comp} input{Examples_icv} \n", -" If multi-ifs 471 input{Examples_standalone} input{Examples_cancellation} \n", -" New Section Nested Regions input{Examples_nested_loop} input{Examples_nesting_restrict}" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " setcounter{chapter}{0} \n", -" restart chapter numbering with 'letter A' renewcommand{thechapter}{Alph{chapter}}\n", -" appendix input{History}" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "---end---" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file From 609560305b5321237ab244347954cdde83abe209 Mon Sep 17 00:00:00 2001 From: Kewei Yan Date: Tue, 8 Oct 2019 13:59:02 -0400 Subject: [PATCH 13/21] comments added --- notebook/tex2notebook.py | 39 ++++++++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/notebook/tex2notebook.py b/notebook/tex2notebook.py index 57e1135..93a0dc9 100644 --- a/notebook/tex2notebook.py +++ b/notebook/tex2notebook.py @@ -6,15 +6,8 @@ # ipynb sets # previously these settings are from .txt, now they are included in this file -# with open('NBSets/LanguageSet.txt', 'r') as f: -# LanguageSet = f.read() - -# with open('NBSets/markdown.txt', 'r') as f: -# MB = f.read() - -# with open('NBSets/code.txt', 'r') as f: -# CB = f.read() - +# languageSet is the code blocks in the end of the .ipynb file to show the setting of kernels +# in this situaiton, the kernel is called Native, which is a C kernel. LanguageSet = ' ],\n' + \ ' "metadata": {\n' + \ ' "kernelspec": {\n' + \ @@ -31,13 +24,14 @@ ' "nbformat": 4,\n' + \ ' "nbformat_minor": 2\n' + \ '}' - +# Also, markdown and code cells are declarated with certain start mark and end mark +# This is start mark for Markdown cells MB = ' {\n' + \ ' "cell_type": "markdown",\n' + \ ' "metadata": {},\n' + \ ' "source": [\n' + \ ' "' - +# this is start mark for code cells CB = ' {\n' + \ ' "cell_type": "code",\n' + \ ' "execution_count": null,\n' + \ @@ -46,11 +40,14 @@ ' "source": [\n' + \ ' "' +# plus, the end marks may vary, for if it is the last one in the cells block or not +# There is a "," if the cell is not the last one E = '"\n ]\n },\n' -E1 = '\n ]\n },\n' E2 = '"\n ]\n }\n' -# Do some changes +# Do some changes to the .tex files +# mainly changing some .tex symbols to .ipynb symbols, or simple get rid of them + # ilegal symbols def replace_underscore(Str): Str = re.sub('"', '\'', Str) @@ -62,6 +59,7 @@ def replace_underscore(Str): Str = re.sub('\\fortranspecificend', '', Str) return Str +# dash, "\\\\\" def replace_dash(Str): Str = re.sub('\\\\', '', Str) return Str @@ -181,6 +179,10 @@ def replace_href(Str): return Str # examples +# There are 7 different kinds of examples that marked with 7 flags, such as "cexample" +# This part is to get the file name of source code for them +# For instance, the flag in .tex file is {cexample}{xxxx1} +# The source code name should be "Example_xxxx.1.c" def replace_example(Str): Str = re.sub('{', '', Str) Str = re.sub('}', '', Str) @@ -236,6 +238,9 @@ def replace_example(Str): return '%load ../sources/Example_' + Str # get file list +# The file list is a temprary .txt file that records the names of .tex files to be processed +# This list will be read line by line in terms of getting access to the .tex files. +# The .tex files are located in the higher level of folder path = '../' dir = os.listdir(path) @@ -250,13 +255,14 @@ def replace_example(Str): mylist = mylist[: -1] mylists = re.split('\n', mylist) -#print mylists +# print mylists # check grammar LIST = ['\\pa', '\\ch', '\\se', '\\su', '\\la', '\\ce', '\\cn', '\\cp', '\\fe', '\\fn', '\\ff'] CodeList = ['ce', 'cn', 'cp', 'fe', 'fn', 'ff'] +# test files are created, which are intermediate files that awaiting for futher translation for FileName in mylists: print(FileName) FileLen = len(FileName) @@ -281,7 +287,8 @@ def replace_example(Str): f.write(' ') f.write(line) - # read and write +# read and write +# read the test files and write the results with open(testfile, 'r') as f: s = f.read() @@ -326,7 +333,9 @@ def replace_example(Str): f.write(E2) f.write(LanguageSet) +# get rid of the test files os.remove(testfile) +# finally get rid of the file list os.remove('MyList.txt') From 633ef9ce65eff22c8fc4b4b13be9f86ccf6203f6 Mon Sep 17 00:00:00 2001 From: Kewei Yan Date: Sun, 13 Oct 2019 19:06:17 -0400 Subject: [PATCH 14/21] tex2notebook updated3 --- notebook/tex2notebook.py | 49 ++++++++++++++++++++++++++++++++-------- 1 file changed, 40 insertions(+), 9 deletions(-) diff --git a/notebook/tex2notebook.py b/notebook/tex2notebook.py index 93a0dc9..f42cb3a 100644 --- a/notebook/tex2notebook.py +++ b/notebook/tex2notebook.py @@ -50,13 +50,27 @@ # ilegal symbols def replace_underscore(Str): + Str = re.sub('\\\\fortranspecificstart', '', Str) + Str = re.sub('\\\\fortranspecificend', '', Str) + Str = re.sub('\\\\cppspecificstart', '', Str) + Str = re.sub('\\\\cppspecificend', '', Str) + Str = re.sub('\\\\ccppspecificstart', '', Str) + Str = re.sub('\\\\ccppspecificend', '', Str) + Str = re.sub('"', '\'', Str) Str = re.sub('\\\\_', '_', Str) - Str = re.sub('\\ifpdf', '', Str) - Str = re.sub('\\item ', '(item)', Str) - Str = re.sub('\\fi', '', Str) - Str = re.sub('\\fortranspecificstart', '', Str) - Str = re.sub('\\fortranspecificend', '', Str) + Str = re.sub('\\\\ifpdf', '', Str) + Str = re.sub('\\\\item ', '(item)', Str) + Str = re.sub('\\\\fi', '', Str) + + Str = re.sub('\\\\bigskip', '', Str) + Str = re.sub('\\%begin', '', Str) + Str = re.sub('\\%end', '', Str) + Str = re.sub('\\%\\%\\% section', '', Str) + Str = re.sub(r'blue line .*', '', Str) + Str = re.sub(r'\% .*', '', Str) # tex comments + Str = re.sub('\\\\code{LOCATION}} \\\\', '', Str) + return Str # dash, "\\\\\" @@ -69,7 +83,7 @@ def replce_pattern(Str): if '[htbp]' in Str: Str = '' - if ' {figs or' in Str: + if ' {figs' in Str: Str = '' return Str @@ -79,10 +93,11 @@ def replace_page(Str): Str = re.sub(r'\\pagebreak', '', Str) return Str -# \label +# \labels def replace_label(Str): Str = re.sub(r'\\label\{[^\{\}]*\}', '', Str) Str = re.sub(r'\\specref\{[^\{\}]*\}', '', Str) + Str = re.sub(r'\\addcontentsline\{[^\{\}]*\}\{[^\{\}]*\}{[^\{\}]*\{[*]*\}[^\{\}]*\}', '', Str) return Str # \chapter @@ -93,6 +108,7 @@ def rep_chapter(match): return out def replace_chapter(Str): + Str = re.sub('\\\\chapter\*', '\\\\chapter', Str) Str = re.sub(r'\\chapter\{[^\{\}]*\}', rep_chapter, Str) return Str @@ -214,6 +230,12 @@ def replace_example(Str): else: Str = Str[9 : l-2] + '.' + Str[l-2 :] + '.c' + elif 'cppnexample' in Str: + if Str[l-2] not in ['1', '2', '3', '4']: + Str = Str[11 : l-1] + '.' + Str[l-1] + '.cpp' + else: + Str = Str[11 : l-2] + '.' + Str[l-2 :] + '.cpp' + elif 'fnexample' in Str: # Str = Str[9 : ] + '.f' if Str[l-2] not in ['1', '2', '3', '4']: @@ -235,6 +257,12 @@ def replace_example(Str): else: Str = Str[12 : l-2] + '.' + Str[l-2 :] + '.f90' + elif 'ffreenexample' in Str: + if Str[l-2] not in ['1', '2', '3', '4']: + Str = Str[13 : l-1] + '.' + Str[l-1] + '.f90' + else: + Str = Str[13 : l-2] + '.' + Str[l-2 :] + '.f90' + return '%load ../sources/Example_' + Str # get file list @@ -258,7 +286,7 @@ def replace_example(Str): # print mylists # check grammar -LIST = ['\\pa', '\\ch', '\\se', '\\su', '\\la', '\\ce', '\\cn', '\\cp', '\\fe', '\\fn', '\\ff'] +LIST = ['\\pa', '\\ch', '\\se', '\\su', '\\la', '\\ce', '\\cn', '\\cp', '\\fe', '\\fn', '\\ff', '\\fo', '\\cc'] CodeList = ['ce', 'cn', 'cp', 'fe', 'fn', 'ff'] @@ -280,7 +308,8 @@ def replace_example(Str): l = len(line) if line[ : 3] in LIST: f.write(line) - f.write('\n') + if line[l-1] != '\\': + f.write('\n') elif l == 0: f.write('\n') else : @@ -338,4 +367,6 @@ def replace_example(Str): # finally get rid of the file list os.remove('MyList.txt') +os.remove('openmp-examples.ipynb') +os.remove('Title_Page.ipynb') From d60aa81e539ad6f203f0d6c590ac00536f171a48 Mon Sep 17 00:00:00 2001 From: Yonghong Yan Date: Sun, 13 Oct 2019 22:16:10 -0400 Subject: [PATCH 15/21] Setting the kernel to be Python (incorrectly) but so user do not need to manually set each time a notebook is open looking for a C/C++/Fortran kernel --- notebook/tex2notebook.py | 43 ++++++++++++++++------------------------ 1 file changed, 17 insertions(+), 26 deletions(-) diff --git a/notebook/tex2notebook.py b/notebook/tex2notebook.py index f42cb3a..5286908 100644 --- a/notebook/tex2notebook.py +++ b/notebook/tex2notebook.py @@ -4,16 +4,17 @@ import re import os -# ipynb sets -# previously these settings are from .txt, now they are included in this file # languageSet is the code blocks in the end of the .ipynb file to show the setting of kernels -# in this situaiton, the kernel is called Native, which is a C kernel. +# Since all the OpenMP example source files are either C and Fortran. The correct setting should be +# a kernel that can recognize C/C++ and Fortran. As of now, since C/C++ and Fortran are not +# officially supported by Jupyter notebook, we set it as python so it won't need users to set it +# manually when open a notebook. Of course, the C/C++/Fortran code is not compiliable or executable. LanguageSet = ' ],\n' + \ ' "metadata": {\n' + \ ' "kernelspec": {\n' + \ - ' "display_name": "C",\n' + \ - ' "language": "c",\n' + \ - ' "name": "c"\n' + \ + ' "display_name": "Python 3",\n' + \ + ' "language": "python",\n' + \ + ' "name": "python3"\n' + \ ' },\n' + \ ' "language_info": {\n' + \ ' "file_extension": ".c",\n' + \ @@ -24,6 +25,7 @@ ' "nbformat": 4,\n' + \ ' "nbformat_minor": 2\n' + \ '}' + # Also, markdown and code cells are declarated with certain start mark and end mark # This is start mark for Markdown cells MB = ' {\n' + \ @@ -265,34 +267,24 @@ def replace_example(Str): return '%load ../sources/Example_' + Str -# get file list -# The file list is a temprary .txt file that records the names of .tex files to be processed -# This list will be read line by line in terms of getting access to the .tex files. -# The .tex files are located in the higher level of folder +# get a list of .text file that will be processed to generate notebook. +# The .tex files are located in parent folder path = '../' dir = os.listdir(path) -with open('MyList.txt', 'w') as f: - for i in dir: - if os.path.splitext(i)[1] == '.tex': - f.write(i) - f.write('\n') - -with open('MyList.txt', 'r') as f: - mylist = f.read() - -mylist = mylist[: -1] -mylists = re.split('\n', mylist) -# print mylists +mylists = [] +for i in dir: + if os.path.splitext(i)[1] == '.tex': + mylists.append(i) # check grammar LIST = ['\\pa', '\\ch', '\\se', '\\su', '\\la', '\\ce', '\\cn', '\\cp', '\\fe', '\\fn', '\\ff', '\\fo', '\\cc'] CodeList = ['ce', 'cn', 'cp', 'fe', 'fn', 'ff'] -# test files are created, which are intermediate files that awaiting for futher translation +# test files are created, which are intermediate files for futher translation for FileName in mylists: - print(FileName) +# print(FileName) FileLen = len(FileName) input = '../' + FileName output = FileName[:(FileLen - 4)] + '.ipynb' @@ -365,8 +357,7 @@ def replace_example(Str): # get rid of the test files os.remove(testfile) -# finally get rid of the file list -os.remove('MyList.txt') +# Title page and table-of-content *.tex files that are properly translated. os.remove('openmp-examples.ipynb') os.remove('Title_Page.ipynb') From b50cbc22d3a950af0e9df75ecf6964bbffa59483 Mon Sep 17 00:00:00 2001 From: Yonghong Yan Date: Sun, 13 Oct 2019 22:49:58 -0400 Subject: [PATCH 16/21] Update README.md --- notebook/README.md | 36 ++++++++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/notebook/README.md b/notebook/README.md index 2b4e158..28e30ac 100644 --- a/notebook/README.md +++ b/notebook/README.md @@ -1,16 +1,36 @@ -## tex2notebook.py script generates Jupyter Notebooks from the tex file +## tex2notebook.py for OpenMP examples document +The tex2notebook.py script generates Jupyter Notebooks from the tex files of the OpenMP examples document. Each tex file is processed by the script which generates a single Jupyter notebook file. The textual content of the tex file is converted to markdown-formatted content enclosed in a notebook cell. A reference to a program source file (example source code in the example document) that appears in the tex file is converted to a cell that uses Jupyter `%load` magic, e.g. `%load ../sources/Example_parallel.1.c` such that running the cell causes loading the content of the file and then replacing the cell with the content. `%load` recognizes both absolute path and related path. Now the default one is `../sources/Example_*`. -#### run +Since all the OpenMP example source files are either C/C++ and Fortran. The correct setting for the notebook kernel +should be a kernel that can recognize C/C++ and Fortran. As of now, C/C++ and Fortran are not +officially supported by Jupyter notebook. Thus the script sets Python as the notebook kernel (Python3 works as well). +By doing that, users won't need to to set it manually when open a notebook. Of course, the C/C++/Fortran code is not compiliable or executable. User can always select a kernel from notebook interface if she has C/C++/Fortran kernel. -Convert .tex to .ipynb - -read .tex -> change .tex(template) -> write .ipynb +### To convert ``` $ python tex2notebook.py ``` -#### notes -`%load` is supported by python, then kernel of jupuyter should be set to python or python3. +All the notebooks will be generated under current folders. The title page and TOC page are removed since they are not properly processed. + + +### Notebook Copyright +The generated notebooks have the same copyright as the orginal tex file and the official OpenMP document. + +**Copyright © 1997-2016 OpenMP Architecture Review Board. +Permission to copy without fee all or part of this material is granted, +provided the OpenMP Architecture Review Board copyright notice and +the title of this document appear. Notice is given that copying is by +permission of OpenMP Architecture Review Board.** + +### Acknowledgement +[Kewei Yan](https://github.com/ambipomyan) from PASSlab (https://passlab.github.io) of +UNC Charlotte is the main developer of this script. The script is licensed with 3-clause BSD License, +and Copyrighted @ 2019 by PASSlab (https://passlab.github.io) +from University of North Carolina at Charlotte. All rights reserved. +To contact, reach Kewei or Yonghong Yan (yanyh15@github or gmail). -`%load` recognizes both absolute path and related path. Now the default one is `../sources/Example_*`. +Funding for this development has been provided by the National Science Foundation +under award number [CISE CCF 1833332](https://www.nsf.gov/awardsearch/showAward?AWD_ID=1833332). Please also +acknowledge OpenMP cOMPunity, one of the OpenMP ARB members. From 32712142d622e487183ea626add6b99ee0bfa1ee Mon Sep 17 00:00:00 2001 From: Yonghong Yan Date: Sun, 13 Oct 2019 22:50:51 -0400 Subject: [PATCH 17/21] Update README.md --- notebook/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/notebook/README.md b/notebook/README.md index 28e30ac..cbff1b2 100644 --- a/notebook/README.md +++ b/notebook/README.md @@ -9,10 +9,11 @@ By doing that, users won't need to to set it manually when open a notebook. Of c ### To convert ``` +cd notebook $ python tex2notebook.py ``` -All the notebooks will be generated under current folders. The title page and TOC page are removed since they are not properly processed. +All the notebooks will be generated under the current folder. The title page and TOC page are removed since they are not properly processed. ### Notebook Copyright From 542cf555e1146c3aad775911cf8e641795dee127 Mon Sep 17 00:00:00 2001 From: Yonghong Yan Date: Sun, 13 Oct 2019 22:53:17 -0400 Subject: [PATCH 18/21] Update README.md --- notebook/README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/notebook/README.md b/notebook/README.md index cbff1b2..6554e46 100644 --- a/notebook/README.md +++ b/notebook/README.md @@ -8,8 +8,8 @@ By doing that, users won't need to to set it manually when open a notebook. Of c ### To convert +Under the `notebook` folder of the repository ``` -cd notebook $ python tex2notebook.py ``` @@ -27,7 +27,8 @@ permission of OpenMP Architecture Review Board.** ### Acknowledgement [Kewei Yan](https://github.com/ambipomyan) from PASSlab (https://passlab.github.io) of -UNC Charlotte is the main developer of this script. The script is licensed with 3-clause BSD License, +UNC Charlotte is the main developer of this script. When this become a question, +the script is licensed with 3-clause BSD License, and Copyrighted @ 2019 by PASSlab (https://passlab.github.io) from University of North Carolina at Charlotte. All rights reserved. To contact, reach Kewei or Yonghong Yan (yanyh15@github or gmail). From e1d0b974183e86cd7df4eb7f2f076de44507401f Mon Sep 17 00:00:00 2001 From: Yonghong Yan Date: Sun, 13 Oct 2019 22:56:03 -0400 Subject: [PATCH 19/21] Update README.md --- notebook/README.md | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/notebook/README.md b/notebook/README.md index 6554e46..c6159f7 100644 --- a/notebook/README.md +++ b/notebook/README.md @@ -1,10 +1,5 @@ ## tex2notebook.py for OpenMP examples document -The tex2notebook.py script generates Jupyter Notebooks from the tex files of the OpenMP examples document. Each tex file is processed by the script which generates a single Jupyter notebook file. The textual content of the tex file is converted to markdown-formatted content enclosed in a notebook cell. A reference to a program source file (example source code in the example document) that appears in the tex file is converted to a cell that uses Jupyter `%load` magic, e.g. `%load ../sources/Example_parallel.1.c` such that running the cell causes loading the content of the file and then replacing the cell with the content. `%load` recognizes both absolute path and related path. Now the default one is `../sources/Example_*`. - -Since all the OpenMP example source files are either C/C++ and Fortran. The correct setting for the notebook kernel -should be a kernel that can recognize C/C++ and Fortran. As of now, C/C++ and Fortran are not -officially supported by Jupyter notebook. Thus the script sets Python as the notebook kernel (Python3 works as well). -By doing that, users won't need to to set it manually when open a notebook. Of course, the C/C++/Fortran code is not compiliable or executable. User can always select a kernel from notebook interface if she has C/C++/Fortran kernel. +The tex2notebook.py script generates Jupyter Notebooks from the tex files of the OpenMP examples document. ### To convert @@ -15,6 +10,13 @@ $ python tex2notebook.py All the notebooks will be generated under the current folder. The title page and TOC page are removed since they are not properly processed. +### Details and limitation +Each tex file is processed by the script which generates a single Jupyter notebook file. The textual content of the tex file is converted to markdown-formatted content enclosed in a notebook cell. A reference to a program source file (example source code in the example document) that appears in the tex file is converted to a cell that uses Jupyter `%load` magic, e.g. `%load ../sources/Example_parallel.1.c` such that running the cell causes loading the content of the file and then replacing the cell with the content. `%load` recognizes both absolute path and related path. Now the default one is `../sources/Example_*`. + +Since all the OpenMP example source files are either C/C++ and Fortran. The correct setting for the notebook kernel +should be a kernel that can recognize C/C++ and Fortran. As of now, C/C++ and Fortran are not +officially supported by Jupyter notebook. Thus the script sets Python as the notebook kernel (Python3 works as well). +By doing that, users won't need to to set it manually when open a notebook. Of course, the C/C++/Fortran code is not compiliable or executable. User can always select a kernel from notebook interface if she has C/C++/Fortran kernel. ### Notebook Copyright The generated notebooks have the same copyright as the orginal tex file and the official OpenMP document. From 350bc6efaf3d12cfd62c6bddba4ba59e821efc18 Mon Sep 17 00:00:00 2001 From: Yonghong Yan Date: Sun, 13 Oct 2019 23:10:24 -0400 Subject: [PATCH 20/21] Update README.md --- notebook/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/notebook/README.md b/notebook/README.md index c6159f7..4d9801a 100644 --- a/notebook/README.md +++ b/notebook/README.md @@ -29,7 +29,7 @@ permission of OpenMP Architecture Review Board.** ### Acknowledgement [Kewei Yan](https://github.com/ambipomyan) from PASSlab (https://passlab.github.io) of -UNC Charlotte is the main developer of this script. When this become a question, +UNC Charlotte is the main developer of this script. When this becomes a question, the script is licensed with 3-clause BSD License, and Copyrighted @ 2019 by PASSlab (https://passlab.github.io) from University of North Carolina at Charlotte. All rights reserved. From b0ddc068ebe3cdd7c9785fbe112367fc03b9ec02 Mon Sep 17 00:00:00 2001 From: Yonghong Yan Date: Fri, 8 Nov 2019 10:45:48 -0500 Subject: [PATCH 21/21] add a simple Makefile for creating and delete notebook files --- notebook/Makefile | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 notebook/Makefile diff --git a/notebook/Makefile b/notebook/Makefile new file mode 100644 index 0000000..4d63724 --- /dev/null +++ b/notebook/Makefile @@ -0,0 +1,5 @@ +default: + python tex2notebook.py + +clean: + rm -rf *.ipynb