├── Changes.log ├── Chap_SIMD.tex ├── Chap_affinity.tex ├── Chap_data_environment.tex ├── Chap_devices.tex ├── Chap_directives.tex ├── Chap_introduction.tex ├── Chap_loop_transformations.tex ├── Chap_memory_model.tex ├── Chap_ompt_interface.tex ├── Chap_parallel_execution.tex ├── Chap_program_control.tex ├── Chap_synchronization.tex ├── Chap_tasking.tex ├── Contributions.md ├── Deprecated_Features.tex ├── Foreword_Chapt.tex ├── History.tex ├── Makefile ├── README.md ├── SIMD ├── SIMD.tex ├── linear_modifier.tex └── sources │ ├── SIMD.1.c │ ├── SIMD.1.f90 │ ├── SIMD.2.c │ ├── SIMD.2.f90 │ ├── SIMD.3.c │ ├── SIMD.3.f90 │ ├── SIMD.4.c │ ├── SIMD.4.f90 │ ├── SIMD.5.c │ ├── SIMD.5.f90 │ ├── SIMD.6.c │ ├── SIMD.6.f90 │ ├── SIMD.7.c │ ├── SIMD.7.f90 │ ├── SIMD.8.c │ ├── SIMD.8.f90 │ ├── linear_modifier.1.cpp │ ├── linear_modifier.1.f90 │ ├── linear_modifier.2.cpp │ ├── linear_modifier.2.f90 │ ├── linear_modifier.3.c │ └── linear_modifier.3.f90 ├── STYLE_GUIDE.md ├── Title_Page.tex ├── affinity ├── affinity.tex ├── affinity_display.tex ├── affinity_query.tex ├── sources │ ├── affinity.1.c │ ├── affinity.1.f │ ├── affinity.2.c │ ├── affinity.2.f90 │ ├── affinity.3.c │ ├── affinity.3.f │ ├── affinity.4.c │ ├── affinity.4.f90 │ ├── affinity.5.c │ ├── affinity.5.f │ ├── affinity.6.c │ ├── affinity.6.f90 │ ├── affinity_display.1.c │ ├── affinity_display.1.f90 │ ├── affinity_display.2.c │ ├── affinity_display.2.f90 │ ├── affinity_display.3.c │ ├── affinity_display.3.f90 │ ├── affinity_query.1.c │ └── affinity_query.1.f90 └── task_affinity.tex ├── data_environment ├── associate.tex ├── carrays_fpriv.tex ├── copyin.tex ├── copyprivate.tex ├── cpp_reference.tex ├── default_none.tex ├── fort_loopvar.tex ├── fort_sa_private.tex ├── fort_shared_var.tex ├── fort_sp_common.tex ├── induction.tex ├── lastprivate.tex ├── private.tex ├── reduction.tex ├── scan.tex ├── sources │ ├── associate.1.f │ ├── associate.2.f │ ├── associate.3.f90 │ ├── associate.4.f90 │ ├── carrays_fpriv.1.c │ ├── copyin.1.c │ ├── copyin.1.f │ ├── copyprivate.1.c │ ├── copyprivate.1.f │ ├── copyprivate.2.c │ ├── copyprivate.2.f │ ├── copyprivate.3.c │ ├── copyprivate.3.f │ ├── copyprivate.4.f │ ├── cpp_reference.1.cpp │ ├── default_none.1.c │ ├── default_none.1.f │ ├── fort_loopvar.1.f90 │ ├── fort_loopvar.2.f90 │ ├── fort_sa_private.1.f │ ├── fort_sa_private.2.f │ ├── fort_sa_private.3.f │ ├── fort_sa_private.4.f │ ├── fort_sa_private.5.f │ ├── fort_shared_var.1.f90 │ ├── fort_sp_common.1.f │ ├── fort_sp_common.2.f │ ├── fort_sp_common.3.f │ ├── fort_sp_common.4.f │ ├── fort_sp_common.5.f │ ├── induction.1.c │ ├── induction.1.f90 │ ├── induction.2.cpp │ ├── induction.2.f90 │ ├── lastprivate.1.c │ ├── lastprivate.1.f │ ├── lastprivate.2.c │ ├── lastprivate.2.f90 │ ├── priv_reduction.1.c │ ├── priv_reduction.1.f90 │ ├── priv_reduction.2.cpp │ ├── priv_reduction.2.f90 │ ├── priv_reduction.3.c │ ├── priv_reduction.3.f90 │ ├── private.1.c │ ├── private.1.f │ ├── private.2.c │ ├── private.2.f │ ├── private.3.c │ ├── private.3.f │ ├── reduction.1.c │ ├── reduction.1.f90 │ ├── reduction.2.c │ ├── reduction.2.f90 │ ├── reduction.3.f90 │ ├── reduction.4.f90 │ ├── reduction.5.f90 │ ├── reduction.6.c │ ├── reduction.6.f │ ├── reduction.7.c │ ├── reduction.7.f90 │ ├── scan.1.c │ ├── scan.1.f90 │ ├── scan.2.c │ ├── scan.2.f90 │ ├── scan.3.c │ ├── scan.3.f90 │ ├── scope_reduction.1.cpp │ ├── scope_reduction.1.f90 │ ├── target_reduction.1.c │ ├── target_reduction.1.f90 │ ├── target_reduction.2.c │ ├── target_reduction.2.f90 │ ├── target_task_reduction.1.c │ ├── target_task_reduction.1.f90 │ ├── target_task_reduction.2a.c │ ├── target_task_reduction.2a.f90 │ ├── target_task_reduction.2b.c │ ├── target_task_reduction.2b.f90 │ ├── task_reduction.1.c │ ├── task_reduction.1.f90 │ ├── task_reduction.2.c │ ├── task_reduction.2.f90 │ ├── taskloop_reduction.1.c │ ├── taskloop_reduction.1.f90 │ ├── taskloop_reduction.2.c │ ├── taskloop_reduction.2.f90 │ ├── taskloop_simd_reduction.1.c │ ├── taskloop_simd_reduction.1.f90 │ ├── threadprivate.1.c │ ├── threadprivate.1.f │ ├── threadprivate.2.c │ ├── threadprivate.2.f │ ├── threadprivate.3.cpp │ ├── threadprivate.3.f │ ├── threadprivate.4.cpp │ ├── threadprivate.4.f │ ├── threadprivate.5.cpp │ ├── threadprivate.5.f │ ├── threadprivate.6.f │ ├── udr.1.c │ ├── udr.1.f90 │ ├── udr.2.c │ ├── udr.2.f90 │ ├── udr.3.c │ ├── udr.3.f90 │ ├── udr.4.f90 │ ├── udr.5.cpp │ └── udr.6.cpp ├── threadprivate.tex └── udr.tex ├── devices ├── C++_virtual_functions.tex ├── array_sections.tex ├── array_shaping.tex ├── async_target_depend.tex ├── async_target_nowait.tex ├── async_target_nowait_arg.tex ├── async_target_nowait_depend.tex ├── async_target_with_tasks.tex ├── declare_target.tex ├── device.tex ├── device_env_traits.tex ├── lambda_expressions.tex ├── sources │ ├── array_sections.1.c │ ├── array_sections.1.f90 │ ├── array_sections.2.c │ ├── array_sections.2.f90 │ ├── array_sections.3.c │ ├── array_sections.3.f90 │ ├── array_sections.4.c │ ├── array_sections.4.f90 │ ├── array_shaping.1.c │ ├── array_shaping.1.f90 │ ├── async_target.1.c │ ├── async_target.1.f90 │ ├── async_target.2.c │ ├── async_target.2.f90 │ ├── async_target.3.c │ ├── async_target.3.f90 │ ├── async_target.4.c │ ├── async_target.4.f90 │ ├── async_target.5.c │ ├── async_target.5.f90 │ ├── declare_target.1.c │ ├── declare_target.1.f90 │ ├── declare_target.2.f90 │ ├── declare_target.2a.cpp │ ├── declare_target.2b_classes.hpp │ ├── declare_target.2b_functions.cpp │ ├── declare_target.2b_main.cpp │ ├── declare_target.2c.cpp │ ├── declare_target.3.c │ ├── declare_target.3.f90 │ ├── declare_target.4.c │ ├── declare_target.4.f90 │ ├── declare_target.5.c │ ├── declare_target.5.f90 │ ├── declare_target.6.c │ ├── declare_target.6.f90 │ ├── declare_target.7.c │ ├── declare_target.7.f90 │ ├── declare_target_indirect_call.1.c │ ├── declare_target_indirect_call.1.f90 │ ├── device.1.c │ ├── device.1.f90 │ ├── device.2.c │ ├── device.2.f90 │ ├── device.3.c │ ├── device.3.f90 │ ├── device.4.c │ ├── device.4.f90 │ ├── device.5.c │ ├── device.5.f90 │ ├── device.6.c │ ├── device.6.f90 │ ├── lambda_expressions.1.cpp │ ├── target.1.c │ ├── target.1.f90 │ ├── target.2.c │ ├── target.2.f90 │ ├── target.3.c │ ├── target.3.f90 │ ├── target.4.c │ ├── target.4.f90 │ ├── target.4b.f90 │ ├── target.5.c │ ├── target.5.f90 │ ├── target.6.c │ ├── target.6.f90 │ ├── target_associate_ptr.1.c │ ├── target_associate_ptr.1.f90 │ ├── target_data.1.c │ ├── target_data.1.f90 │ ├── target_data.2.c │ ├── target_data.2.f90 │ ├── target_data.3.c │ ├── target_data.3.f90 │ ├── target_data.4.c │ ├── target_data.4.f90 │ ├── target_data.5.cpp │ ├── target_data.5.f90 │ ├── target_data.6.c │ ├── target_data.6.f90 │ ├── target_data.7.c │ ├── target_data.7.f90 │ ├── target_defaultmap.1.c │ ├── target_defaultmap.1.f90 │ ├── target_fort_allocatable_map.1.f90 │ ├── target_fort_allocatable_map.2.f90 │ ├── target_fort_allocatable_map.3.f90 │ ├── target_mapper.1.c │ ├── target_mapper.1.f90 │ ├── target_mapper.2.c │ ├── target_mapper.2.f90 │ ├── target_mapper.3.c │ ├── target_mapper.3.f90 │ ├── target_ptr_map.1.c │ ├── target_ptr_map.2.c │ ├── target_ptr_map.3a.c │ ├── target_ptr_map.3b.c │ ├── target_ptr_map.4.c │ ├── target_ptr_map.5.c │ ├── target_ptr_map.5.f90 │ ├── target_reverse_offload.7.c │ ├── target_reverse_offload.7.f90 │ ├── target_struct_map.1.c │ ├── target_struct_map.2.cpp │ ├── target_struct_map.3.c │ ├── target_struct_map.4.c │ ├── target_unstructured_data.1.c │ ├── target_unstructured_data.1.cpp │ ├── target_unstructured_data.1.f90 │ ├── target_update.1.c │ ├── target_update.1.f90 │ ├── target_update.2.c │ ├── target_update.2.f90 │ ├── target_update.3.c │ ├── target_update.3.f90 │ ├── teams.1.c │ ├── teams.1.f90 │ ├── teams.2.c │ ├── teams.2.f90 │ ├── teams.3.c │ ├── teams.3.f90 │ ├── teams.4.c │ ├── teams.4.f90 │ ├── teams.5.c │ ├── teams.5.f90 │ ├── teams.6.c │ ├── teams.6.f90 │ ├── teams.7.c │ ├── teams.7.f90 │ ├── usm_scalar_ptr_ref_asc.1.cpp │ ├── usm_scalar_ptr_ref_asc.1.f90 │ ├── virtual_functions.1.cpp │ └── virtual_functions.2.cpp ├── target.tex ├── target_associate_ptr.tex ├── target_data.tex ├── target_defaultmap.tex ├── target_fort_allocatable_array_mapping.tex ├── target_mapper.tex ├── target_pointer_mapping.tex ├── target_structure_mapping.tex ├── target_unstructured_data.tex ├── target_update.tex ├── teams.tex └── usm.tex ├── directives ├── attributes.tex ├── fixed_format_comments.tex ├── free_format_comments.tex ├── pragmas.tex └── sources │ ├── directive_syntax_F_block.1.f90 │ ├── directive_syntax_F_block.2.f90 │ ├── directive_syntax_F_fixed_comment.1.f │ ├── directive_syntax_F_free_comment.1.f90 │ ├── directive_syntax_attribute.1.cpp │ ├── directive_syntax_attribute.2.cpp │ └── directive_syntax_pragma.1.c ├── figs ├── proc_bind_fig.pdf ├── proc_bind_fig.png ├── tile-2d_tiling.pdf ├── tile-2d_tiling.tex ├── tile-Example_tile2.pdf └── tile-Example_tile2.tex ├── introduction └── Examples.tex ├── latexdiff.cfg ├── loop_transformations ├── apply.tex ├── partial_tile.tex ├── sources │ ├── apply_nested.1.c │ ├── apply_nested.1.f90 │ ├── apply_nested_equivalent.1.c │ ├── apply_nested_equivalent.1.f90 │ ├── apply_span.1.c │ ├── apply_span.1.f90 │ ├── apply_span_equivalent.1.c │ ├── apply_span_equivalent.1.f90 │ ├── apply_syntax.1.c │ ├── apply_syntax.1.f90 │ ├── apply_syntax.2.c │ ├── apply_syntax.2.f90 │ ├── apply_syntax.3.c │ ├── apply_syntax.3.f90 │ ├── apply_syntax_equivalent.1.c │ ├── apply_syntax_equivalent.1.f90 │ ├── apply_syntax_equivalent.2.c │ ├── apply_syntax_equivalent.2.f90 │ ├── apply_syntax_equivalent.3.c │ ├── apply_syntax_equivalent.3.f90 │ ├── partial_tile.1.c │ ├── partial_tile.1.f90 │ ├── partial_tile.2.c │ ├── partial_tile.2.f90 │ ├── tile.1.c │ ├── tile.1.f90 │ ├── tile.2.c │ ├── tile.2.f90 │ ├── unroll.1.c │ ├── unroll.1.f90 │ ├── unroll.2.c │ ├── unroll.2.f90 │ ├── unroll.3.c │ ├── unroll.3.f90 │ ├── unroll.4.c │ └── unroll.4.f90 ├── tile.tex └── unroll.tex ├── memory_model ├── allocators.tex ├── fort_race.tex ├── mem_model.tex └── sources │ ├── allocators.1.c │ ├── allocators.1.f90 │ ├── allocators.2.f90 │ ├── allocators.3.f90 │ ├── allocators.4.c │ ├── allocators.4.f90 │ ├── allocators.5.c │ ├── allocators.5.f90 │ ├── allocators.6.c │ ├── allocators.6.f90 │ ├── fort_race.1.f90 │ ├── mem_model.1.c │ ├── mem_model.1.f90 │ ├── mem_model.2.c │ ├── mem_model.2.f │ ├── mem_model.3.c │ ├── mem_model.3.f │ ├── mem_model.4a.c │ ├── mem_model.4a.f90 │ ├── mem_model.4b.c │ └── mem_model.4b.f90 ├── omp_copyright.txt ├── ompt_interface ├── ompt_start.tex └── sources │ └── ompt_start.1.c ├── openmp-examples.tex ├── openmp-index.ist ├── openmp-logo.png ├── openmp.sty ├── parallel_execution ├── collapse.tex ├── fort_do.tex ├── fpriv_sections.tex ├── get_nthrs.tex ├── host_teams.tex ├── linear_in_loop.tex ├── loop.tex ├── masked.tex ├── nowait.tex ├── nthrs_dynamic.tex ├── nthrs_nesting.tex ├── parallel.tex ├── ploop.tex ├── pra_iterator.tex ├── psections.tex ├── set_dynamic_nthrs.tex ├── single.tex ├── sources │ ├── collapse.1.c │ ├── collapse.1.f │ ├── collapse.2.c │ ├── collapse.2.f │ ├── collapse.3.c │ ├── collapse.3.f │ ├── collapse.4.c │ ├── collapse.4.f90 │ ├── fort_do.1.f │ ├── fort_do.2.f │ ├── fpriv_sections.1.c │ ├── fpriv_sections.1.f90 │ ├── get_nthrs.1.c │ ├── get_nthrs.1.f │ ├── get_nthrs.2.c │ ├── get_nthrs.2.f │ ├── host_teams.1.c │ ├── host_teams.1.f90 │ ├── linear_in_loop.1.c │ ├── linear_in_loop.1.f90 │ ├── loop.1.c │ ├── loop.1.f90 │ ├── loop.2.c │ ├── loop.2.f90 │ ├── masked.1.c │ ├── masked.1.f │ ├── nowait.1.c │ ├── nowait.1.f │ ├── nowait.2.c │ ├── nowait.2.f90 │ ├── nthrs_dynamic.1.c │ ├── nthrs_dynamic.1.f │ ├── nthrs_dynamic.2.c │ ├── nthrs_dynamic.2.f │ ├── nthrs_nesting.1.c │ ├── nthrs_nesting.1.f │ ├── parallel.1.c │ ├── parallel.1.f │ ├── ploop.1.c │ ├── ploop.1.f │ ├── pra_iterator.1.cpp │ ├── psections.1.c │ ├── psections.1.f │ ├── set_dynamic_nthrs.1.c │ ├── set_dynamic_nthrs.1.f │ ├── single.1.c │ ├── single.1.f │ ├── workshare.1.f │ ├── workshare.2.f │ ├── workshare.3.f │ ├── workshare.4.f │ ├── workshare.5.f │ ├── workshare.6.f │ └── workshare.7.f └── workshare.tex ├── program_control ├── assumption.tex ├── cancellation.tex ├── cond_comp.tex ├── context_based_variants.tex ├── dispatch.tex ├── icv.tex ├── interop.tex ├── nested_loop.tex ├── nesting_restrict.tex ├── pause_resource.tex ├── reproducible.tex ├── requires.tex ├── sources │ ├── assumption.1.c │ ├── assumption.1.f90 │ ├── assumption.2.c │ ├── assumption.2.f90 │ ├── cancellation.1.cpp │ ├── cancellation.1.f90 │ ├── cancellation.2.c │ ├── cancellation.2.f90 │ ├── cond_comp.1.c │ ├── cond_comp.1.f │ ├── declare_variant.1.c │ ├── declare_variant.1.f90 │ ├── declare_variant.2.c │ ├── declare_variant.2.f90 │ ├── declare_variant.3.c │ ├── dispatch.1.c │ ├── dispatch.1.f90 │ ├── display_env.1.c │ ├── display_env.1.f90 │ ├── error.1.c │ ├── error.1.f90 │ ├── get_wtime.1.c │ ├── get_wtime.1.f90 │ ├── icv.1.c │ ├── icv.1.f │ ├── icv.2.c │ ├── icv.2.f90 │ ├── interop.1.c │ ├── metadirective.1.c │ ├── metadirective.1.f90 │ ├── metadirective.2.c │ ├── metadirective.2.f90 │ ├── metadirective.3.c │ ├── metadirective.3.f90 │ ├── metadirective.4.c │ ├── metadirective.4.f90 │ ├── metadirective.5.cpp │ ├── nested_loop.1.c │ ├── nested_loop.1.f │ ├── nested_loop.2.c │ ├── nested_loop.2.f │ ├── nesting_restrict.1.c │ ├── nesting_restrict.1.f │ ├── nesting_restrict.2.c │ ├── nesting_restrict.2.f │ ├── nesting_restrict.3.c │ ├── nesting_restrict.3.f │ ├── nesting_restrict.4.c │ ├── nesting_restrict.4.f │ ├── nesting_restrict.5.c │ ├── nesting_restrict.5.f │ ├── nesting_restrict.6.c │ ├── nesting_restrict.6.f │ ├── pause_resource.1.c │ ├── pause_resource.2a.f90 │ ├── pause_resource.2b.f90 │ ├── reproducible.1.c │ ├── reproducible.1.f90 │ ├── reproducible.2.c │ ├── reproducible.2.f90 │ ├── requires.1.cpp │ ├── requires.1.f90 │ ├── selector_scoring.1.c │ ├── selector_scoring.1.f90 │ ├── selector_scoring.2.c │ ├── selector_scoring.2.f90 │ ├── standalone.1.c │ ├── standalone.1.f90 │ ├── standalone.2.c │ ├── standalone.2.f90 │ ├── target_offload_control.1.c │ └── target_offload_control.1.f90 ├── standalone.tex ├── target_offload.tex └── utilities.tex ├── sources ├── README ├── check_tags ├── eval_codes ├── eval_utils ├── run_code └── sourceme ├── synchronization ├── acquire_release.tex ├── atomic.tex ├── atomic_cas.tex ├── atomic_hint.tex ├── atomic_restrict.tex ├── barrier_regions.tex ├── critical.tex ├── depobj.tex ├── doacross.tex ├── init_lock.tex ├── init_lock_with_hint.tex ├── lock_owner.tex ├── locks.tex ├── nestable_lock.tex ├── ordered.tex ├── simple_lock.tex ├── sources │ ├── acquire_release.1.c │ ├── acquire_release.1.f90 │ ├── acquire_release.2.c │ ├── acquire_release.2.f90 │ ├── acquire_release.3.c │ ├── acquire_release.3.f90 │ ├── acquire_release_broke.4.c │ ├── acquire_release_broke.4.f90 │ ├── atomic.1.c │ ├── atomic.1.f │ ├── atomic.2.c │ ├── atomic.2.f │ ├── atomic.3.c │ ├── atomic.3.f │ ├── atomic.4.c │ ├── atomic.4.f90 │ ├── atomic_restrict.1.c │ ├── atomic_restrict.1.f │ ├── atomic_restrict.2.c │ ├── atomic_restrict.2.f │ ├── atomic_restrict.3.f │ ├── barrier_regions.1.c │ ├── barrier_regions.1.f │ ├── cas.1.c │ ├── cas.2.c │ ├── critical.1.c │ ├── critical.1.f │ ├── critical.2.c │ ├── critical.2.f │ ├── depobj.1.c │ ├── depobj.1.f90 │ ├── doacross.1.c │ ├── doacross.1.f90 │ ├── doacross.2.c │ ├── doacross.2.f90 │ ├── doacross.3.c │ ├── doacross.3.f90 │ ├── doacross.4.c │ ├── doacross.4.f90 │ ├── init_lock.1.cpp │ ├── init_lock.1.f │ ├── init_lock_with_hint.1.cpp │ ├── init_lock_with_hint.1.f │ ├── lock_owner.1.c │ ├── lock_owner.1.f │ ├── nestable_lock.1.c │ ├── nestable_lock.1.f │ ├── ordered.1.c │ ├── ordered.1.f │ ├── ordered.2.c │ ├── ordered.2.f │ ├── ordered.3.c │ ├── ordered.3.f │ ├── simple_lock.1.c │ ├── simple_lock.1.f │ ├── worksharing_critical.1.c │ └── worksharing_critical.1.f └── worksharing_critical.tex ├── tasking ├── parallel_masked_taskloop.tex ├── sources │ ├── parallel_masked_taskloop.1.c │ ├── parallel_masked_taskloop.1.f90 │ ├── task_dep.1.c │ ├── task_dep.1.f90 │ ├── task_dep.10.c │ ├── task_dep.10.f90 │ ├── task_dep.11.c │ ├── task_dep.11.f90 │ ├── task_dep.12.c │ ├── task_dep.12.f90 │ ├── task_dep.13.c │ ├── task_dep.13.f90 │ ├── task_dep.14.c │ ├── task_dep.14.f90 │ ├── task_dep.2.c │ ├── task_dep.2.f90 │ ├── task_dep.3.c │ ├── task_dep.3.f90 │ ├── task_dep.4.c │ ├── task_dep.4.f90 │ ├── task_dep.4b.c │ ├── task_dep.4b.f90 │ ├── task_dep.5.c │ ├── task_dep.5.f90 │ ├── task_dep.6.c │ ├── task_dep.6.f90 │ ├── task_dep.7.c │ ├── task_dep.7.f90 │ ├── task_dep.8.c │ ├── task_dep.8.f90 │ ├── task_dep.9.c │ ├── task_dep.9.f90 │ ├── task_detach.1.c │ ├── task_detach.1.f90 │ ├── task_detach.2.c │ ├── task_priority.1.c │ ├── task_priority.1.f90 │ ├── taskgroup.1.c │ ├── taskgroup.1.f90 │ ├── tasking.1.c │ ├── tasking.1.f90 │ ├── tasking.10.c │ ├── tasking.10.f90 │ ├── tasking.11.c │ ├── tasking.11.f90 │ ├── tasking.12.c │ ├── tasking.12.f90 │ ├── tasking.13.c │ ├── tasking.13.f90 │ ├── tasking.14.c │ ├── tasking.14.f90 │ ├── tasking.2.c │ ├── tasking.2.f90 │ ├── tasking.3.c │ ├── tasking.3.f90 │ ├── tasking.4.c │ ├── tasking.4.f │ ├── tasking.5.c │ ├── tasking.5.f │ ├── tasking.6.c │ ├── tasking.6.f │ ├── tasking.7.c │ ├── tasking.7.f │ ├── tasking.8.c │ ├── tasking.8.f │ ├── tasking.9.c │ ├── tasking.9.f │ ├── taskloop.1.c │ ├── taskloop.1.f90 │ ├── taskloop.2.c │ ├── taskloop.2.f90 │ ├── taskloop_dep.1.c │ ├── taskloop_dep.1.f90 │ ├── taskloop_dep.2.c │ ├── taskloop_dep.2.f90 │ ├── taskyield.1.c │ └── taskyield.1.f90 ├── task_dep.tex ├── task_detach.tex ├── task_priority.tex ├── taskgroup.tex ├── tasking.tex ├── taskloop.tex ├── taskloop_dep.tex └── taskyield.tex ├── util ├── Makefile ├── README ├── chk_tags.c ├── cvt_fixed ├── gen_tags ├── latexdiff │ ├── VERSION │ ├── latexdiff │ ├── latexdiff-fast │ └── latexdiff-vc └── list_tags └── versioninfo /README.md: -------------------------------------------------------------------------------- 1 | # OpenMP Examples Document 2 | 3 | This is the OpenMP Examples document in LaTeX format. 4 | 5 | Please see [Contributions.md](Contributions.md) on how to make contributions to adding new examples. 6 | 7 | For a brief revision history, please see [Changes.log](Changes.log). 8 | 9 | For copyright information, please see [omp_copyright.txt](omp_copyright.txt). 10 | 11 | -------------------------------------------------------------------------------- /SIMD/sources/SIMD.1.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: SIMD.1 3 | * @@type: C 4 | * @@operation: compile 5 | * @@expect: success 6 | * @@version: omp_4.0 7 | */ 8 | void star( double *a, double *b, double *c, int n, int *ioff ) 9 | { 10 | int i; 11 | #pragma omp simd 12 | for ( i = 0; i < n; i++ ) 13 | a[i] *= b[i] * c[i+ *ioff]; 14 | } 15 | -------------------------------------------------------------------------------- /SIMD/sources/SIMD.1.f90: -------------------------------------------------------------------------------- 1 | ! @@name: SIMD.1 2 | ! @@type: F-free 3 | ! @@operation: compile 4 | ! @@expect: success 5 | ! @@version: omp_4.0 6 | subroutine star(a,b,c,n,ioff_ptr) 7 | implicit none 8 | double precision :: a(*),b(*),c(*) 9 | integer :: n, i 10 | integer, pointer :: ioff_ptr 11 | 12 | !$omp simd 13 | do i = 1,n 14 | a(i) = a(i) * b(i) * c(i+ioff_ptr) 15 | end do 16 | 17 | end subroutine 18 | -------------------------------------------------------------------------------- /SIMD/sources/SIMD.3.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: SIMD.3 3 | * @@type: C 4 | * @@operation: compile 5 | * @@expect: success 6 | * @@version: omp_4.0 7 | */ 8 | double work( double *a, double *b, int n ) 9 | { 10 | int i; 11 | double tmp, sum; 12 | sum = 0.0; 13 | #pragma omp simd private(tmp) reduction(+:sum) 14 | for (i = 0; i < n; i++) { 15 | tmp = a[i] + b[i]; 16 | sum += tmp; 17 | } 18 | return sum; 19 | } 20 | -------------------------------------------------------------------------------- /SIMD/sources/SIMD.3.f90: -------------------------------------------------------------------------------- 1 | ! @@name: SIMD.3 2 | ! @@type: F-free 3 | ! @@operation: compile 4 | ! @@expect: success 5 | ! @@version: omp_4.0 6 | subroutine work( a, b, n, sum ) 7 | implicit none 8 | integer :: i, n 9 | double precision :: a(n), b(n), sum, tmp 10 | 11 | sum = 0.0d0 12 | !$omp simd private(tmp) reduction(+:sum) 13 | do i = 1,n 14 | tmp = a(i) + b(i) 15 | sum = sum + tmp 16 | end do 17 | 18 | end subroutine work 19 | -------------------------------------------------------------------------------- /SIMD/sources/SIMD.4.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: SIMD.4 3 | * @@type: C 4 | * @@operation: compile 5 | * @@expect: success 6 | * @@version: omp_4.0 7 | */ 8 | void work( float *b, int n, int m ) 9 | { 10 | int i; 11 | #pragma omp simd safelen(16) 12 | for (i = m; i < n; i++) 13 | b[i] = b[i-m] - 1.0f; 14 | } 15 | -------------------------------------------------------------------------------- /SIMD/sources/SIMD.4.f90: -------------------------------------------------------------------------------- 1 | ! @@name: SIMD.4 2 | ! @@type: F-free 3 | ! @@operation: compile 4 | ! @@expect: success 5 | ! @@version: omp_4.0 6 | subroutine work( b, n, m ) 7 | implicit none 8 | real :: b(n) 9 | integer :: i,n,m 10 | 11 | !$omp simd safelen(16) 12 | do i = m+1, n 13 | b(i) = b(i-m) - 1.0 14 | end do 15 | end subroutine work 16 | -------------------------------------------------------------------------------- /SIMD/sources/SIMD.5.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: SIMD.5 3 | * @@type: C 4 | * @@operation: compile 5 | * @@expect: success 6 | * @@version: omp_4.0 7 | */ 8 | void work( double **a, double **b, double **c, int n ) 9 | { 10 | int i, j; 11 | double tmp; 12 | #pragma omp for simd collapse(2) private(tmp) 13 | for (i = 0; i < n; i++) { 14 | for (j = 0; j < n; j++) { 15 | tmp = a[i][j] + b[i][j]; 16 | c[i][j] = tmp; 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /SIMD/sources/SIMD.5.f90: -------------------------------------------------------------------------------- 1 | ! @@name: SIMD.5 2 | ! @@type: F-free 3 | ! @@operation: compile 4 | ! @@expect: success 5 | ! @@version: omp_4.0 6 | subroutine work( a, b, c, n ) 7 | implicit none 8 | integer :: i,j,n 9 | double precision :: a(n,n), b(n,n), c(n,n), tmp 10 | 11 | !$omp do simd collapse(2) private(tmp) 12 | do j = 1,n 13 | do i = 1,n 14 | tmp = a(i,j) + b(i,j) 15 | c(i,j) = tmp 16 | end do 17 | end do 18 | 19 | end subroutine work 20 | -------------------------------------------------------------------------------- /SIMD/sources/SIMD.7.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: SIMD.7 3 | * @@type: C 4 | * @@operation: run 5 | * @@expect: success 6 | * @@version: omp_4.0 7 | */ 8 | #include 9 | #include 10 | 11 | #define N 45 12 | int a[N], b[N], c[N]; 13 | 14 | #pragma omp declare simd inbranch 15 | int fib( int n ) 16 | { 17 | if (n <= 1) 18 | return n; 19 | else { 20 | return fib(n-1) + fib(n-2); 21 | } 22 | } 23 | 24 | int main(void) 25 | { 26 | int i; 27 | 28 | #pragma omp simd 29 | for (i=0; i < N; i++) b[i] = i; 30 | 31 | #pragma omp simd 32 | for (i=0; i < N; i++) { 33 | a[i] = fib(b[i]); 34 | } 35 | printf("Done a[%d] = %d\n", N-1, a[N-1]); //Done a[44] = 701408733 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /affinity/sources/affinity.1.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: affinity.1 3 | * @@type: C 4 | * @@operation: compile 5 | * @@expect: success 6 | * @@version: omp_4.0 7 | */ 8 | void work(); 9 | 10 | int main() 11 | { 12 | 13 | #pragma omp parallel proc_bind(spread) num_threads(4) 14 | { 15 | work(); 16 | } 17 | 18 | return 0; 19 | 20 | } 21 | -------------------------------------------------------------------------------- /affinity/sources/affinity.1.f: -------------------------------------------------------------------------------- 1 | ! @@name: affinity.1 2 | ! @@type: F-fixed 3 | ! @@operation: compile 4 | ! @@expect: success 5 | ! @@version: omp_4.0 6 | PROGRAM EXAMPLE 7 | !$OMP PARALLEL PROC_BIND(SPREAD) NUM_THREADS(4) 8 | CALL WORK() 9 | !$OMP END PARALLEL 10 | END PROGRAM EXAMPLE 11 | -------------------------------------------------------------------------------- /affinity/sources/affinity.2.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: affinity.2 3 | * @@type: C 4 | * @@operation: compile 5 | * @@expect: success 6 | * @@version: omp_4.0 7 | */ 8 | void work(); 9 | void foo() 10 | { 11 | #pragma omp parallel num_threads(16) proc_bind(spread) 12 | { 13 | work(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /affinity/sources/affinity.2.f90: -------------------------------------------------------------------------------- 1 | ! @@name: affinity.2 2 | ! @@type: F-free 3 | ! @@operation: compile 4 | ! @@expect: success 5 | ! @@version: omp_4.0 6 | subroutine foo 7 | !$omp parallel num_threads(16) proc_bind(spread) 8 | call work() 9 | !$omp end parallel 10 | end subroutine 11 | -------------------------------------------------------------------------------- /affinity/sources/affinity.3.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: affinity.3 3 | * @@type: C 4 | * @@operation: compile 5 | * @@expect: success 6 | * @@version: omp_4.0 7 | */ 8 | void work(); 9 | int main() 10 | { 11 | #pragma omp parallel proc_bind(close) num_threads(4) 12 | { 13 | work(); 14 | } 15 | return 0; 16 | } 17 | -------------------------------------------------------------------------------- /affinity/sources/affinity.3.f: -------------------------------------------------------------------------------- 1 | ! @@name: affinity.3 2 | ! @@type: F-fixed 3 | ! @@operation: compile 4 | ! @@expect: success 5 | ! @@version: omp_4.0 6 | PROGRAM EXAMPLE 7 | !$OMP PARALLEL PROC_BIND(CLOSE) NUM_THREADS(4) 8 | CALL WORK() 9 | !$OMP END PARALLEL 10 | END PROGRAM EXAMPLE 11 | -------------------------------------------------------------------------------- /affinity/sources/affinity.4.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: affinity.4 3 | * @@type: C 4 | * @@operation: compile 5 | * @@expect: success 6 | * @@version: omp_4.0 7 | */ 8 | void work(); 9 | void foo() 10 | { 11 | #pragma omp parallel num_threads(16) proc_bind(close) 12 | { 13 | work(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /affinity/sources/affinity.4.f90: -------------------------------------------------------------------------------- 1 | ! @@name: affinity.4 2 | ! @@type: F-free 3 | ! @@operation: compile 4 | ! @@expect: success 5 | ! @@version: omp_4.0 6 | subroutine foo 7 | !$omp parallel num_threads(16) proc_bind(close) 8 | call work() 9 | !$omp end parallel 10 | end subroutine 11 | -------------------------------------------------------------------------------- /affinity/sources/affinity.5.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: affinity.5 3 | * @@type: C 4 | * @@operation: compile 5 | * @@expect: success 6 | * @@version: omp_5.1 7 | */ 8 | void work(); 9 | int main() 10 | { 11 | #pragma omp parallel proc_bind(primary) num_threads(4) 12 | { 13 | work(); 14 | } 15 | return 0; 16 | } 17 | -------------------------------------------------------------------------------- /affinity/sources/affinity.5.f: -------------------------------------------------------------------------------- 1 | ! @@name: affinity.5 2 | ! @@type: F-fixed 3 | ! @@operation: compile 4 | ! @@expect: success 5 | ! @@version: omp_5.1 6 | PROGRAM EXAMPLE 7 | !$OMP PARALLEL PROC_BIND(primary) NUM_THREADS(4) 8 | CALL WORK() 9 | !$OMP END PARALLEL 10 | END PROGRAM EXAMPLE 11 | -------------------------------------------------------------------------------- /affinity/sources/affinity.6.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: affinity.6 3 | * @@type: C 4 | * @@operation: compile 5 | * @@expect: success 6 | * @@version: omp_5.0 7 | */ 8 | double * alloc_init_B(double *A, int N); 9 | void compute_on_B(double *B, int N); 10 | 11 | void task_affinity(double *A, int N) 12 | { 13 | double * B; 14 | #pragma omp task depend(out:B) shared(B) affinity(A[0:N]) 15 | { 16 | B = alloc_init_B(A,N); 17 | } 18 | 19 | #pragma omp task depend( in:B) shared(B) affinity(A[0:N]) 20 | { 21 | compute_on_B(B,N); 22 | } 23 | 24 | #pragma omp taskwait 25 | } 26 | -------------------------------------------------------------------------------- /affinity/sources/affinity.6.f90: -------------------------------------------------------------------------------- 1 | ! @@name: affinity.6 2 | ! @@type: F-free 3 | ! @@operation: compile 4 | ! @@expect: success 5 | ! @@version: omp_5.0 6 | subroutine task_affinity(A, N) 7 | 8 | external alloc_init_B 9 | external compute_on_B 10 | double precision, allocatable :: B(:) 11 | 12 | !$omp task depend(out:B) shared(B) affinity(A) 13 | call alloc_init_B(B,A) 14 | !$omp end task 15 | 16 | !$omp task depend(in:B) shared(B) affinity(A) 17 | call compute_on_B(B) 18 | !$omp end task 19 | 20 | !$omp taskwait 21 | 22 | end subroutine 23 | -------------------------------------------------------------------------------- /data_environment/copyin.tex: -------------------------------------------------------------------------------- 1 | %\pagebreak 2 | \section{\kcode{copyin} Clause} 3 | \label{sec:copyin} 4 | \index{clauses!copyin@\kcode{copyin}} 5 | \index{copyin clause@\kcode{copyin} clause} 6 | \index{directives!threadprivate@\kcode{threadprivate}} 7 | \index{threadprivate directive@\kcode{threadprivate} directive} 8 | 9 | The \kcode{copyin} clause is used to initialize threadprivate data upon entry 10 | to a \kcode{parallel} region. The value of the threadprivate variable in the primary 11 | thread is copied to the threadprivate variable of each other team member. 12 | 13 | \cexample{copyin}{1} 14 | 15 | \fexample{copyin}{1} 16 | 17 | 18 | -------------------------------------------------------------------------------- /data_environment/fort_sa_private.tex: -------------------------------------------------------------------------------- 1 | %\pagebreak 2 | \begin{fortranspecific}[4ex] 3 | \section{Fortran Restrictions on Storage Association with the \kcode{private} Clause} 4 | \label{sec:fort_sa_private} 5 | \index{clauses!private@\kcode{private}} 6 | \index{private clause@\kcode{private} clause!storage association, Fortran} 7 | 8 | The following non-conforming examples illustrate the implications of the \kcode{private} 9 | clause rules with regard to storage association. 10 | 11 | \pagebreak 12 | \fnexample{fort_sa_private}{1} 13 | 14 | \topmarker{Fortran} 15 | \fnexample{fort_sa_private}{2} 16 | 17 | \fnexample{fort_sa_private}{3} 18 | 19 | \fnexample{fort_sa_private}{4} 20 | 21 | \topmarker{Fortran} 22 | \fnexample[5.1]{fort_sa_private}{5} 23 | \end{fortranspecific} 24 | 25 | -------------------------------------------------------------------------------- /data_environment/sources/associate.1.f: -------------------------------------------------------------------------------- 1 | ! @@name: associate.1 2 | ! @@type: F-fixed 3 | ! @@operation: compile 4 | ! @@expect: ct-error 5 | ! @@version: omp_4.0 6 | program example_broken 7 | real :: a, c 8 | associate (b => a) 9 | !$omp parallel private(b, c) ! invalid to privatize b 10 | c = 2.0*b 11 | !$omp end parallel 12 | end associate 13 | end program 14 | -------------------------------------------------------------------------------- /data_environment/sources/associate.2.f: -------------------------------------------------------------------------------- 1 | ! @@name: associate.2 2 | ! @@type: F-fixed 3 | ! @@operation: link 4 | ! @@expect: success 5 | ! @@version: omp_4.0 6 | program example 7 | use omp_lib 8 | integer i 9 | !$omp parallel private(i) 10 | i = omp_get_thread_num() 11 | associate(thread_id => i) 12 | print *, thread_id ! print private i value 13 | end associate 14 | !$omp end parallel 15 | end program 16 | -------------------------------------------------------------------------------- /data_environment/sources/associate.3.f90: -------------------------------------------------------------------------------- 1 | ! @@name: associate.3 2 | ! @@type: F-free 3 | ! @@operation: run 4 | ! @@expect: success 5 | ! @@version: omp_4.0 6 | program example 7 | integer :: v 8 | v = 15 9 | associate(u => v) 10 | !$omp parallel private(v) 11 | v = -1 12 | print *, "v=", v ! private v=-1 13 | print *, "u=", u ! original v=15 14 | !$omp end parallel 15 | end associate 16 | end program 17 | -------------------------------------------------------------------------------- /data_environment/sources/copyin.1.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: copyin.1 3 | * @@type: C 4 | * @@operation: compile 5 | * @@expect: success 6 | * @@version: pre_omp_3.0 7 | */ 8 | #include 9 | 10 | float* work; 11 | int size; 12 | float tol; 13 | 14 | #pragma omp threadprivate(work,size,tol) 15 | 16 | void build() 17 | { 18 | int i; 19 | work = (float*)malloc( sizeof(float)*size ); 20 | for( i = 0; i < size; ++i ) work[i] = tol; 21 | } 22 | 23 | void copyin_example( float t, int n ) 24 | { 25 | tol = t; 26 | size = n; 27 | #pragma omp parallel copyin(tol,size) 28 | { 29 | build(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /data_environment/sources/copyin.1.f: -------------------------------------------------------------------------------- 1 | ! @@name: copyin.1 2 | ! @@type: F-fixed 3 | ! @@operation: compile 4 | ! @@expect: success 5 | ! @@version: pre_omp_3.0 6 | MODULE M 7 | REAL, POINTER, SAVE :: WORK(:) 8 | INTEGER :: SIZE 9 | REAL :: TOL 10 | !$OMP THREADPRIVATE(WORK,SIZE,TOL) 11 | END MODULE M 12 | 13 | SUBROUTINE COPYIN_EXAMPLE( T, N ) 14 | USE M 15 | REAL :: T 16 | INTEGER :: N 17 | TOL = T 18 | SIZE = N 19 | !$OMP PARALLEL COPYIN(TOL,SIZE) 20 | CALL BUILD 21 | !$OMP END PARALLEL 22 | END SUBROUTINE COPYIN_EXAMPLE 23 | 24 | SUBROUTINE BUILD 25 | USE M 26 | ALLOCATE(WORK(SIZE)) 27 | WORK = TOL 28 | END SUBROUTINE BUILD 29 | -------------------------------------------------------------------------------- /data_environment/sources/copyprivate.1.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: copyprivate.1 3 | * @@type: C 4 | * @@operation: compile 5 | * @@expect: success 6 | * @@version: pre_omp_3.0 7 | */ 8 | #include 9 | float x, y; 10 | #pragma omp threadprivate(x, y) 11 | 12 | void init(float a, float b ) { 13 | #pragma omp single copyprivate(a,b,x,y) 14 | { 15 | scanf("%f %f %f %f", &a, &b, &x, &y); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /data_environment/sources/copyprivate.1.f: -------------------------------------------------------------------------------- 1 | ! @@name: copyprivate.1 2 | ! @@type: F-fixed 3 | ! @@operation: compile 4 | ! @@expect: success 5 | ! @@version: pre_omp_3.0 6 | SUBROUTINE INIT(A,B) 7 | REAL A, B 8 | COMMON /XY/ X,Y 9 | !$OMP THREADPRIVATE (/XY/) 10 | 11 | !$OMP SINGLE 12 | READ (11) A,B,X,Y 13 | !$OMP END SINGLE COPYPRIVATE (A,B,/XY/) 14 | 15 | END SUBROUTINE INIT 16 | -------------------------------------------------------------------------------- /data_environment/sources/copyprivate.2.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: copyprivate.2 3 | * @@type: C 4 | * @@operation: compile 5 | * @@expect: success 6 | * @@version: omp_5.1 7 | */ 8 | #include 9 | #include 10 | 11 | float read_next( ) { 12 | float * tmp; 13 | float return_val; 14 | 15 | #pragma omp single copyprivate(tmp) 16 | { 17 | tmp = (float *) malloc(sizeof(float)); 18 | } /* copies the pointer only */ 19 | 20 | 21 | #pragma omp masked 22 | { 23 | scanf("%f", tmp); 24 | } 25 | 26 | #pragma omp barrier 27 | return_val = *tmp; 28 | #pragma omp barrier 29 | 30 | #pragma omp single nowait 31 | { 32 | free(tmp); 33 | } 34 | 35 | return return_val; 36 | } 37 | -------------------------------------------------------------------------------- /data_environment/sources/copyprivate.2.f: -------------------------------------------------------------------------------- 1 | ! @@name: copyprivate.2 2 | ! @@type: F-fixed 3 | ! @@operation: compile 4 | ! @@expect: success 5 | ! @@version: omp_5.1 6 | REAL FUNCTION READ_NEXT() 7 | REAL, POINTER :: TMP 8 | 9 | !$OMP SINGLE 10 | ALLOCATE (TMP) 11 | !$OMP END SINGLE COPYPRIVATE (TMP) ! copies the pointer only 12 | 13 | !$OMP MASKED 14 | READ (11) TMP 15 | !$OMP END MASKED 16 | 17 | !$OMP BARRIER 18 | READ_NEXT = TMP 19 | !$OMP BARRIER 20 | 21 | !$OMP SINGLE 22 | DEALLOCATE (TMP) 23 | !$OMP END SINGLE NOWAIT 24 | END FUNCTION READ_NEXT 25 | -------------------------------------------------------------------------------- /data_environment/sources/copyprivate.3.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: copyprivate.3 3 | * @@type: C 4 | * @@operation: compile 5 | * @@expect: success 6 | * @@version: pre_omp_3.0 7 | */ 8 | #include 9 | #include 10 | #include 11 | 12 | omp_lock_t *new_lock() 13 | { 14 | omp_lock_t *lock_ptr; 15 | 16 | #pragma omp single copyprivate(lock_ptr) 17 | { 18 | lock_ptr = (omp_lock_t *) malloc(sizeof(omp_lock_t)); 19 | omp_init_lock( lock_ptr ); 20 | } 21 | 22 | return lock_ptr; 23 | } 24 | -------------------------------------------------------------------------------- /data_environment/sources/copyprivate.3.f: -------------------------------------------------------------------------------- 1 | ! @@name: copyprivate.3 2 | ! @@type: F-fixed 3 | ! @@operation: compile 4 | ! @@expect: success 5 | ! @@version: pre_omp_3.0 6 | FUNCTION NEW_LOCK() 7 | USE OMP_LIB ! or INCLUDE "omp_lib.h" 8 | INTEGER(OMP_LOCK_KIND), POINTER :: NEW_LOCK 9 | 10 | !$OMP SINGLE 11 | ALLOCATE(NEW_LOCK) 12 | CALL OMP_INIT_LOCK(NEW_LOCK) 13 | !$OMP END SINGLE COPYPRIVATE(NEW_LOCK) 14 | END FUNCTION NEW_LOCK 15 | -------------------------------------------------------------------------------- /data_environment/sources/copyprivate.4.f: -------------------------------------------------------------------------------- 1 | ! @@name: copyprivate.4 2 | ! @@type: F-fixed 3 | ! @@operation: compile 4 | ! @@expect: success 5 | ! @@version: pre_omp_3.0 6 | SUBROUTINE S(N) 7 | INTEGER N 8 | 9 | REAL, DIMENSION(:), ALLOCATABLE :: A 10 | REAL, DIMENSION(:), POINTER :: B 11 | 12 | ALLOCATE (A(N)) 13 | !$OMP SINGLE 14 | ALLOCATE (B(N)) 15 | READ (11) A,B 16 | !$OMP END SINGLE COPYPRIVATE(A,B) 17 | ! Variable A is private and is 18 | ! assigned the same value in each thread 19 | ! Variable B is shared 20 | 21 | !$OMP BARRIER 22 | !$OMP SINGLE 23 | DEALLOCATE (B) 24 | !$OMP END SINGLE NOWAIT 25 | END SUBROUTINE S 26 | -------------------------------------------------------------------------------- /data_environment/sources/cpp_reference.1.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: cpp_reference.1 3 | * @@type: C++ 4 | * @@operation: compile 5 | * @@expect: success 6 | * @@version: omp_4.5 7 | */ 8 | void task_body (int &); 9 | void gen_task (int &x) { // on orphaned task construct reference argument 10 | #pragma omp task // x is implicitly determined firstprivate(x) 11 | task_body (x); 12 | } 13 | void test (int &y, int &z) { 14 | #pragma omp parallel private(y) 15 | { 16 | y = z + 2; 17 | gen_task (y); // no matter if the argument is determined private 18 | gen_task (z); // or shared in the enclosing context. 19 | 20 | y++; // each thread has its own int object y refers to 21 | gen_task (y); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /data_environment/sources/fort_loopvar.1.f90: -------------------------------------------------------------------------------- 1 | ! @@name: fort_loopvar.1 2 | ! @@type: F-free 3 | ! @@operation: compile 4 | ! @@expect: success 5 | ! @@version: pre_omp_3.0 6 | SUBROUTINE PLOOP_1(A,N) 7 | INCLUDE "omp_lib.h" ! or USE OMP_LIB 8 | 9 | REAL A(*) 10 | INTEGER I, MYOFFSET, N 11 | 12 | !$OMP PARALLEL PRIVATE(MYOFFSET) 13 | MYOFFSET = OMP_GET_THREAD_NUM()*N 14 | DO I = 1, N 15 | A(MYOFFSET+I) = FLOAT(I) 16 | ENDDO 17 | !$OMP END PARALLEL 18 | 19 | END SUBROUTINE PLOOP_1 20 | -------------------------------------------------------------------------------- /data_environment/sources/fort_loopvar.2.f90: -------------------------------------------------------------------------------- 1 | ! @@name: fort_loopvar.2 2 | ! @@type: F-free 3 | ! @@operation: compile 4 | ! @@expect: success 5 | ! @@version: pre_omp_3.0 6 | SUBROUTINE PLOOP_2(A,B,N,I1,I2) 7 | REAL A(*), B(*) 8 | INTEGER I1, I2, N 9 | 10 | !$OMP PARALLEL SHARED(A,B,I1,I2) 11 | !$OMP SECTIONS 12 | !$OMP SECTION 13 | DO I1 = I1, N 14 | IF (A(I1).NE.0.0) EXIT 15 | ENDDO 16 | !$OMP SECTION 17 | DO I2 = I2, N 18 | IF (B(I2).NE.0.0) EXIT 19 | ENDDO 20 | !$OMP END SECTIONS 21 | !$OMP SINGLE 22 | IF (I1.LE.N) PRINT *, 'ITEMS IN A UP TO ', I1, 'ARE ALL ZERO.' 23 | IF (I2.LE.N) PRINT *, 'ITEMS IN B UP TO ', I2, 'ARE ALL ZERO.' 24 | !$OMP END SINGLE 25 | !$OMP END PARALLEL 26 | 27 | END SUBROUTINE PLOOP_2 28 | -------------------------------------------------------------------------------- /data_environment/sources/fort_sa_private.1.f: -------------------------------------------------------------------------------- 1 | ! @@name: fort_sa_private.1 2 | ! @@type: F-fixed 3 | ! @@operation: run 4 | ! @@expect: unspecified 5 | ! @@version: pre_omp_3.0 6 | SUBROUTINE SUB() 7 | COMMON /BLOCK/ X 8 | PRINT *,X ! X is undefined 9 | END SUBROUTINE SUB 10 | 11 | PROGRAM PRIV_RESTRICT 12 | COMMON /BLOCK/ X 13 | X = 1.0 14 | !$OMP PARALLEL PRIVATE (X) 15 | X = 2.0 16 | CALL SUB() 17 | !$OMP END PARALLEL 18 | END PROGRAM PRIV_RESTRICT 19 | -------------------------------------------------------------------------------- /data_environment/sources/fort_sa_private.2.f: -------------------------------------------------------------------------------- 1 | ! @@name: fort_sa_private.2 2 | ! @@type: F-fixed 3 | ! @@operation: run 4 | ! @@expect: unspecified 5 | ! @@version: pre_omp_3.0 6 | PROGRAM PRIV_RESTRICT2 7 | COMMON /BLOCK2/ X 8 | X = 1.0 9 | 10 | !$OMP PARALLEL PRIVATE (X) 11 | X = 2.0 12 | CALL SUB() 13 | !$OMP END PARALLEL 14 | 15 | CONTAINS 16 | 17 | SUBROUTINE SUB() 18 | COMMON /BLOCK2/ Y 19 | 20 | PRINT *,X ! X is undefined 21 | PRINT *,Y ! Y is undefined 22 | END SUBROUTINE SUB 23 | 24 | END PROGRAM PRIV_RESTRICT2 25 | -------------------------------------------------------------------------------- /data_environment/sources/fort_sa_private.3.f: -------------------------------------------------------------------------------- 1 | ! @@name: fort_sa_private.3 2 | ! @@type: F-fixed 3 | ! @@operation: run 4 | ! @@expect: unspecified 5 | ! @@version: pre_omp_3.0 6 | PROGRAM PRIV_RESTRICT3 7 | EQUIVALENCE (X,Y) 8 | X = 1.0 9 | 10 | !$OMP PARALLEL PRIVATE(X) 11 | PRINT *,Y ! Y is undefined 12 | Y = 10 13 | PRINT *,X ! X is undefined 14 | !$OMP END PARALLEL 15 | END PROGRAM PRIV_RESTRICT3 16 | -------------------------------------------------------------------------------- /data_environment/sources/fort_sp_common.1.f: -------------------------------------------------------------------------------- 1 | ! @@name: fort_sp_common.1 2 | ! @@type: F-fixed 3 | ! @@operation: compile 4 | ! @@expect: success 5 | ! @@version: pre_omp_3.0 6 | SUBROUTINE COMMON_GOOD() 7 | COMMON /C/ X,Y 8 | REAL X, Y 9 | 10 | !$OMP PARALLEL PRIVATE (/C/) 11 | ! do work here 12 | !$OMP END PARALLEL 13 | !$OMP PARALLEL SHARED (X,Y) 14 | ! do work here 15 | !$OMP END PARALLEL 16 | END SUBROUTINE COMMON_GOOD 17 | -------------------------------------------------------------------------------- /data_environment/sources/fort_sp_common.2.f: -------------------------------------------------------------------------------- 1 | ! @@name: fort_sp_common.2 2 | ! @@type: F-fixed 3 | ! @@operation: compile 4 | ! @@expect: success 5 | ! @@version: pre_omp_3.0 6 | SUBROUTINE COMMON_GOOD2() 7 | COMMON /C/ X,Y 8 | REAL X, Y 9 | INTEGER I 10 | !$OMP PARALLEL 11 | !$OMP DO PRIVATE(/C/) 12 | DO I=1,1000 13 | ! do work here 14 | ENDDO 15 | !$OMP END DO 16 | !$OMP DO PRIVATE(X) 17 | DO I=1,1000 18 | ! do work here 19 | ENDDO 20 | !$OMP END DO 21 | !$OMP END PARALLEL 22 | END SUBROUTINE COMMON_GOOD2 23 | -------------------------------------------------------------------------------- /data_environment/sources/fort_sp_common.3.f: -------------------------------------------------------------------------------- 1 | ! @@name: fort_sp_common.3 2 | ! @@type: F-fixed 3 | ! @@operation: compile 4 | ! @@expect: success 5 | ! @@version: pre_omp_3.0 6 | SUBROUTINE COMMON_GOOD3() 7 | COMMON /C/ X,Y 8 | !$OMP PARALLEL PRIVATE (/C/) 9 | ! do work here 10 | !$OMP END PARALLEL 11 | !$OMP PARALLEL SHARED (/C/) 12 | ! do work here 13 | !$OMP END PARALLEL 14 | END SUBROUTINE COMMON_GOOD3 15 | -------------------------------------------------------------------------------- /data_environment/sources/fort_sp_common.4.f: -------------------------------------------------------------------------------- 1 | ! @@name: fort_sp_common.4 2 | ! @@type: F-fixed 3 | ! @@operation: compile 4 | ! @@expect: ct-error 5 | ! @@version: pre_omp_3.0 6 | SUBROUTINE COMMON_WRONG() 7 | COMMON /C/ X,Y 8 | ! Incorrect because X is a constituent element of C 9 | !$OMP PARALLEL PRIVATE(/C/), SHARED(X) 10 | ! do work here 11 | !$OMP END PARALLEL 12 | END SUBROUTINE COMMON_WRONG 13 | -------------------------------------------------------------------------------- /data_environment/sources/fort_sp_common.5.f: -------------------------------------------------------------------------------- 1 | ! @@name: fort_sp_common.5 2 | ! @@type: F-fixed 3 | ! @@operation: compile 4 | ! @@expect: ct-error 5 | ! @@version: pre_omp_3.0 6 | SUBROUTINE COMMON_WRONG2() 7 | COMMON /C/ X,Y 8 | ! Incorrect: common block C cannot be declared both 9 | ! shared and private 10 | !$OMP PARALLEL PRIVATE (/C/), SHARED(/C/) 11 | ! do work here 12 | !$OMP END PARALLEL 13 | 14 | END SUBROUTINE COMMON_WRONG2 15 | -------------------------------------------------------------------------------- /data_environment/sources/lastprivate.1.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: lastprivate.1 3 | * @@type: C 4 | * @@operation: compile 5 | * @@expect: success 6 | * @@version: pre_omp_3.0 7 | */ 8 | void lastpriv (int n, float *a, float *b) 9 | { 10 | int i; 11 | 12 | #pragma omp parallel 13 | { 14 | #pragma omp for lastprivate(i) 15 | for (i=0; i 9 | 10 | float condlastprivate(float *a, int n) 11 | { 12 | float x = 0.0f; 13 | 14 | #pragma omp parallel for simd lastprivate(conditional: x) 15 | for (int k = 0; k < n; k++) { 16 | if (a[k] < 108.5 || a[k] > 208.5) { 17 | x = sinf(a[k]); 18 | } 19 | } 20 | 21 | return x; 22 | } 23 | -------------------------------------------------------------------------------- /data_environment/sources/lastprivate.2.f90: -------------------------------------------------------------------------------- 1 | ! @@name: lastprivate.2 2 | ! @@type: F-free 3 | ! @@operation: compile 4 | ! @@expect: success 5 | ! @@version: omp_5.0 6 | function condlastprivate(a, n) result(x) 7 | implicit none 8 | real a(*), x 9 | integer n, k 10 | 11 | x = 0.0 12 | 13 | !$omp parallel do simd lastprivate(conditional: x) 14 | do k = 1, n 15 | if (a(k) < 108.5 .or. a(k) > 208.5) then 16 | x = sin(a(k)) 17 | endif 18 | end do 19 | 20 | end function condlastprivate 21 | -------------------------------------------------------------------------------- /data_environment/sources/priv_reduction.1.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: priv_reduction.1 3 | * @@type: C 4 | * @@operation: run 5 | * @@expect: success 6 | * @@version: omp_6.0 7 | */ 8 | #include 9 | #include 10 | #define N 100 11 | 12 | int do_red(int n, int *v) 13 | { 14 | int sum_v = 0; // sum_v is private 15 | 16 | #pragma omp for reduction(+: sum_v) 17 | for (int i = 0; i < n; i++) { 18 | sum_v += v[i]; 19 | } 20 | return sum_v; 21 | } 22 | 23 | int main(void) 24 | { 25 | int v[N]; 26 | for (int i = 0; i < N; i++) 27 | v[i] = i; 28 | 29 | #pragma omp parallel 30 | { 31 | int s_v = do_red(N, v); 32 | printf("myid %d: sum of v = %d\n", omp_get_thread_num(), s_v); 33 | } 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /data_environment/sources/priv_reduction.2.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: priv_reduction.2 3 | * @@type: C++ 4 | * @@operation: run 5 | * @@expect: success 6 | * @@version: omp_6.0 7 | */ 8 | #include 9 | #include 10 | #define N 100 11 | 12 | void do_red(int n, int *v, int &sum_v) 13 | { 14 | sum_v = 0; // sum_v is private 15 | #pragma omp for reduction(original(private),+: sum_v) 16 | for (int i = 0; i < n; i++) { 17 | sum_v += v[i]; 18 | } 19 | } 20 | 21 | int main(void) 22 | { 23 | int v[N]; 24 | for (int i = 0; i < N; i++) 25 | v[i] = i; 26 | 27 | #pragma omp parallel 28 | { 29 | int s_v; // s_v is private 30 | do_red(N, v, s_v); 31 | printf("myid %d: sum of v = %d\n", omp_get_thread_num(), s_v); 32 | } 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /data_environment/sources/priv_reduction.3.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: priv_reduction.3 3 | * @@type: C 4 | * @@operation: run 5 | * @@expect: success 6 | * @@version: omp_6.0 7 | */ 8 | #include 9 | 10 | int main(void) 11 | { 12 | int x; 13 | 14 | x = 0; 15 | // parallel reduction on shared x 16 | #pragma omp parallel reduction(+: x) num_threads(strict: 4) 17 | { 18 | #pragma omp for reduction(+: x) // reduction on private x 19 | for (int i = 0; i < 10; i++) 20 | x++; 21 | } 22 | printf("x = %d\n", x); // should print 40, with 4 threads 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /data_environment/sources/priv_reduction.3.f90: -------------------------------------------------------------------------------- 1 | ! @@name: priv_reduction.3 2 | ! @@type: F-free 3 | ! @@operation: run 4 | ! @@expect: success 5 | ! @@version: omp_6.0 6 | program nest_red 7 | implicit none 8 | integer :: x 9 | 10 | x = 0 11 | ! parallel reduction on shared x 12 | !$omp parallel reduction(+: x) num_threads(strict: 4) 13 | !$omp do reduction(+: x) ! reduction on private x 14 | do i = 1, 10 15 | x = x + 1 16 | end do 17 | !$omp end do 18 | !$omp end parallel 19 | print *, "x =", x ! should print 40, with 4 threads 20 | end program 21 | -------------------------------------------------------------------------------- /data_environment/sources/private.1.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: private.1 3 | * @@type: C 4 | * @@operation: run 5 | * @@expect: success 6 | * @@version: pre_omp_3.0 7 | */ 8 | #include 9 | #include 10 | 11 | int main() 12 | { 13 | int i, j; 14 | int *ptr_i, *ptr_j; 15 | 16 | i = 1; 17 | j = 2; 18 | 19 | ptr_i = &i; 20 | ptr_j = &j; 21 | 22 | #pragma omp parallel private(i) firstprivate(j) 23 | { 24 | i = 3; 25 | j = j + 2; 26 | assert (*ptr_i == 1 && *ptr_j == 2); 27 | } 28 | 29 | assert(i == 1 && j == 2); 30 | 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /data_environment/sources/private.1.f: -------------------------------------------------------------------------------- 1 | ! @@name: private.1 2 | ! @@type: F-fixed 3 | ! @@operation: run 4 | ! @@expect: success 5 | ! @@version: pre_omp_3.0 6 | PROGRAM PRIV_EXAMPLE 7 | INTEGER I, J 8 | 9 | I = 1 10 | J = 2 11 | 12 | !$OMP PARALLEL PRIVATE(I) FIRSTPRIVATE(J) 13 | I = 3 14 | J = J + 2 15 | !$OMP END PARALLEL 16 | 17 | PRINT *, I, J ! I .eq. 1 .and. J .eq. 2 18 | END PROGRAM PRIV_EXAMPLE 19 | -------------------------------------------------------------------------------- /data_environment/sources/private.2.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: private.2 3 | * @@type: C 4 | * @@operation: compile 5 | * @@expect: unspecified 6 | * @@version: pre_omp_3.0 7 | */ 8 | int a; 9 | 10 | void g(int k) { 11 | a = k; /* Accessed in the region but outside of the construct; 12 | * therefore unspecified whether original or private list 13 | * item is modified. */ 14 | } 15 | 16 | 17 | void f(int n) { 18 | int a = 0; 19 | 20 | #pragma omp parallel for private(a) 21 | for (int i=1; i 9 | void priv_example3() 10 | { 11 | int i, a; 12 | 13 | #pragma omp parallel private(a) 14 | { 15 | a = 1; 16 | #pragma omp parallel for private(a) 17 | for (i=0; i<10; i++) 18 | { 19 | a = 2; 20 | } 21 | assert(a == 1); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /data_environment/sources/private.3.f: -------------------------------------------------------------------------------- 1 | ! @@name: private.3 2 | ! @@type: F-fixed 3 | ! @@operation: compile 4 | ! @@expect: success 5 | ! @@version: pre_omp_3.0 6 | SUBROUTINE PRIV_EXAMPLE3() 7 | INTEGER I, A 8 | 9 | !$OMP PARALLEL PRIVATE(A) 10 | A = 1 11 | !$OMP PARALLEL DO PRIVATE(A) 12 | DO I = 1, 10 13 | A = 2 14 | END DO 15 | !$OMP END PARALLEL DO 16 | PRINT *, A ! Outer A still has value 1 17 | !$OMP END PARALLEL 18 | END SUBROUTINE PRIV_EXAMPLE3 19 | -------------------------------------------------------------------------------- /data_environment/sources/reduction.1.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: reduction.1 3 | * @@type: C 4 | * @@operation: compile 5 | * @@expect: success 6 | * @@version: omp_3.1 7 | */ 8 | #include 9 | void reduction1(float *x, int *y, int n) 10 | { 11 | int i, b, c; 12 | float a, d; 13 | a = 0.0; 14 | b = 0; 15 | c = y[0]; 16 | d = x[0]; 17 | #pragma omp parallel for private(i) shared(x, y, n) \ 18 | reduction(+:a) reduction(^:b) \ 19 | reduction(min:c) reduction(max:d) 20 | for (i=0; i y[i]) c = y[i]; 24 | d = fmaxf(d,x[i]); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /data_environment/sources/reduction.1.f90: -------------------------------------------------------------------------------- 1 | ! @@name: reduction.1 2 | ! @@type: F-free 3 | ! @@operation: compile 4 | ! @@expect: success 5 | ! @@version: pre_omp_3.0 6 | SUBROUTINE REDUCTION1(A, B, C, D, X, Y, N) 7 | REAL :: X(*), A, D 8 | INTEGER :: Y(*), N, B, C 9 | INTEGER :: I 10 | A = 0 11 | B = 0 12 | C = Y(1) 13 | D = X(1) 14 | !$OMP PARALLEL DO PRIVATE(I) SHARED(X, Y, N) REDUCTION(+:A) & 15 | !$OMP& REDUCTION(IEOR:B) REDUCTION(MIN:C) REDUCTION(MAX:D) 16 | DO I=1,N 17 | A = A + X(I) 18 | B = IEOR(B, Y(I)) 19 | C = MIN(C, Y(I)) 20 | IF (D < X(I)) D = X(I) 21 | END DO 22 | 23 | END SUBROUTINE REDUCTION1 24 | -------------------------------------------------------------------------------- /data_environment/sources/reduction.3.f90: -------------------------------------------------------------------------------- 1 | ! @@name: reduction.3 2 | ! @@type: F-free 3 | ! @@operation: compile 4 | ! @@expect: ct-error 5 | ! @@version: pre_omp_3.0 6 | PROGRAM REDUCTION_WRONG 7 | MAX = HUGE(0) 8 | M = 0 9 | 10 | !$OMP PARALLEL DO REDUCTION(MAX: M) 11 | ! MAX is no longer the intrinsic so this is non-conforming 12 | DO I = 1, 100 13 | CALL SUB(M,I) 14 | END DO 15 | 16 | END PROGRAM REDUCTION_WRONG 17 | 18 | SUBROUTINE SUB(M,I) 19 | M = MAX(M,I) 20 | END SUBROUTINE SUB 21 | -------------------------------------------------------------------------------- /data_environment/sources/reduction.4.f90: -------------------------------------------------------------------------------- 1 | ! @@name: reduction.4 2 | ! @@type: F-free 3 | ! @@operation: run 4 | ! @@expect: success 5 | ! @@version: pre_omp_3.0 6 | MODULE M 7 | INTRINSIC MAX 8 | END MODULE M 9 | 10 | PROGRAM REDUCTION3 11 | USE M, REN => MAX 12 | N = 0 13 | !$OMP PARALLEL DO REDUCTION(REN: N) ! still does MAX 14 | DO I = 1, 100 15 | N = MAX(N,I) 16 | END DO 17 | END PROGRAM REDUCTION3 18 | -------------------------------------------------------------------------------- /data_environment/sources/reduction.5.f90: -------------------------------------------------------------------------------- 1 | ! @@name: reduction.5 2 | ! @@type: F-free 3 | ! @@operation: run 4 | ! @@expect: success 5 | ! @@version: pre_omp_3.0 6 | MODULE MOD 7 | INTRINSIC MAX, MIN 8 | END MODULE MOD 9 | 10 | PROGRAM REDUCTION4 11 | USE MOD, MIN=>MAX, MAX=>MIN 12 | REAL :: R 13 | R = -HUGE(0.0) 14 | 15 | !$OMP PARALLEL DO REDUCTION(MIN: R) ! still does MAX 16 | DO I = 1, 1000 17 | R = MIN(R, SIN(REAL(I))) 18 | END DO 19 | PRINT *, R 20 | END PROGRAM REDUCTION4 21 | -------------------------------------------------------------------------------- /data_environment/sources/reduction.6.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: reduction.6 3 | * @@type: C 4 | * @@operation: run 5 | * @@expect: unspecified 6 | * @@version: omp_5.1 7 | */ 8 | #include 9 | 10 | int main (void) 11 | { 12 | int a, i; 13 | 14 | #pragma omp parallel shared(a) private(i) 15 | { 16 | #pragma omp masked 17 | a = 0; 18 | 19 | // To avoid race conditions, add a barrier here. 20 | 21 | #pragma omp for reduction(+:a) 22 | for (i = 0; i < 10; i++) { 23 | a += i; 24 | } 25 | 26 | #pragma omp single 27 | printf ("Sum is %d\n", a); 28 | } 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /data_environment/sources/reduction.6.f: -------------------------------------------------------------------------------- 1 | ! @@name: reduction.6 2 | ! @@type: F-fixed 3 | ! @@operation: run 4 | ! @@expect: unspecified 5 | ! @@version: omp_5.1 6 | INTEGER A, I 7 | 8 | !$OMP PARALLEL SHARED(A) PRIVATE(I) 9 | 10 | !$OMP MASKED 11 | A = 0 12 | !$OMP END MASKED 13 | 14 | ! To avoid race conditions, add a barrier here. 15 | 16 | !$OMP DO REDUCTION(+:A) 17 | DO I= 0, 9 18 | A = A + I 19 | END DO 20 | 21 | !$OMP SINGLE 22 | PRINT *, "Sum is ", A 23 | !$OMP END SINGLE 24 | 25 | !$OMP END PARALLEL 26 | 27 | END 28 | -------------------------------------------------------------------------------- /data_environment/sources/reduction.7.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: reduction.7 3 | * @@type: C 4 | * @@operation: compile 5 | * @@expect: success 6 | * @@version: omp_4.5 7 | */ 8 | #include 9 | 10 | #define N 100 11 | void init(int n, float (*b)[N]); 12 | 13 | int main(){ 14 | 15 | int i,j; 16 | float a[N], b[N][N]; 17 | 18 | init(N,b); 19 | 20 | for(i=0; i 9 | #define N 100 10 | 11 | int main(void) 12 | { 13 | int a[N], b[N]; 14 | int x = 0; 15 | 16 | // initialization 17 | for (int k = 0; k < N; k++) 18 | a[k] = k + 1; 19 | 20 | // a[k] is included in the computation of producing results in b[k] 21 | #pragma omp parallel for simd reduction(inscan,+: x) 22 | for (int k = 0; k < N; k++) { 23 | x += a[k]; 24 | #pragma omp scan inclusive(x) 25 | b[k] = x; 26 | } 27 | 28 | printf("x = %d, b[0:3] = %d %d %d\n", x, b[0], b[1], b[2]); 29 | // 5050, 1 3 6 30 | 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /data_environment/sources/scan.1.f90: -------------------------------------------------------------------------------- 1 | ! @@name: scan.1 2 | ! @@type: F-free 3 | ! @@operation: run 4 | ! @@expect: success 5 | ! @@version: omp_5.0 6 | program inclusive_scan 7 | implicit none 8 | integer, parameter :: n = 100 9 | integer a(n), b(n) 10 | integer x, k 11 | 12 | ! initialization 13 | x = 0 14 | do k = 1, n 15 | a(k) = k 16 | end do 17 | 18 | ! a(k) is included in the computation of producing results in b(k) 19 | !$omp parallel do simd reduction(inscan,+: x) 20 | do k = 1, n 21 | x = x + a(k) 22 | !$omp scan inclusive(x) 23 | b(k) = x 24 | end do 25 | 26 | print *,'x =', x, ', b(1:3) =', b(1:3) 27 | ! 5050, 1 3 6 28 | 29 | end program 30 | -------------------------------------------------------------------------------- /data_environment/sources/scan.2.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: scan.2 3 | * @@type: C 4 | * @@operation: run 5 | * @@expect: success 6 | * @@version: omp_5.0 7 | */ 8 | #include 9 | #define N 100 10 | 11 | int main(void) 12 | { 13 | int a[N], b[N]; 14 | int x = 0; 15 | 16 | // initialization 17 | for (int k = 0; k < N; k++) 18 | a[k] = k + 1; 19 | 20 | // a[k] is not included in the computation of producing 21 | // results in b[k] 22 | #pragma omp parallel for simd reduction(inscan,+: x) 23 | for (int k = 0; k < N; k++) { 24 | b[k] = x; 25 | #pragma omp scan exclusive(x) 26 | x += a[k]; 27 | } 28 | 29 | printf("x = %d, b[0:3] = %d %d %d\n", x, b[0], b[1], b[2]); 30 | // 5050, 0 1 3 31 | 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /data_environment/sources/scan.2.f90: -------------------------------------------------------------------------------- 1 | ! @@name: scan.2 2 | ! @@type: F-free 3 | ! @@operation: run 4 | ! @@expect: success 5 | ! @@version: omp_5.0 6 | program exclusive_scan 7 | implicit none 8 | integer, parameter :: n = 100 9 | integer a(n), b(n) 10 | integer x, k 11 | 12 | ! initialization 13 | x = 0 14 | do k = 1, n 15 | a(k) = k 16 | end do 17 | 18 | ! a(k) is not included in the computation of producing results in b(k) 19 | !$omp parallel do simd reduction(inscan,+: x) 20 | do k = 1, n 21 | b(k) = x 22 | !$omp scan exclusive(x) 23 | x = x + a(k) 24 | end do 25 | 26 | print *,'x =', x, ', b(1:3) =', b(1:3) 27 | ! 5050, 0 1 3 28 | 29 | end program 30 | -------------------------------------------------------------------------------- /data_environment/sources/target_reduction.1.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: target_reduction.1 3 | * @@type: C 4 | * @@operation: run 5 | * @@expect: success 6 | * @@version: omp_5.0 7 | */ 8 | #include 9 | int f(int); 10 | int g(int); 11 | int main() 12 | { 13 | int sum1=0, sum2=0; 14 | const int n = 100; 15 | 16 | #pragma omp target teams distribute reduction(+:sum1) 17 | for (int i = 0; i < n; i++) { 18 | sum1 += f(i); 19 | } 20 | 21 | #pragma omp target teams distribute reduction(+:sum2) 22 | for (int i = 0; i < n; i++) { 23 | sum2 += g(i) * sum1; 24 | } 25 | 26 | printf( "sum1 = %d, sum2 = %d\n", sum1, sum2); 27 | //OUTPUT: sum1 = 9900, sum2 = 147015000 28 | return 0; 29 | } 30 | 31 | int f(int res){ return res*2; } 32 | int g(int res){ return res*3; } 33 | -------------------------------------------------------------------------------- /data_environment/sources/target_task_reduction.2b.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: target_task_reduction.2b 3 | * @@type: C 4 | * @@operation: run 5 | * @@expect: success 6 | * @@version: omp_5.2 7 | */ 8 | #include 9 | extern void device_compute(int *); 10 | #pragma omp declare target enter(device_compute) 11 | extern void host_compute(int *); 12 | int main() 13 | { 14 | int sum = 0; 15 | 16 | #pragma omp parallel masked reduction(task, +:sum) 17 | { 18 | #pragma omp target in_reduction(+:sum) nowait 19 | device_compute(&sum); 20 | 21 | host_compute(&sum); 22 | } 23 | printf( "sum = %d\n", sum); 24 | //OUTPUT: sum = 2 25 | return 0; 26 | } 27 | 28 | void device_compute(int *sum){ *sum = 1; } 29 | void host_compute(int *sum){ *sum = 1; } 30 | -------------------------------------------------------------------------------- /data_environment/sources/taskloop_reduction.1.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: taskloop_reduction.1 3 | * @@type: C 4 | * @@operation: run 5 | * @@expect: success 6 | * @@version: omp_5.0 7 | */ 8 | #include 9 | 10 | int array_sum(int n, int *v) { 11 | int i; 12 | int res = 0; 13 | 14 | #pragma omp taskloop reduction(+: res) 15 | for(i = 0; i < n; ++i) 16 | res += v[i]; 17 | 18 | return res; 19 | } 20 | 21 | int main(int argc, char *argv[]) { 22 | int n = 10; 23 | int v[10] = {1,2,3,4,5,6,7,8,9,10}; 24 | 25 | #pragma omp parallel 26 | #pragma omp single 27 | { 28 | int res = array_sum(n, v); 29 | printf("The result is %d\n", res); 30 | } 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /data_environment/sources/threadprivate.1.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: threadprivate.1 3 | * @@type: C 4 | * @@operation: compile 5 | * @@expect: success 6 | * @@version: pre_omp_3.0 7 | */ 8 | int counter = 0; 9 | #pragma omp threadprivate(counter) 10 | 11 | int increment_counter() 12 | { 13 | counter++; 14 | return(counter); 15 | } 16 | -------------------------------------------------------------------------------- /data_environment/sources/threadprivate.1.f: -------------------------------------------------------------------------------- 1 | ! @@name: threadprivate.1 2 | ! @@type: F-fixed 3 | ! @@operation: compile 4 | ! @@expect: success 5 | ! @@version: pre_omp_3.0 6 | INTEGER FUNCTION INCREMENT_COUNTER() 7 | COMMON/INC_COMMON/COUNTER 8 | !$OMP THREADPRIVATE(/INC_COMMON/) 9 | 10 | COUNTER = COUNTER +1 11 | INCREMENT_COUNTER = COUNTER 12 | RETURN 13 | END FUNCTION INCREMENT_COUNTER 14 | -------------------------------------------------------------------------------- /data_environment/sources/threadprivate.2.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: threadprivate.2 3 | * @@type: C 4 | * @@operation: compile 5 | * @@expect: success 6 | * @@version: pre_omp_3.0 7 | */ 8 | int increment_counter_2() 9 | { 10 | static int counter = 0; 11 | #pragma omp threadprivate(counter) 12 | counter++; 13 | return(counter); 14 | } 15 | -------------------------------------------------------------------------------- /data_environment/sources/threadprivate.2.f: -------------------------------------------------------------------------------- 1 | ! @@name: threadprivate.2 2 | ! @@type: F-fixed 3 | ! @@operation: compile 4 | ! @@expect: ct-error 5 | ! @@version: pre_omp_3.0 6 | MODULE INC_MODULE 7 | COMMON /T/ A 8 | END MODULE INC_MODULE 9 | 10 | SUBROUTINE INC_MODULE_WRONG() 11 | USE INC_MODULE 12 | !$OMP THREADPRIVATE(/T/) 13 | !non-conforming because /T/ not declared in INC_MODULE_WRONG 14 | END SUBROUTINE INC_MODULE_WRONG 15 | -------------------------------------------------------------------------------- /data_environment/sources/threadprivate.3.f: -------------------------------------------------------------------------------- 1 | ! @@name: threadprivate.3 2 | ! @@type: F-fixed 3 | ! @@operation: compile 4 | ! @@expect: ct-error 5 | ! @@version: pre_omp_3.0 6 | SUBROUTINE INC_WRONG() 7 | COMMON /T/ A 8 | !$OMP THREADPRIVATE(/T/) 9 | 10 | CONTAINS 11 | SUBROUTINE INC_WRONG_SUB() 12 | !$OMP PARALLEL COPYIN(/T/) 13 | !non-conforming because /T/ not declared in INC_WRONG_SUB 14 | !$OMP END PARALLEL 15 | END SUBROUTINE INC_WRONG_SUB 16 | END SUBROUTINE INC_WRONG 17 | -------------------------------------------------------------------------------- /data_environment/sources/threadprivate.4.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: threadprivate.4 3 | * @@type: C++ 4 | * @@operation: view 5 | * @@expect: unspecified 6 | * @@version: pre_omp_3.0 7 | */ 8 | struct T { T (); T (int); ~T (); int t; }; 9 | int f(); 10 | static T t1; 11 | #pragma omp threadprivate(t1) 12 | static T t2( 23 ); 13 | #pragma omp threadprivate(t2) 14 | static T t3 = f(); 15 | #pragma omp threadprivate(t3) 16 | -------------------------------------------------------------------------------- /data_environment/sources/threadprivate.4.f: -------------------------------------------------------------------------------- 1 | ! @@name: threadprivate.4 2 | ! @@type: F-fixed 3 | ! @@operation: compile 4 | ! @@expect: success 5 | ! @@version: pre_omp_3.0 6 | SUBROUTINE INC_GOOD() 7 | COMMON /T/ A 8 | !$OMP THREADPRIVATE(/T/) 9 | 10 | CONTAINS 11 | SUBROUTINE INC_GOOD_SUB() 12 | COMMON /T/ A 13 | !$OMP THREADPRIVATE(/T/) 14 | 15 | !$OMP PARALLEL COPYIN(/T/) 16 | !$OMP END PARALLEL 17 | END SUBROUTINE INC_GOOD_SUB 18 | END SUBROUTINE INC_GOOD 19 | -------------------------------------------------------------------------------- /data_environment/sources/threadprivate.5.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: threadprivate.5 3 | * @@type: C++ 4 | * @@operation: view 5 | * @@expect: unspecified 6 | * @@version: pre_omp_3.0 7 | */ 8 | class T { 9 | public: 10 | static int i; 11 | #pragma omp threadprivate(i) 12 | }; 13 | -------------------------------------------------------------------------------- /data_environment/sources/udr.5.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: udr.5 3 | * @@type: C++ 4 | * @@operation: compile 5 | * @@expect: success 6 | * @@version: omp_6.0 7 | */ 8 | class V { 9 | float *p; 10 | int n; 11 | 12 | public: 13 | V( int _n ) : n(_n) { p = new float[n]; } 14 | V( const V& m ) : n(m.n) { p = new float[n]; } 15 | ~V() { delete[] p; } 16 | 17 | V& operator+= ( const V& ); 18 | 19 | #pragma omp declare reduction( + : V ) combiner( omp_out += omp_in ) \ 20 | initializer(omp_priv(omp_orig)) 21 | }; 22 | -------------------------------------------------------------------------------- /data_environment/sources/udr.6.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: udr.6 3 | * @@type: C++ 4 | * @@operation: view 5 | * @@expect: unspecified 6 | * @@version: omp_6.0 7 | */ 8 | #include 9 | #include 10 | #include 11 | 12 | #pragma omp declare reduction( + : std::vector ) \ 13 | combiner( std::transform (omp_out.begin(), omp_out.end(), \ 14 | omp_in.begin(), omp_in.end(),std::plus()) ) 15 | 16 | #pragma omp declare reduction( merge : std::vector ) \ 17 | combiner( omp_out.insert(omp_out.end(), omp_in.begin(), \ 18 | omp_in.end()) ) 19 | 20 | #pragma omp declare reduction( merge : std::list ) \ 21 | combiner( omp_out.merge(omp_in) ) 22 | -------------------------------------------------------------------------------- /devices/async_target_depend.tex: -------------------------------------------------------------------------------- 1 | \pagebreak 2 | \section{Asynchronous \kcode{target} Execution and Dependences} 3 | \label{sec:async_target_exec_depend} 4 | 5 | Asynchronous execution of a \kcode{target} region can be accomplished 6 | by creating an explicit task around the \kcode{target} region. Examples 7 | with explicit tasks are shown at the beginning of this section. 8 | 9 | As of OpenMP 4.5 and beyond the \kcode{nowait} clause can be used on the 10 | \kcode{target} directive for asynchronous execution. Examples with 11 | \kcode{nowait} clauses follow the examples with explicit tasks. 12 | 13 | This section also shows the use of \kcode{depend} clauses to order 14 | executions through dependences. 15 | -------------------------------------------------------------------------------- /devices/sources/array_sections.1.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: array_sections.1 3 | * @@type: C 4 | * @@operation: compile 5 | * @@expect: ct-error 6 | * @@version: omp_4.0 7 | */ 8 | void foo () 9 | { 10 | int A[30]; 11 | #pragma omp target data map( A[0:4] ) 12 | { 13 | /* Cannot map distinct parts of the same array */ 14 | #pragma omp target map( A[7:20] ) 15 | { 16 | A[2] = 0; 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /devices/sources/array_sections.1.f90: -------------------------------------------------------------------------------- 1 | ! @@name: array_sections.1 2 | ! @@type: F-free 3 | ! @@operation: compile 4 | ! @@expect: ct-error 5 | ! @@version: omp_4.0 6 | subroutine foo() 7 | integer :: A(30) 8 | A = 1 9 | !$omp target data map( A(1:4) ) 10 | ! Cannot map distinct parts of the same array 11 | !$omp target map( A(8:27) ) 12 | A(3) = 0 13 | !$omp end target 14 | !$omp end target data 15 | end subroutine 16 | -------------------------------------------------------------------------------- /devices/sources/array_sections.2.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: array_sections.2 3 | * @@type: C 4 | * @@operation: compile 5 | * @@expect: ct-error 6 | * @@version: omp_4.0 7 | */ 8 | void foo () 9 | { 10 | int A[30], *p; 11 | #pragma omp target data map( A[0:4] ) 12 | { 13 | p = &A[0]; 14 | /* invalid because p[3] and A[3] are the same 15 | * location on the host but the array section 16 | * specified via p[...] is not a subset of A[0:4] */ 17 | #pragma omp target map( p[3:20] ) 18 | { 19 | A[2] = 0; 20 | p[8] = 0; 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /devices/sources/array_sections.2.f90: -------------------------------------------------------------------------------- 1 | ! @@name: array_sections.2 2 | ! @@type: F-free 3 | ! @@operation: compile 4 | ! @@expect: ct-error 5 | ! @@version: omp_4.0 6 | subroutine foo() 7 | integer,target :: A(30) 8 | integer,pointer :: p(:) 9 | A=1 10 | !$omp target data map( A(1:4) ) 11 | p=>A 12 | ! invalid because p(4) and A(4) are the same 13 | ! location on the host but the array section 14 | ! specified via p(...) is not a subset of A(1:4) 15 | !$omp target map( p(4:23) ) 16 | A(3) = 0 17 | p(9) = 0 18 | !$omp end target 19 | !$omp end target data 20 | end subroutine 21 | -------------------------------------------------------------------------------- /devices/sources/array_sections.3.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: array_sections.3 3 | * @@type: C 4 | * @@operation: compile 5 | * @@expect: success 6 | * @@version: omp_4.0 7 | */ 8 | void foo () 9 | { 10 | int A[30], *p; 11 | #pragma omp target data map( A[0:4] ) 12 | { 13 | p = &A[0]; 14 | #pragma omp target map( p[7:20] ) 15 | { 16 | A[2] = 0; 17 | p[8] = 0; 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /devices/sources/array_sections.3.f90: -------------------------------------------------------------------------------- 1 | ! @@name: array_sections.3 2 | ! @@type: F-free 3 | ! @@operation: compile 4 | ! @@expect: success 5 | ! @@version: omp_4.0 6 | subroutine foo() 7 | integer,target :: A(30) 8 | integer,pointer :: p(:) 9 | !$omp target data map( A(1:4) ) 10 | p=>A 11 | !$omp target map( p(8:27) ) 12 | A(3) = 0 13 | p(9) = 0 14 | !$omp end target 15 | !$omp end target data 16 | end subroutine 17 | -------------------------------------------------------------------------------- /devices/sources/array_sections.4.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: array_sections.4 3 | * @@type: C 4 | * @@operation: compile 5 | * @@expect: success 6 | * @@version: omp_4.0 7 | */ 8 | void foo () 9 | { 10 | int A[30], *p; 11 | #pragma omp target data map( A[0:10] ) 12 | { 13 | p = &A[0]; 14 | #pragma omp target map( p[3:7] ) 15 | { 16 | A[2] = 0; 17 | p[8] = 0; 18 | A[8] = 1; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /devices/sources/array_sections.4.f90: -------------------------------------------------------------------------------- 1 | ! @@name: array_sections.4 2 | ! @@type: F-free 3 | ! @@operation: compile 4 | ! @@expect: success 5 | ! @@version: omp_4.0 6 | subroutine foo() 7 | integer,target :: A(30) 8 | integer,pointer :: p(:) 9 | !$omp target data map( A(1:10) ) 10 | p=>A 11 | !$omp target map( p(4:10) ) 12 | A(3) = 0 13 | p(9) = 0 14 | A(9) = 1 15 | !$omp end target 16 | !$omp end target data 17 | end subroutine 18 | -------------------------------------------------------------------------------- /devices/sources/async_target.1.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: async_target.1 3 | * @@type: C 4 | * @@operation: compile 5 | * @@expect: success 6 | * @@version: omp_5.1 7 | */ 8 | #pragma omp begin declare target 9 | float F(float); 10 | #pragma omp end declare target 11 | 12 | #define N 1000000000 13 | #define CHUNKSZ 1000000 14 | void init(float *, int); 15 | float Z[N]; 16 | void pipedF(){ 17 | int C, i; 18 | init(Z, N); 19 | for (C=0; C THRESHOLD) 16 | { 17 | fib(n); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /devices/sources/declare_target.1.f90: -------------------------------------------------------------------------------- 1 | ! @@name: declare_target.1 2 | ! @@type: F-free 3 | ! @@operation: compile 4 | ! @@expect: success 5 | ! @@version: omp_4.0 6 | module module_fib 7 | integer :: THRESHOLD=1000000 8 | contains 9 | subroutine fib(N) 10 | integer :: N 11 | !$omp declare target 12 | !... 13 | end subroutine 14 | end module 15 | subroutine my_fib(N) 16 | use module_fib 17 | integer :: N 18 | !$omp target if( N > THRESHOLD ) 19 | call fib(N) 20 | !$omp end target 21 | end subroutine 22 | -------------------------------------------------------------------------------- /devices/sources/declare_target.2.f90: -------------------------------------------------------------------------------- 1 | ! @@name: declare_target.2 2 | ! @@type: F-free 3 | ! @@operation: link 4 | ! @@expect: success 5 | ! @@version: omp_4.0 6 | program my_fib 7 | integer :: N = 8 8 | interface 9 | subroutine fib(N) 10 | !$omp declare target 11 | integer :: N 12 | end subroutine fib 13 | end interface 14 | !$omp target 15 | call fib(N) 16 | !$omp end target 17 | end program 18 | subroutine fib(N) 19 | integer :: N 20 | !$omp declare target 21 | print*,"hello from fib" 22 | !... 23 | end subroutine 24 | -------------------------------------------------------------------------------- /devices/sources/declare_target.2b_classes.hpp: -------------------------------------------------------------------------------- 1 | #pragma omp begin declare target 2 | class XOR1 3 | { 4 | int a; 5 | public: 6 | XOR1(int arg): a(arg) {}; 7 | int foo(); 8 | }; 9 | #pragma omp end declare target 10 | -------------------------------------------------------------------------------- /devices/sources/declare_target.2b_functions.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: declare_target.2b_functions 3 | * @@type: C++ 4 | * @@operation: compile 5 | * @@expect: success 6 | * @@version: omp_5.1 7 | * @@depend: declare_target.2b_classes.hpp 8 | */ 9 | #include "declare_target.2b_classes.hpp" 10 | int XOR1::foo() { return a^0x01;} 11 | -------------------------------------------------------------------------------- /devices/sources/declare_target.2b_main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: declare_target.2b_main 3 | * @@type: C++ 4 | * @@operation: run 5 | * @@expect: success 6 | * @@version: omp_5.1 7 | * @@depend: declare_target.2b_classes.hpp 8 | */ 9 | #include 10 | using namespace std; 11 | 12 | #include "declare_target.2b_classes.hpp" 13 | 14 | int main (){ 15 | 16 | XOR1 my_XOR1(3); 17 | int res1; 18 | 19 | #pragma omp target map(from: res1) 20 | res1=my_XOR1.foo(); 21 | 22 | cout << res1 << endl; // OUT1: 2 23 | } 24 | -------------------------------------------------------------------------------- /devices/sources/declare_target.2c.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: declare_target.2c 3 | * @@type: C++ 4 | * @@operation: compile 5 | * @@expect: ct-error 6 | * @@version: omp_5.1 7 | */ 8 | struct typeX 9 | { 10 | int a; 11 | }; 12 | class typeY 13 | { 14 | int a; 15 | public: 16 | int foo() { return a^0x01;} 17 | }; 18 | 19 | #pragma omp begin declare target 20 | struct typeX varX; // ok 21 | class typeY varY; // ok if varY.foo() not called on target device 22 | #pragma omp end declare target 23 | 24 | void foo() 25 | { 26 | #pragma omp target 27 | { 28 | varX.a = 100; // ok 29 | varY.foo(); // error foo() is not available on a target device 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /devices/sources/declare_target.3.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: declare_target.3 3 | * @@type: C 4 | * @@operation: compile 5 | * @@expect: success 6 | * @@version: omp_5.1 7 | */ 8 | #define N 1000 9 | 10 | #pragma omp begin declare target 11 | float p[N], v1[N], v2[N]; 12 | #pragma omp end declare target 13 | 14 | extern void init(float *, float *, int); 15 | extern void output(float *, int); 16 | 17 | void vec_mult() 18 | { 19 | int i; 20 | init(v1, v2, N); 21 | #pragma omp target update to(v1, v2) 22 | #pragma omp target 23 | #pragma omp parallel for 24 | for (i=0; i 9 | 10 | void foo(); 11 | void foo_onhost(); 12 | 13 | #pragma omp declare target enter(foo) device_type(nohost) 14 | 15 | #pragma omp declare variant(foo_onhost) match(device={kind(host)}) 16 | void foo(){ 17 | //device specific computation 18 | } 19 | 20 | void foo_onhost(){ 21 | printf("On host\n"); 22 | } 23 | 24 | int main(){ 25 | #pragma omp target teams 26 | { 27 | foo(); //calls foo() on target device or 28 | //foo_onhost() in case of host fallback 29 | } 30 | return 0; 31 | 32 | } 33 | -------------------------------------------------------------------------------- /devices/sources/declare_target.7.f90: -------------------------------------------------------------------------------- 1 | ! @@name: declare_target.7 2 | ! @@type: F-free 3 | ! @@operation: link 4 | ! @@expect: success 5 | ! @@version: omp_5.2 6 | module subs 7 | 8 | contains 9 | subroutine foo() 10 | !$omp declare target enter(foo) device_type(nohost) 11 | !$omp declare variant(foo_onhost) match(device={kind(host)}) 12 | ! device specific computation 13 | end subroutine 14 | 15 | subroutine foo_onhost() 16 | print *,' On host.' 17 | end subroutine 18 | 19 | end module 20 | 21 | program main 22 | 23 | use subs 24 | !$omp target 25 | call foo !calls foo() on device or 26 | !foo_onhost() in case of host fallback 27 | !$omp end target 28 | 29 | end program 30 | -------------------------------------------------------------------------------- /devices/sources/device.2.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: device.2 3 | * @@type: C 4 | * @@operation: compile 5 | * @@expect: success 6 | * @@version: omp_4.0 7 | */ 8 | #include 9 | extern void init(float *, float *, int); 10 | extern void output(float *, int); 11 | void vec_mult(float *p, float *v1, float *v2, int N) 12 | { 13 | int i; 14 | init(v1, v2, N); 15 | int ndev = omp_get_num_devices(); 16 | int do_offload = (ndev>0 && N>1000000); 17 | #pragma omp target if(do_offload) \ 18 | map(to: v1[0:N], v2[:N]) \ 19 | map(from: p[0:N]) 20 | #pragma omp parallel for if(N>1000) private(i) 21 | for (i=0; i0) .and. (N>1000000) 14 | !$omp target if(do_offload) map(to: v1, v2) map(from: p) 15 | !$omp parallel do if(N>1000) 16 | do i=1,N 17 | p(i) = v1(i) * v2(i) 18 | end do 19 | !$omp end target 20 | call output(p, N) 21 | end subroutine 22 | -------------------------------------------------------------------------------- /devices/sources/device.3.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: device.3 3 | * @@type: C 4 | * @@operation: compile 5 | * @@expect: success 6 | * @@version: omp_4.0 7 | */ 8 | #include 9 | #include 10 | void foo(void) 11 | { 12 | int default_device = omp_get_default_device(); 13 | printf("Default device = %d\n", default_device); 14 | omp_set_default_device(default_device+1); 15 | if (omp_get_default_device() != default_device+1) 16 | printf("Default device is still = %d\n", default_device); 17 | } 18 | -------------------------------------------------------------------------------- /devices/sources/device.3.f90: -------------------------------------------------------------------------------- 1 | ! @@name: device.3 2 | ! @@type: F-free 3 | ! @@operation: link 4 | ! @@expect: success 5 | ! @@version: omp_4.0 6 | program foo 7 | use omp_lib, ONLY : omp_get_default_device, omp_set_default_device 8 | integer :: old_default_device, new_default_device 9 | old_default_device = omp_get_default_device() 10 | print*, "Default device = ", old_default_device 11 | new_default_device = old_default_device + 1 12 | call omp_set_default_device(new_default_device) 13 | if (omp_get_default_device() == old_default_device) & 14 | print*,"Default device is STILL = ", old_default_device 15 | end program 16 | -------------------------------------------------------------------------------- /devices/sources/target.1.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: target.1 3 | * @@type: C 4 | * @@operation: compile 5 | * @@expect: success 6 | * @@version: omp_4.0 7 | */ 8 | extern void init(float*, float*, int); 9 | extern void output(float*, int); 10 | void vec_mult(int N) 11 | { 12 | int i; 13 | float p[N], v1[N], v2[N]; 14 | init(v1, v2, N); 15 | #pragma omp target 16 | #pragma omp parallel for private(i) 17 | for (i=0; iTHRESHOLD1) map(to: v1[0:N], v2[:N])\ 21 | map(from: p[0:N]) 22 | #pragma omp parallel for if(N>THRESHOLD2) 23 | for (i=0; iTHRESHHOLD1) map(to: v1, v2 ) map(from: p) 18 | !$omp parallel do if(N>THRESHOLD2) 19 | do i=1,N 20 | p(i) = v1(i) * v2(i) 21 | end do 22 | !$omp end target 23 | 24 | call output(p, N) 25 | end subroutine 26 | -------------------------------------------------------------------------------- /devices/sources/target.6.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: target.6 3 | * @@type: C 4 | * @@operation: compile 5 | * @@expect: success 6 | * @@version: omp_4.5 7 | */ 8 | #define THRESHOLD1 1000000 9 | #define THRESHOLD2 1000 10 | 11 | extern void init(float*, float*, int); 12 | extern void output(float*, int); 13 | 14 | void vec_mult(float *p, float *v1, float *v2, int N) 15 | { 16 | int i; 17 | 18 | init(v1, v2, N); 19 | 20 | #pragma omp target parallel for \ 21 | if(target: N>THRESHOLD1) if(parallel: N>THRESHOLD2) \ 22 | map(to: v1[0:N], v2[:N]) map(from: p[0:N]) 23 | for (i=0; iTHRESHHOLD1) if(parallel: N>THRESHOLD2) & 19 | !$omp& map(to: v1, v2 ) map(from: p) 20 | do i=1,N 21 | p(i) = v1(i) * v2(i) 22 | end do 23 | !$omp end target parallel do 24 | 25 | call output(p, N) 26 | end subroutine 27 | -------------------------------------------------------------------------------- /devices/sources/target_data.1.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: target_data.1 3 | * @@type: C 4 | * @@operation: compile 5 | * @@expect: success 6 | * @@version: omp_4.0 7 | */ 8 | extern void init(float*, float*, int); 9 | extern void output(float*, int); 10 | void vec_mult(float *p, float *v1, float *v2, int N) 11 | { 12 | int i; 13 | init(v1, v2, N); 14 | #pragma omp target data map(to: v1[0:N], v2[:N]) map(from: p[0:N]) 15 | { 16 | #pragma omp target 17 | #pragma omp parallel for 18 | for (i=0; iTHRESHOLD) map(to: v1[:N], v2[:N]) 18 | #pragma omp parallel for 19 | for (i=0; iTHRESHOLD) map(to: v1, v2) 16 | !$omp parallel do 17 | do i=1,N 18 | p(i) = v1(i) * v2(i) 19 | end do 20 | !$omp end target 21 | !$omp end target data 22 | call output(p, N) !*** UNDEFINED behavior if N<=THRESHOLD 23 | end subroutine 24 | -------------------------------------------------------------------------------- /devices/sources/target_mapper.1.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: target_mapper.1 3 | * @@type: C 4 | * @@operation: run 5 | * @@expect: success 6 | * @@version: omp_5.0 7 | */ 8 | #include 9 | #include 10 | #define N 100 11 | 12 | typedef struct myvec{ 13 | size_t len; 14 | double *data; 15 | } myvec_t; 16 | 17 | #pragma omp declare mapper(myvec_t v) \ 18 | map(v, v.data[0:v.len]) 19 | void init(myvec_t *s); 20 | 21 | int main(){ 22 | myvec_t s; 23 | 24 | s.data = (double *)calloc(N,sizeof(double)); 25 | s.len = N; 26 | 27 | #pragma omp target 28 | init(&s); 29 | 30 | printf("s.data[%d]=%lf\n",N-1,s.data[N-1]); //s.data[99]=99.000000 31 | } 32 | 33 | void init(myvec_t *s) 34 | { for(size_t i=0; ilen; i++) s->data[i]=i; } 35 | -------------------------------------------------------------------------------- /devices/sources/target_unstructured_data.1.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: target_unstructured_data.1 3 | * @@type: C 4 | * @@operation: compile 5 | * @@expect: success 6 | * @@version: omp_4.5 7 | */ 8 | #include 9 | typedef struct { 10 | double *A; 11 | int N; 12 | } Matrix; 13 | 14 | void init_matrix(Matrix *mat, int n) 15 | { 16 | mat->A = (double *)malloc(n*sizeof(double)); 17 | mat->N = n; 18 | #pragma omp target enter data map(alloc:mat->A[:n]) 19 | } 20 | 21 | void free_matrix(Matrix *mat) 22 | { 23 | #pragma omp target exit data map(delete:mat->A[:mat->N]) 24 | mat->N = 0; 25 | free(mat->A); 26 | mat->A = NULL; 27 | } 28 | -------------------------------------------------------------------------------- /devices/sources/target_unstructured_data.1.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: target_unstructured_data.1 3 | * @@type: C++ 4 | * @@operation: compile 5 | * @@expect: success 6 | * @@version: omp_4.5 7 | */ 8 | class Matrix 9 | { 10 | 11 | Matrix(int n) { 12 | len = n; 13 | v = new double[len]; 14 | #pragma omp target enter data map(alloc:v[0:len]) 15 | } 16 | 17 | ~Matrix() { 18 | // NOTE: delete map type should be used, since the corresponding 19 | // host data will cease to exist after the destructor is called. 20 | 21 | #pragma omp target exit data map(delete:v[0:len]) 22 | delete[] v; 23 | } 24 | 25 | private: 26 | double* v; 27 | int len; 28 | 29 | }; 30 | -------------------------------------------------------------------------------- /devices/sources/target_unstructured_data.1.f90: -------------------------------------------------------------------------------- 1 | ! @@name: target_unstructured_data.1 2 | ! @@type: F-free 3 | ! @@operation: compile 4 | ! @@expect: success 5 | ! @@version: omp_4.5 6 | module example 7 | real(8), allocatable :: A(:) 8 | 9 | contains 10 | subroutine initialize(N) 11 | integer :: N 12 | 13 | allocate(A(N)) 14 | !$omp target enter data map(alloc:A) 15 | 16 | end subroutine initialize 17 | 18 | subroutine finalize() 19 | 20 | !$omp target exit data map(delete:A) 21 | deallocate(A) 22 | 23 | end subroutine finalize 24 | end module example 25 | -------------------------------------------------------------------------------- /devices/sources/teams.3.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: teams.3 3 | * @@type: C 4 | * @@operation: compile 5 | * @@expect: success 6 | * @@version: omp_4.5 7 | */ 8 | float dotprod(float B[], float C[], int N) 9 | { 10 | float sum = 0; 11 | int i; 12 | #pragma omp target teams map(to: B[0:N], C[0:N]) \ 13 | defaultmap(tofrom:scalar) reduction(+:sum) 14 | #pragma omp distribute parallel for reduction(+:sum) 15 | for (i=0; i 9 | #include 10 | 11 | int x; 12 | #pragma omp declare target local(x) 13 | 14 | int main() { 15 | x = 128; 16 | #pragma omp target 17 | x = 256; 18 | 19 | #pragma omp target 20 | #pragma omp teams num_teams(x) // Undefined behavior due to value of "x" 21 | if (omp_get_team_num() == 0){ 22 | printf("%d\n", omp_get_num_teams()); 23 | } 24 | 25 | return 0; 26 | } 27 | 28 | -------------------------------------------------------------------------------- /devices/sources/teams.7.f90: -------------------------------------------------------------------------------- 1 | ! @@name: teams.7 2 | ! @@type: F-free 3 | ! @@operation: run 4 | ! @@expect: success 5 | ! @@version: omp_6.0 6 | PROGRAM main 7 | USE omp_lib 8 | INTEGER :: x 9 | !$OMP DECLARE TARGET LOCAL(x) 10 | 11 | x = 128 12 | 13 | !$OMP TARGET 14 | x = 256 15 | !$OMP END TARGET 16 | 17 | !$OMP TARGET 18 | !$OMP TEAMS NUM_TEAMS(x) ! Undefined behavior due to value of 'x' 19 | IF (omp_get_team_num() == 0) THEN 20 | PRINT *, omp_get_num_teams() 21 | END IF 22 | !$OMP END TEAMS 23 | !$OMP END TARGET 24 | 25 | END PROGRAM main 26 | -------------------------------------------------------------------------------- /figs/proc_bind_fig.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenMP/Examples/415024c36902acc179108369ff56faf86ec468e2/figs/proc_bind_fig.pdf -------------------------------------------------------------------------------- /figs/proc_bind_fig.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenMP/Examples/415024c36902acc179108369ff56faf86ec468e2/figs/proc_bind_fig.png -------------------------------------------------------------------------------- /figs/tile-2d_tiling.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenMP/Examples/415024c36902acc179108369ff56faf86ec468e2/figs/tile-2d_tiling.pdf -------------------------------------------------------------------------------- /figs/tile-Example_tile2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenMP/Examples/415024c36902acc179108369ff56faf86ec468e2/figs/tile-Example_tile2.pdf -------------------------------------------------------------------------------- /latexdiff.cfg: -------------------------------------------------------------------------------- 1 | PICTUREENV=(?:picture|DIFnomarkup)[\w\d*@]* 2 | VERBATIMLINEENV=(?:boxedcode|omptCallback|omptRecord|omptInquiry|omptEnum|omptOther|ompcPragma|ompfPragma|ompfSyntax|ompfFunction|ompfSubroutine|ompcEnum|ompcFunction|ompfEnum|ompEnv|ompSyntax|indentedcodelist|codepar) 3 | COUNTERCMD=subsubsubsection 4 | CUSTOMDIFCMD=(?:binding|comments|constraints|crossreferences|descr|argdesc|effect|format|restrictions|summary|syntax|events|tools|record|glossaryterm) 5 | FLOATENV=(?:note|(?:c|cpp|ccpp|c90|c99|fortran)specific) 6 | -------------------------------------------------------------------------------- /loop_transformations/sources/apply_nested.1.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: apply_nested.1 3 | * @@type: C 4 | * @@operation: compile 5 | * @@expect: success 6 | * @@version: omp_6.0 7 | */ 8 | void nested_apply(double A[100]) 9 | { 10 | #pragma omp tile sizes(10) \ 11 | apply(intratile: unroll partial(2) apply(reverse)) 12 | for (int i = 0; i < 100; ++i) 13 | A[i] = A[i] + 1; 14 | } 15 | -------------------------------------------------------------------------------- /loop_transformations/sources/apply_nested.1.f90: -------------------------------------------------------------------------------- 1 | ! @@name: apply_nested.1 2 | ! @@type: F-free 3 | ! @@operation: compile 4 | ! @@expect: success 5 | ! @@version: omp_6.0 6 | subroutine nested_apply(A) 7 | implicit none 8 | double precision :: A(0:99) 9 | integer :: i 10 | 11 | !$omp tile sizes(10) apply(intratile: unroll partial(2) apply(reverse)) 12 | do i = 0, 99 13 | A(i) = A(i) + 1 14 | enddo 15 | end subroutine 16 | -------------------------------------------------------------------------------- /loop_transformations/sources/apply_span.1.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: apply_span.1 3 | * @@type: C 4 | * @@operation: compile 5 | * @@expect: success 6 | * @@version: omp_6.0 7 | */ 8 | void span_apply(double A[128][128]) 9 | { 10 | #pragma omp for collapse(2) 11 | #pragma omp tile sizes(16,16) \ 12 | apply(grid: interchange,reverse) 13 | for (int i = 0; i < 128; ++i) 14 | for (int j = 0; j < 128; ++j) 15 | A[i][j] = A[i][j] + 1; 16 | } 17 | -------------------------------------------------------------------------------- /loop_transformations/sources/apply_span.1.f90: -------------------------------------------------------------------------------- 1 | ! @@name: apply_span.1 2 | ! @@type: F-free 3 | ! @@operation: compile 4 | ! @@expect: success 5 | ! @@version: omp_6.0 6 | subroutine span_apply( A ) 7 | implicit none 8 | double precision :: A(0:127,0:127) 9 | integer :: i , j 10 | 11 | !$omp for collapse(2) 12 | !$omp tile sizes(16,16) apply(grid: interchange,reverse) 13 | do i = 0, 127 14 | do j = 0, 127 15 | A(j,i) = A(j,i) + 1 16 | enddo; enddo 17 | 18 | end subroutine 19 | -------------------------------------------------------------------------------- /loop_transformations/sources/apply_syntax.1.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: apply_syntax.1 3 | * @@type: C 4 | * @@operation: compile 5 | * @@expect: success 6 | * @@version: omp_6.0 7 | */ 8 | void construct_unroll(double A[100]) 9 | { 10 | #pragma omp unroll 11 | #pragma omp tile sizes(4) 12 | for (int i = 0; i < 100; ++i) 13 | A[i] = A[i] + 1; 14 | } 15 | 16 | void apply_unroll(double A[100]) 17 | { 18 | #pragma omp tile sizes(4) apply(grid: unroll) 19 | for (int i = 0; i < 100; ++i) 20 | A[i] = A[i] + 1; 21 | } 22 | -------------------------------------------------------------------------------- /loop_transformations/sources/apply_syntax.1.f90: -------------------------------------------------------------------------------- 1 | ! @@name: apply_syntax.1 2 | ! @@type: F-free 3 | ! @@operation: compile 4 | ! @@expect: success 5 | ! @@version: omp_6.0 6 | subroutine construct_unroll(A) 7 | implicit none 8 | integer :: i 9 | double precision :: A(0:99) 10 | 11 | !$omp unroll 12 | !$omp tile sizes(4) 13 | do i = 0, 99 14 | A(i) = A(i) + 1 15 | end do 16 | end subroutine 17 | 18 | subroutine apply_unroll(A) 19 | implicit none 20 | integer :: i 21 | double precision :: A(0:99) 22 | 23 | !$omp tile sizes(4) apply(grid: unroll) 24 | do i = 0, 99 25 | A(i) = A(i) + 1 26 | end do 27 | end subroutine 28 | -------------------------------------------------------------------------------- /loop_transformations/sources/apply_syntax.2.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: apply_syntax.2 3 | * @@type: C 4 | * @@operation: compile 5 | * @@expect: success 6 | * @@version: omp_6.0 7 | */ 8 | void apply_assoc(double A[100][100][3]) 9 | { 10 | #pragma omp tile sizes(4,4) \ 11 | apply( grid: interchange,nothing) \ 12 | apply(intratile: nothing,interchange) 13 | for (int i = 0; i < 100; ++i) 14 | for (int j = 0; j < 100; ++j) 15 | 16 | // k loop not associated with tile, but with interchange 17 | for (int k = 0; k < 3; ++k) 18 | A[i][j][k] = A[i][j][k] + 1; 19 | } 20 | -------------------------------------------------------------------------------- /loop_transformations/sources/apply_syntax.2.f90: -------------------------------------------------------------------------------- 1 | ! @@name: apply_syntax.2 2 | ! @@type: F-free 3 | ! @@operation: compile 4 | ! @@expect: success 5 | ! @@version: omp_6.0 6 | subroutine apply_assoc(A) 7 | implicit none 8 | double precision :: A(0:2, 0:99, 0:99) 9 | integer :: k, j, i 10 | 11 | !$omp tile sizes(4,4) & 12 | !$omp& apply( grid: interchange, nothing) & 13 | !$omp& apply(intratile: nothing, interchange) 14 | do i = 0, 99 15 | do j = 0, 99 16 | 17 | do k = 0, 2 !! k loop not associated with tile, but w. interchange 18 | A(k,j,i) = A(k,j,i) + 1 19 | enddo 20 | enddo; enddo 21 | end subroutine 22 | -------------------------------------------------------------------------------- /loop_transformations/sources/apply_syntax.3.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: apply_syntax.3 3 | * @@type: C 4 | * @@operation: compile 5 | * @@expect: success 6 | * @@version: omp_6.0 7 | */ 8 | void apply_complexarg(double A[100*100]) 9 | { 10 | #pragma omp tile sizes(4,5) \ 11 | apply(grid(1): reverse) \ 12 | apply(intratile(2): unroll) 13 | for (int i = 0; i < 100; ++i) 14 | for (int j = 0; j < 100; ++j) 15 | A[i*100+j] += 1; 16 | } 17 | -------------------------------------------------------------------------------- /loop_transformations/sources/apply_syntax.3.f90: -------------------------------------------------------------------------------- 1 | ! @@name: apply_syntax.3 2 | ! @@type: F-free 3 | ! @@operation: compile 4 | ! @@expect: success 5 | ! @@version: omp_6.0 6 | subroutine apply_complexarg(A) 7 | implicit none 8 | double precision :: A(100,100) 9 | integer :: i, j 10 | 11 | !$omp tile sizes(4,5) & 12 | !$omp& apply(grid(1): reverse) & 13 | !$omp& apply(intratile(2): unroll) 14 | do i = 1, 100 15 | do j = 1, 100 16 | A(j,i) = A(j,i) + 1 17 | end do 18 | end do 19 | end subroutine 20 | -------------------------------------------------------------------------------- /loop_transformations/sources/apply_syntax_equivalent.1.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: apply_syntax_equivalent.1 3 | * @@type: C 4 | * @@operation: compile 5 | * @@expect: success 6 | * @@version: omp_5.1 7 | */ 8 | void equivalent(double A[100]) 9 | { 10 | #pragma omp unroll 11 | for (int i1 = 0; i1 < 25; ++i1) 12 | for (int i2 = 0; i2 < 4; ++i2) { 13 | int i = i1 * 4 + i2; 14 | A[i] = A[i] + 1; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /loop_transformations/sources/apply_syntax_equivalent.1.f90: -------------------------------------------------------------------------------- 1 | ! @@name: apply_syntax_equivalent.1 2 | ! @@type: F-free 3 | ! @@operation: compile 4 | ! @@expect: success 5 | ! @@version: omp_5.1 6 | subroutine equivalent(A) 7 | implicit none 8 | double precision :: A(0:99) 9 | integer :: i1,i2, i 10 | 11 | !$omp unroll 12 | do i1=0,24 13 | do i2=0, 3 14 | i = i1 * 4 + i2 15 | A(i) = A(i) + 1 16 | enddo; enddo 17 | 18 | end subroutine 19 | -------------------------------------------------------------------------------- /loop_transformations/sources/apply_syntax_equivalent.2.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: apply_syntax_equivalent.2 3 | * @@type: C 4 | * @@operation: compile 5 | * @@expect: success 6 | * @@version: omp_6.0 7 | */ 8 | void equivalent(double A[100][100][3]) 9 | { 10 | #pragma omp interchange 11 | for (int i1 = 0; i1 < 25; ++i1) 12 | #pragma omp nothing 13 | for (int j1 = 0; j1 < 25; ++j1) 14 | 15 | #pragma omp nothing 16 | for (int i2 = 0; i2 < 4; ++i2) 17 | #pragma omp interchange 18 | for (int j2 = 0; j2 < 4; ++j2) 19 | 20 | for (int k = 0; k < 3; ++k) { 21 | int i = i1 * 4 + i2; 22 | int j = j1 * 4 + j2; 23 | A[i][j][k] = A[i][j][k] + 1; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /loop_transformations/sources/tile.1.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: tile.1 3 | * @@type: C 4 | * @@operation: compile 5 | * @@expect: success 6 | * @@version: omp_5.1 7 | */ 8 | void func1(int A[100][128]) 9 | { 10 | #pragma omp parallel for 11 | #pragma omp tile sizes(5,16) 12 | for (int i = 0; i < 100; ++i) 13 | for (int j = 0; j < 128; ++j) 14 | A[i][j] = i*1000 + j; 15 | } 16 | 17 | void func2(int A[100][128]) 18 | { 19 | #pragma omp parallel for 20 | for (int i1 = 0; i1 < 100; i1+=5) 21 | for (int j1 = 0; j1 < 128; j1+=16) 22 | for (int i2 = i1; i2 < i1+5; ++i2) 23 | for (int j2 = j1; j2 < j1+16; ++j2) 24 | A[i2][j2] = i2*1000 + j2; 25 | } 26 | -------------------------------------------------------------------------------- /loop_transformations/sources/tile.1.f90: -------------------------------------------------------------------------------- 1 | ! @@name: tile.1 2 | ! @@type: F-free 3 | ! @@operation: compile 4 | ! @@expect: success 5 | ! @@version: omp_5.1 6 | subroutine func1(A) 7 | integer :: A(128,100) 8 | integer :: i, j 9 | !$omp parallel do 10 | !$omp tile sizes(5,16) 11 | do i = 1, 100 12 | do j = 1, 128 13 | A(j,i) = j*1000 + i 14 | end do; end do 15 | end subroutine 16 | 17 | subroutine func2(A) 18 | integer :: A(128,100) 19 | integer :: i1, j1, i2, j2 20 | !$omp parallel do 21 | do i1 = 1, 100,5 22 | do j1 = 1, 128,16 23 | do i2 = i1, i1+( 5-1) 24 | do j2 = j1, j1+(16-1) 25 | A(j2,i2) = j2*1000 + i2 26 | end do; end do 27 | end do; end do 28 | end subroutine 29 | -------------------------------------------------------------------------------- /loop_transformations/sources/unroll.1.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: unroll.1 3 | * @@type: C 4 | * @@operation: compile 5 | * @@expect: success 6 | * @@version: omp_5.1 7 | */ 8 | void unroll(double A[], int n) 9 | { 10 | #pragma omp unroll 11 | for (int i = 0; i < n; ++i) 12 | A[i] = 0; 13 | } 14 | 15 | void unroll_full(double A[]) 16 | { 17 | #pragma omp unroll full 18 | for (int i = 0; i < 4; ++i) 19 | A[i] = 0; 20 | } 21 | 22 | void unroll_full_equivalent(double A[]) 23 | { 24 | A[0] = 0; 25 | A[1] = 0; 26 | A[2] = 0; 27 | A[3] = 0; 28 | } 29 | -------------------------------------------------------------------------------- /loop_transformations/sources/unroll.1.f90: -------------------------------------------------------------------------------- 1 | ! @@name: unroll.1 2 | ! @@type: F-free 3 | ! @@operation: compile 4 | ! @@expect: success 5 | ! @@version: omp_5.1 6 | subroutine unroll(A, n) 7 | implicit none 8 | integer :: i,n 9 | double precision :: A(n) 10 | 11 | !$omp unroll 12 | do i = 1,n 13 | A(i) = 0.0d0 14 | end do 15 | end subroutine 16 | 17 | subroutine unroll_full(A) 18 | implicit none 19 | integer :: i 20 | double precision :: A(*) 21 | 22 | !$omp unroll full 23 | do i = 1,4 24 | A(i) = 0.0d0 25 | end do 26 | end subroutine 27 | 28 | subroutine unroll_full_equivalent(A) 29 | implicit none 30 | double precision :: A(*) 31 | 32 | A(1) = 0.0d0 33 | A(2) = 0.0d0 34 | A(3) = 0.0d0 35 | A(4) = 0.0d0 36 | end subroutine 37 | -------------------------------------------------------------------------------- /loop_transformations/sources/unroll.3.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: unroll.3 3 | * @@type: C 4 | * @@operation: compile 5 | * @@expect: success 6 | * @@version: omp_5.1 7 | */ 8 | void unroll3_partial(double A[]) 9 | { 10 | #pragma omp unroll partial(4) 11 | for (int i = 0; i < 128; ++i) 12 | A[i] = 0; 13 | } 14 | 15 | void unroll3_partial_equivalent(double A[]) 16 | { 17 | for (int i_iv = 0; i_iv < 32; ++i_iv) { 18 | A[i_iv * 4 + 0] = 0; 19 | A[i_iv * 4 + 1] = 0; 20 | A[i_iv * 4 + 2] = 0; 21 | A[i_iv * 4 + 3] = 0; 22 | } 23 | } 24 | 25 | void unroll3_partial_nofactor(double A[]) 26 | { 27 | #pragma omp unroll partial 28 | for (int i = 0; i < 128; ++i) 29 | A[i] = 0; 30 | } 31 | -------------------------------------------------------------------------------- /memory_model/sources/fort_race.1.f90: -------------------------------------------------------------------------------- 1 | ! @@name: fort_race.1 2 | ! @@type: F-free 3 | ! @@operation: compile 4 | ! @@expect: unspecified 5 | ! @@version: pre_omp_3.0 6 | SUBROUTINE SHARED_RACE 7 | 8 | INCLUDE "omp_lib.h" ! or USE OMP_LIB 9 | 10 | REAL A(20) 11 | INTEGER MYTHREAD 12 | 13 | !$OMP PARALLEL SHARED(A) PRIVATE(MYTHREAD) 14 | 15 | MYTHREAD = OMP_GET_THREAD_NUM() 16 | IF (MYTHREAD .EQ. 0) THEN 17 | CALL SUB(A(1:10)) ! compiler may introduce writes to A(6:10) 18 | ELSE 19 | A(6:10) = 12 20 | ENDIF 21 | 22 | !$OMP END PARALLEL 23 | 24 | END SUBROUTINE SHARED_RACE 25 | 26 | SUBROUTINE SUB(X) 27 | REAL X(*) 28 | X(1:5) = 4 29 | END SUBROUTINE SUB 30 | -------------------------------------------------------------------------------- /openmp-index.ist: -------------------------------------------------------------------------------- 1 | headings_flag 1 2 | heading_prefix "{\\bfseries " 3 | heading_suffix "}\\nopagebreak\n" 4 | delim_0 ",\\penalty1000\\ " 5 | -------------------------------------------------------------------------------- /openmp-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenMP/Examples/415024c36902acc179108369ff56faf86ec468e2/openmp-logo.png -------------------------------------------------------------------------------- /parallel_execution/linear_in_loop.tex: -------------------------------------------------------------------------------- 1 | \section{\kcode{linear} Clause in Loop Constructs} 2 | \label{sec:linear_in_loop} 3 | \index{clauses!linear@\kcode{linear}} 4 | \index{linear clause@\kcode{linear} clause} 5 | 6 | The following example shows the use of the \kcode{linear} clause in a worksharing-loop 7 | construct to allow the proper parallelization of a loop that contains 8 | an induction variable (\ucode{j}). At the end of the execution of 9 | the worksharing-loop construct, the original variable \ucode{j} is updated with 10 | the value \ucode{N/2} from the last iteration of the loop. 11 | 12 | \cexample[4.5]{linear_in_loop}{1} 13 | 14 | \ffreeexample[4.5]{linear_in_loop}{1} 15 | 16 | -------------------------------------------------------------------------------- /parallel_execution/nthrs_nesting.tex: -------------------------------------------------------------------------------- 1 | %\pagebreak 2 | \section{Controlling the Number of Threads on Multiple Nesting Levels} 3 | \label{sec:nthrs_nesting} 4 | \index{environment variables!OMP_NUM_THREADS@\kcode{OMP_NUM_THREADS}} 5 | \index{OMP_NUM_THREADS@\kcode{OMP_NUM_THREADS}} 6 | 7 | The following examples demonstrate how to use the \kcode{OMP_NUM_THREADS} environment 8 | variable to control the number of threads on multiple nesting levels: 9 | 10 | \cexample{nthrs_nesting}{1}[1] 11 | 12 | \fexample{nthrs_nesting}{1}[1] 13 | 14 | 15 | -------------------------------------------------------------------------------- /parallel_execution/parallel.tex: -------------------------------------------------------------------------------- 1 | \pagebreak 2 | \section{\kcode{parallel} Construct} 3 | \label{sec:parallel} 4 | \index{constructs!parallel@\kcode{parallel}} 5 | \index{parallel construct@\kcode{parallel} construct} 6 | 7 | The \kcode{parallel} construct can be used in coarse-grain parallel programs. 8 | In the following example, each thread in the \kcode{parallel} region decides what 9 | part of the global array \ucode{x} to work on, based on the thread number: 10 | 11 | \cexample{parallel}{1} 12 | 13 | \fexample{parallel}{1} 14 | 15 | -------------------------------------------------------------------------------- /parallel_execution/pra_iterator.tex: -------------------------------------------------------------------------------- 1 | %\pagebreak 2 | \begin{cppspecific}[4ex] 3 | \section{Parallel Random Access Iterator Loop} 4 | \label{sec:pra_iterator} 5 | \index{random access iterator, C++} 6 | 7 | The following example shows a parallel random access iterator loop. 8 | 9 | \cppnexample[3.0]{pra_iterator}{1} 10 | \end{cppspecific} 11 | 12 | 13 | -------------------------------------------------------------------------------- /parallel_execution/psections.tex: -------------------------------------------------------------------------------- 1 | \pagebreak 2 | \section{\kcode{parallel sections} Construct} 3 | \label{sec:psections} 4 | \index{combined constructs!parallel sections@\kcode{parallel sections}} 5 | \index{parallel sections construct@\kcode{parallel sections} construct} 6 | 7 | In the following example routines \ucode{XAXIS}, \ucode{YAXIS}, and \ucode{ZAXIS} can 8 | be executed concurrently. The first \kcode{section} directive is optional. Note 9 | that all \kcode{section} directives need to appear in the 10 | \kcode{parallel sections} construct. 11 | 12 | \cexample{psections}{1} 13 | 14 | \fexample{psections}{1} 15 | 16 | -------------------------------------------------------------------------------- /parallel_execution/sources/collapse.1.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: collapse.1 3 | * @@type: C 4 | * @@operation: compile 5 | * @@expect: success 6 | * @@version: omp_3.0 7 | */ 8 | void bar(float *a, int i, int j, int k); 9 | 10 | int kl, ku, ks, jl, ju, js, il, iu,is; 11 | 12 | void sub(float *a) 13 | { 14 | int i, j, k; 15 | 16 | #pragma omp for collapse(2) private(i, k, j) 17 | for (k=kl; k<=ku; k+=ks) 18 | for (j=jl; j<=ju; j+=js) 19 | for (i=il; i<=iu; i+=is) 20 | bar(a,i,j,k); 21 | } 22 | -------------------------------------------------------------------------------- /parallel_execution/sources/collapse.1.f: -------------------------------------------------------------------------------- 1 | ! @@name: collapse.1 2 | ! @@type: F-fixed 3 | ! @@operation: compile 4 | ! @@expect: success 5 | ! @@version: omp_3.0 6 | subroutine sub(a) 7 | 8 | real a(*) 9 | integer kl, ku, ks, jl, ju, js, il, iu, is 10 | common /csub/ kl, ku, ks, jl, ju, js, il, iu, is 11 | integer i, j, k 12 | 13 | !$omp do collapse(2) private(i,j,k) 14 | do k = kl, ku, ks 15 | do j = jl, ju, js 16 | do i = il, iu, is 17 | call bar(a,i,j,k) 18 | enddo 19 | enddo 20 | enddo 21 | !$omp end do 22 | 23 | end subroutine 24 | -------------------------------------------------------------------------------- /parallel_execution/sources/collapse.2.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: collapse.2 3 | * @@type: C 4 | * @@operation: run 5 | * @@expect: success 6 | * @@version: omp_3.0 7 | */ 8 | #include 9 | int main() 10 | { 11 | int j, k, jlast, klast; 12 | #pragma omp parallel 13 | { 14 | #pragma omp for collapse(2) lastprivate(jlast, klast) 15 | for (k=1; k<=2; k++) 16 | for (j=1; j<=3; j++) 17 | { 18 | jlast=j; 19 | klast=k; 20 | } 21 | #pragma omp single 22 | printf("%d %d\n", klast, jlast); //2 3 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /parallel_execution/sources/collapse.2.f: -------------------------------------------------------------------------------- 1 | ! @@name: collapse.2 2 | ! @@type: F-fixed 3 | ! @@operation: run 4 | ! @@expect: success 5 | ! @@version: omp_3.0 6 | program test 7 | !$omp parallel 8 | !$omp do private(j,k) collapse(2) lastprivate(jlast, klast) 9 | do k = 1,2 10 | do j = 1,3 11 | jlast=j 12 | klast=k 13 | enddo 14 | enddo 15 | !$omp end do 16 | !$omp single 17 | print *, klast, jlast !2, 3 18 | !$omp end single 19 | !$omp end parallel 20 | end program test 21 | -------------------------------------------------------------------------------- /parallel_execution/sources/collapse.3.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: collapse.3 3 | * @@type: C 4 | * @@operation: compile 5 | * @@expect: success 6 | * @@version: omp_3.0 7 | */ 8 | #include 9 | #include 10 | void work(int a, int j, int k); 11 | void sub() 12 | { 13 | int j, k, a = 5; 14 | #pragma omp parallel num_threads(2) 15 | { 16 | #pragma omp for collapse(2) ordered private(j,k) schedule(static,3) 17 | for (k=1; k<=3; k++) 18 | for (j=1; j<=2; j++) 19 | { 20 | #pragma omp ordered 21 | printf("%d %d %d\n", omp_get_thread_num(), k, j); 22 | /* end ordered */ 23 | work(a,j,k); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /parallel_execution/sources/collapse.3.f: -------------------------------------------------------------------------------- 1 | ! @@name: collapse.3 2 | ! @@type: F-fixed 3 | ! @@operation: compile 4 | ! @@expect: success 5 | ! @@version: omp_3.0 6 | program test 7 | include 'omp_lib.h' 8 | !$omp parallel num_threads(2) 9 | !$omp do collapse(2) ordered private(j,k) schedule(static,3) 10 | do k = 1,3 11 | do j = 1,2 12 | !$omp ordered 13 | print *, omp_get_thread_num(), k, j 14 | !$omp end ordered 15 | call work(a,j,k) 16 | enddo 17 | enddo 18 | !$omp end do 19 | !$omp end parallel 20 | end program test 21 | -------------------------------------------------------------------------------- /parallel_execution/sources/fort_do.1.f: -------------------------------------------------------------------------------- 1 | ! @@name: fort_do.1 2 | ! @@type: F-fixed 3 | ! @@operation: compile 4 | ! @@expect: success 5 | ! @@version: pre_omp_3.0 6 | SUBROUTINE WORK(I, J) 7 | INTEGER I,J 8 | END SUBROUTINE WORK 9 | 10 | SUBROUTINE DO_GOOD() 11 | INTEGER I, J 12 | REAL A(1000) 13 | 14 | DO 100 I = 1,10 15 | !$OMP DO 16 | DO 100 J = 1,10 17 | CALL WORK(I,J) 18 | 100 CONTINUE ! !$OMP ENDDO implied here 19 | 20 | !$OMP DO 21 | DO 200 J = 1,10 22 | 200 A(I) = I + 1 23 | !$OMP ENDDO 24 | 25 | !$OMP DO 26 | DO 300 I = 1,10 27 | DO 300 J = 1,10 28 | CALL WORK(I,J) 29 | 300 CONTINUE 30 | !$OMP ENDDO 31 | END SUBROUTINE DO_GOOD 32 | -------------------------------------------------------------------------------- /parallel_execution/sources/fort_do.2.f: -------------------------------------------------------------------------------- 1 | ! @@name: fort_do.2 2 | ! @@type: F-fixed 3 | ! @@operation: compile 4 | ! @@expect: ct-error 5 | ! @@version: pre_omp_3.0 6 | SUBROUTINE WORK(I, J) 7 | INTEGER I,J 8 | END SUBROUTINE WORK 9 | 10 | SUBROUTINE DO_WRONG 11 | INTEGER I, J 12 | 13 | DO 100 I = 1,10 14 | !$OMP DO 15 | DO 100 J = 1,10 16 | CALL WORK(I,J) 17 | 100 CONTINUE 18 | !$OMP ENDDO 19 | END SUBROUTINE DO_WRONG 20 | -------------------------------------------------------------------------------- /parallel_execution/sources/fpriv_sections.1.f90: -------------------------------------------------------------------------------- 1 | ! @@name: fpriv_sections.1 2 | ! @@type: F-free 3 | ! @@operation: run 4 | ! @@expect: success 5 | ! @@version: pre_omp_3.0 6 | program section 7 | use omp_lib 8 | integer :: section_count = 0 9 | integer, parameter :: NT = 4 10 | call omp_set_dynamic(.false.) 11 | call omp_set_num_threads(NT) 12 | !$omp parallel 13 | !$omp sections firstprivate ( section_count ) 14 | !$omp section 15 | section_count = section_count + 1 16 | ! may print the number one or two 17 | print *, 'section_count', section_count 18 | !$omp section 19 | section_count = section_count + 1 20 | ! may print the number one or two 21 | print *, 'section_count', section_count 22 | !$omp end sections 23 | !$omp end parallel 24 | end program section 25 | -------------------------------------------------------------------------------- /parallel_execution/sources/get_nthrs.1.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: get_nthrs.1 3 | * @@type: C 4 | * @@operation: compile 5 | * @@expect: rt-error 6 | * @@version: pre_omp_3.0 7 | */ 8 | #include 9 | void work(int i); 10 | 11 | void incorrect() { 12 | int np, i; 13 | 14 | np = omp_get_num_threads(); /* misplaced */ 15 | 16 | #pragma omp parallel for schedule(static) 17 | for (i=0; i < np; i++) 18 | work(i); 19 | } 20 | -------------------------------------------------------------------------------- /parallel_execution/sources/get_nthrs.1.f: -------------------------------------------------------------------------------- 1 | ! @@name: get_nthrs.1 2 | ! @@type: F-fixed 3 | ! @@operation: compile 4 | ! @@expect: rt-error 5 | ! @@version: pre_omp_3.0 6 | SUBROUTINE WORK(I) 7 | INTEGER I 8 | I = I + 1 9 | END SUBROUTINE WORK 10 | 11 | SUBROUTINE INCORRECT() 12 | INCLUDE "omp_lib.h" ! or USE OMP_LIB 13 | INTEGER I, NP 14 | 15 | NP = OMP_GET_NUM_THREADS() !misplaced: will return 1 16 | !$OMP PARALLEL DO SCHEDULE(STATIC) 17 | DO I = 0, NP-1 18 | CALL WORK(I) 19 | ENDDO 20 | !$OMP END PARALLEL DO 21 | END SUBROUTINE INCORRECT 22 | -------------------------------------------------------------------------------- /parallel_execution/sources/get_nthrs.2.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: get_nthrs.2 3 | * @@type: C 4 | * @@operation: compile 5 | * @@expect: success 6 | * @@version: pre_omp_3.0 7 | */ 8 | #include 9 | void work(int i); 10 | 11 | void correct() 12 | { 13 | int i; 14 | 15 | #pragma omp parallel private(i) 16 | { 17 | i = omp_get_thread_num(); 18 | work(i); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /parallel_execution/sources/get_nthrs.2.f: -------------------------------------------------------------------------------- 1 | ! @@name: get_nthrs.2 2 | ! @@type: F-fixed 3 | ! @@operation: compile 4 | ! @@expect: success 5 | ! @@version: pre_omp_3.0 6 | SUBROUTINE WORK(I) 7 | INTEGER I 8 | 9 | I = I + 1 10 | 11 | END SUBROUTINE WORK 12 | 13 | SUBROUTINE CORRECT() 14 | INCLUDE "omp_lib.h" ! or USE OMP_LIB 15 | INTEGER I 16 | 17 | !$OMP PARALLEL PRIVATE(I) 18 | I = OMP_GET_THREAD_NUM() 19 | CALL WORK(I) 20 | !$OMP END PARALLEL 21 | 22 | END SUBROUTINE CORRECT 23 | -------------------------------------------------------------------------------- /parallel_execution/sources/linear_in_loop.1.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: linear_in_loop.1 3 | * @@type: C 4 | * @@operation: run 5 | * @@expect: success 6 | * @@version: omp_4.5 7 | */ 8 | #include 9 | 10 | #define N 100 11 | int main(void) 12 | { 13 | float a[N], b[N/2]; 14 | int i, j; 15 | 16 | for ( i = 0; i < N; i++ ) 17 | a[i] = i + 1; 18 | 19 | j = 0; 20 | #pragma omp parallel 21 | #pragma omp for linear(j:1) 22 | for ( i = 0; i < N; i += 2 ) { 23 | b[j] = a[i] * 2.0f; 24 | j++; 25 | } 26 | 27 | printf( "%d %f %f\n", j, b[0], b[j-1] ); 28 | /* print out: 50 2.0 198.0 */ 29 | 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /parallel_execution/sources/linear_in_loop.1.f90: -------------------------------------------------------------------------------- 1 | ! @@name: linear_in_loop.1 2 | ! @@type: F-free 3 | ! @@operation: run 4 | ! @@expect: success 5 | ! @@version: omp_4.5 6 | program linear_loop 7 | implicit none 8 | integer, parameter :: N = 100 9 | real :: a(N), b(N/2) 10 | integer :: i, j 11 | 12 | do i = 1, N 13 | a(i) = i 14 | end do 15 | 16 | j = 0 17 | !$omp parallel 18 | !$omp do linear(j:1) 19 | do i = 1, N, 2 20 | j = j + 1 21 | b(j) = a(i) * 2.0 22 | end do 23 | !$omp end parallel 24 | 25 | print *, j, b(1), b(j) 26 | ! print out: 50 2.0 198.0 27 | 28 | end program 29 | -------------------------------------------------------------------------------- /parallel_execution/sources/loop.1.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: loop.1 3 | * @@type: C 4 | * @@operation: run 5 | * @@expect: success 6 | * @@version: omp_5.0 7 | */ 8 | #include 9 | #define N 100 10 | int main() 11 | { 12 | float x[N], y[N]; 13 | float a = 2.0; 14 | for(int i=0;i 9 | int main() 10 | { 11 | omp_set_dynamic(1); 12 | #pragma omp parallel num_threads(10) 13 | { 14 | /* do work here */ 15 | } 16 | return 0; 17 | } 18 | -------------------------------------------------------------------------------- /parallel_execution/sources/nthrs_dynamic.2.f: -------------------------------------------------------------------------------- 1 | ! @@name: nthrs_dynamic.2 2 | ! @@type: F-fixed 3 | ! @@operation: link 4 | ! @@expect: success 5 | ! @@version: pre_omp_3.0 6 | PROGRAM EXAMPLE 7 | INCLUDE "omp_lib.h" ! or USE OMP_LIB 8 | CALL OMP_SET_DYNAMIC(.TRUE.) 9 | !$OMP PARALLEL NUM_THREADS(10) 10 | ! do work here 11 | !$OMP END PARALLEL 12 | END PROGRAM EXAMPLE 13 | -------------------------------------------------------------------------------- /parallel_execution/sources/ploop.1.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: ploop.1 3 | * @@type: C 4 | * @@operation: compile 5 | * @@expect: success 6 | * @@version: pre_omp_3.0 7 | */ 8 | void simple(int n, float *a, float *b) 9 | { 10 | int i; 11 | 12 | #pragma omp parallel for 13 | for (i=1; i 9 | void iterator_example() 10 | { 11 | std::vector vec(23); 12 | std::vector::iterator it; 13 | #pragma omp parallel for default(none) shared(vec) 14 | for (it = vec.begin(); it < vec.end(); it++) 15 | { 16 | // do work with *it // 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /parallel_execution/sources/psections.1.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: psections.1 3 | * @@type: C 4 | * @@operation: compile 5 | * @@expect: success 6 | * @@version: pre_omp_3.0 7 | */ 8 | void XAXIS(); 9 | void YAXIS(); 10 | void ZAXIS(); 11 | 12 | void sect_example() 13 | { 14 | #pragma omp parallel sections 15 | { 16 | #pragma omp section 17 | XAXIS(); 18 | 19 | #pragma omp section 20 | YAXIS(); 21 | 22 | #pragma omp section 23 | ZAXIS(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /parallel_execution/sources/psections.1.f: -------------------------------------------------------------------------------- 1 | ! @@name: psections.1 2 | ! @@type: F-fixed 3 | ! @@operation: compile 4 | ! @@expect: success 5 | ! @@version: pre_omp_3.0 6 | SUBROUTINE SECT_EXAMPLE() 7 | !$OMP PARALLEL SECTIONS 8 | !$OMP SECTION 9 | CALL XAXIS() 10 | !$OMP SECTION 11 | CALL YAXIS() 12 | 13 | !$OMP SECTION 14 | CALL ZAXIS() 15 | 16 | !$OMP END PARALLEL SECTIONS 17 | END SUBROUTINE SECT_EXAMPLE 18 | -------------------------------------------------------------------------------- /parallel_execution/sources/set_dynamic_nthrs.1.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: set_dynamic_nthrs.1 3 | * @@type: C 4 | * @@operation: compile 5 | * @@expect: success 6 | * @@version: pre_omp_3.0 7 | */ 8 | #include 9 | #include 10 | 11 | void do_by_16(float *x, int iam, int ipoints) {} 12 | 13 | void dynthreads(float *x, int npoints) 14 | { 15 | int iam, ipoints; 16 | 17 | omp_set_dynamic(0); 18 | omp_set_num_threads(16); 19 | 20 | #pragma omp parallel shared(x, npoints) private(iam, ipoints) 21 | { 22 | if (omp_get_num_threads() != 16) 23 | abort(); 24 | 25 | iam = omp_get_thread_num(); 26 | ipoints = npoints/16; 27 | do_by_16(x, iam, ipoints); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /parallel_execution/sources/single.1.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: single.1 3 | * @@type: C 4 | * @@operation: link 5 | * @@expect: success 6 | * @@version: pre_omp_3.0 7 | */ 8 | #include 9 | 10 | void work1() {} 11 | void work2() {} 12 | 13 | int main() 14 | { 15 | #pragma omp parallel 16 | { 17 | #pragma omp single 18 | printf("Beginning work1.\n"); 19 | 20 | work1(); 21 | 22 | #pragma omp single 23 | printf("Finishing work1.\n"); 24 | 25 | #pragma omp single nowait 26 | printf("Finished work1 and beginning work2.\n"); 27 | 28 | work2(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /parallel_execution/sources/single.1.f: -------------------------------------------------------------------------------- 1 | ! @@name: single.1 2 | ! @@type: F-fixed 3 | ! @@operation: link 4 | ! @@expect: success 5 | ! @@version: pre_omp_3.0 6 | SUBROUTINE WORK1() 7 | END SUBROUTINE WORK1 8 | 9 | SUBROUTINE WORK2() 10 | END SUBROUTINE WORK2 11 | 12 | PROGRAM SINGLE_EXAMPLE 13 | !$OMP PARALLEL 14 | 15 | !$OMP SINGLE 16 | print *, "Beginning work1." 17 | !$OMP END SINGLE 18 | 19 | CALL WORK1() 20 | 21 | !$OMP SINGLE 22 | print *, "Finishing work1." 23 | !$OMP END SINGLE 24 | 25 | !$OMP SINGLE 26 | print *, "Finished work1 and beginning work2." 27 | !$OMP END SINGLE NOWAIT 28 | 29 | CALL WORK2() 30 | 31 | !$OMP END PARALLEL 32 | 33 | END PROGRAM SINGLE_EXAMPLE 34 | -------------------------------------------------------------------------------- /parallel_execution/sources/workshare.1.f: -------------------------------------------------------------------------------- 1 | ! @@name: workshare.1 2 | ! @@type: F-fixed 3 | ! @@operation: compile 4 | ! @@expect: success 5 | ! @@version: pre_omp_3.0 6 | SUBROUTINE WSHARE1(AA, BB, CC, DD, EE, FF, N) 7 | INTEGER N 8 | REAL AA(N,N), BB(N,N), CC(N,N), DD(N,N), EE(N,N), FF(N,N) 9 | 10 | !$OMP PARALLEL 11 | !$OMP WORKSHARE 12 | AA = BB 13 | CC = DD 14 | EE = FF 15 | !$OMP END WORKSHARE 16 | !$OMP END PARALLEL 17 | 18 | END SUBROUTINE WSHARE1 19 | -------------------------------------------------------------------------------- /parallel_execution/sources/workshare.2.f: -------------------------------------------------------------------------------- 1 | ! @@name: workshare.2 2 | ! @@type: F-fixed 3 | ! @@operation: compile 4 | ! @@expect: success 5 | ! @@version: pre_omp_3.0 6 | SUBROUTINE WSHARE2(AA, BB, CC, DD, EE, FF, N) 7 | INTEGER N 8 | REAL AA(N,N), BB(N,N), CC(N,N) 9 | REAL DD(N,N), EE(N,N), FF(N,N) 10 | 11 | !$OMP PARALLEL 12 | !$OMP WORKSHARE 13 | AA = BB 14 | CC = DD 15 | !$OMP END WORKSHARE NOWAIT 16 | !$OMP WORKSHARE 17 | EE = FF 18 | !$OMP END WORKSHARE 19 | !$OMP END PARALLEL 20 | END SUBROUTINE WSHARE2 21 | -------------------------------------------------------------------------------- /parallel_execution/sources/workshare.3.f: -------------------------------------------------------------------------------- 1 | ! @@name: workshare.3 2 | ! @@type: F-fixed 3 | ! @@operation: compile 4 | ! @@expect: success 5 | ! @@version: pre_omp_3.0 6 | SUBROUTINE WSHARE3(AA, BB, CC, DD, N) 7 | INTEGER N 8 | REAL AA(N,N), BB(N,N), CC(N,N), DD(N,N) 9 | REAL R 10 | R=0 11 | !$OMP PARALLEL 12 | !$OMP WORKSHARE 13 | AA = BB 14 | !$OMP ATOMIC UPDATE 15 | R = R + SUM(AA) 16 | CC = DD 17 | !$OMP END WORKSHARE 18 | !$OMP END PARALLEL 19 | END SUBROUTINE WSHARE3 20 | -------------------------------------------------------------------------------- /parallel_execution/sources/workshare.4.f: -------------------------------------------------------------------------------- 1 | ! @@name: workshare.4 2 | ! @@type: F-fixed 3 | ! @@operation: compile 4 | ! @@expect: success 5 | ! @@version: pre_omp_3.0 6 | SUBROUTINE WSHARE4(AA, BB, CC, DD, EE, FF, GG, HH, N) 7 | INTEGER N 8 | REAL AA(N,N), BB(N,N), CC(N,N) 9 | REAL DD(N,N), EE(N,N), FF(N,N) 10 | REAL GG(N,N), HH(N,N) 11 | 12 | !$OMP PARALLEL 13 | !$OMP WORKSHARE 14 | AA = BB 15 | CC = DD 16 | WHERE (EE .ne. 0) FF = 1 / EE 17 | GG = HH 18 | !$OMP END WORKSHARE 19 | !$OMP END PARALLEL 20 | 21 | END SUBROUTINE WSHARE4 22 | -------------------------------------------------------------------------------- /parallel_execution/sources/workshare.5.f: -------------------------------------------------------------------------------- 1 | ! @@name: workshare.5 2 | ! @@type: F-fixed 3 | ! @@operation: compile 4 | ! @@expect: success 5 | ! @@version: pre_omp_3.0 6 | SUBROUTINE WSHARE5(AA, BB, CC, DD, N) 7 | INTEGER N 8 | REAL AA(N,N), BB(N,N), CC(N,N), DD(N,N) 9 | 10 | INTEGER SHR 11 | 12 | !$OMP PARALLEL SHARED(SHR) 13 | !$OMP WORKSHARE 14 | AA = BB 15 | SHR = 1 16 | CC = DD * SHR 17 | !$OMP END WORKSHARE 18 | !$OMP END PARALLEL 19 | 20 | END SUBROUTINE WSHARE5 21 | -------------------------------------------------------------------------------- /parallel_execution/sources/workshare.6.f: -------------------------------------------------------------------------------- 1 | ! @@name: workshare.6 2 | ! @@type: F-fixed 3 | ! @@operation: compile 4 | ! @@expect: unspecified 5 | ! @@version: pre_omp_3.0 6 | SUBROUTINE WSHARE6_WRONG(AA, BB, CC, DD, N) 7 | INTEGER N 8 | REAL AA(N,N), BB(N,N), CC(N,N), DD(N,N) 9 | 10 | INTEGER PRI 11 | 12 | !$OMP PARALLEL PRIVATE(PRI) 13 | !$OMP WORKSHARE 14 | AA = BB 15 | PRI = 1 16 | CC = DD * PRI 17 | !$OMP END WORKSHARE 18 | !$OMP END PARALLEL 19 | 20 | END SUBROUTINE WSHARE6_WRONG 21 | -------------------------------------------------------------------------------- /parallel_execution/sources/workshare.7.f: -------------------------------------------------------------------------------- 1 | ! @@name: workshare.7 2 | ! @@type: F-fixed 3 | ! @@operation: compile 4 | ! @@expect: success 5 | ! @@version: pre_omp_3.0 6 | SUBROUTINE WSHARE7(AA, BB, CC, N) 7 | INTEGER N 8 | REAL AA(N), BB(N), CC(N) 9 | 10 | !$OMP PARALLEL 11 | !$OMP WORKSHARE 12 | AA(1:50) = BB(11:60) 13 | CC(11:20) = AA(1:10) 14 | !$OMP END WORKSHARE 15 | !$OMP END PARALLEL 16 | 17 | END SUBROUTINE WSHARE7 18 | -------------------------------------------------------------------------------- /program_control/nested_loop.tex: -------------------------------------------------------------------------------- 1 | %\pagebreak 2 | \section{Nested Loop Constructs} 3 | \label{sec:nested_loop} 4 | \index{nested loop constructs} 5 | 6 | The following example of loop construct nesting is conforming because the inner 7 | and outer loop regions bind to different \kcode{parallel} regions: 8 | 9 | \cexample{nested_loop}{1} 10 | 11 | \fexample{nested_loop}{1} 12 | 13 | The following variation of the preceding example is also conforming: 14 | 15 | \cexample{nested_loop}{2} 16 | 17 | \fexample{nested_loop}{2} 18 | 19 | 20 | -------------------------------------------------------------------------------- /program_control/sources/cancellation.1.f90: -------------------------------------------------------------------------------- 1 | ! @@name: cancellation.1 2 | ! @@type: F-free 3 | ! @@operation: compile 4 | ! @@expect: success 5 | ! @@version: omp_4.0 6 | subroutine example(n, dim) 7 | integer, intent(in) :: n, dim(n) 8 | integer :: i, s, err 9 | real, allocatable :: B(:) 10 | err = 0 11 | !$omp parallel shared(err) 12 | ! ... 13 | !$omp do private(s, B) 14 | do i=1, n 15 | !$omp cancellation point do 16 | allocate(B(dim(i)), stat=s) 17 | if (s .gt. 0) then 18 | !$omp atomic write 19 | err = s 20 | !$omp cancel do 21 | endif 22 | ! ... 23 | ! deallocate private array B 24 | if (allocated(B)) then 25 | deallocate(B) 26 | endif 27 | enddo 28 | !$omp end parallel 29 | end subroutine 30 | -------------------------------------------------------------------------------- /program_control/sources/cond_comp.1.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: cond_comp.1 3 | * @@type: C 4 | * @@operation: run 5 | * @@expect: success 6 | * @@version: pre_omp_3.0 7 | */ 8 | #include 9 | 10 | int main() 11 | { 12 | 13 | # ifdef _OPENMP 14 | printf("Compiled by an OpenMP-compliant implementation.\n"); 15 | # endif 16 | 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /program_control/sources/cond_comp.1.f: -------------------------------------------------------------------------------- 1 | ! @@name: cond_comp.1 2 | ! @@type: F-fixed 3 | ! @@operation: run 4 | ! @@expect: success 5 | ! @@version: pre_omp_3.0 6 | PROGRAM EXAMPLE 7 | 8 | C234567890 9 | !$ PRINT *, "Compiled by an OpenMP-compliant implementation." 10 | 11 | END PROGRAM EXAMPLE 12 | -------------------------------------------------------------------------------- /program_control/sources/display_env.1.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: display_env.1 3 | * @@type: C 4 | * @@operation: link 5 | * @@expect: success 6 | * @@version: omp_5.1 7 | */ 8 | #include 9 | 10 | //implementers: customize debug routines for app debugging 11 | int debug(){ return 1; } 12 | int debug_omp_verbose(){ return 0; } 13 | 14 | int main() 15 | { 16 | if( debug() ) omp_display_env( debug_omp_verbose() ); 17 | // ... 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /program_control/sources/display_env.1.f90: -------------------------------------------------------------------------------- 1 | ! @@name: display_env.1 2 | ! @@type: F-free 3 | ! @@operation: link 4 | ! @@expect: success 5 | ! @@version: omp_5.1 6 | !implementers: customize debug routines for app debugging 7 | function debug() 8 | logical :: debug 9 | debug = .true. 10 | end function 11 | 12 | function debug_omp_verbose() 13 | logical :: debug_omp_verbose 14 | debug_omp_verbose = .false. 15 | end function 16 | 17 | program display_omp_environment 18 | use omp_lib 19 | logical :: debug, debug_omp_verbose 20 | 21 | if( debug() ) call omp_display_env( debug_omp_verbose() ) 22 | !! ... 23 | end program 24 | -------------------------------------------------------------------------------- /program_control/sources/get_wtime.1.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: get_wtime.1 3 | * @@type: C 4 | * @@operation: link 5 | * @@expect: success 6 | * @@version: pre_omp_3.0 7 | */ 8 | #include 9 | #include 10 | #include 11 | 12 | void work_to_be_timed() 13 | { 14 | sleep(2); 15 | } 16 | 17 | int main() 18 | { 19 | double start, end; 20 | 21 | start = omp_get_wtime(); 22 | work_to_be_timed(); // any parallel or serial codes 23 | end = omp_get_wtime(); 24 | 25 | printf("Work took %f seconds\n", end - start); 26 | printf("Precision of the timer is %f (sec)\n", omp_get_wtick()); 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /program_control/sources/metadirective.1.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: metadirective.1 3 | * @@type: C 4 | * @@operation: run 5 | * @@expect: success 6 | * @@version: omp_5.2 7 | */ 8 | #define N 100 9 | #include 10 | 11 | int main() 12 | { 13 | int v1[N], v2[N], v3[N]; 14 | for(int i=0; i 9 | #include 10 | 11 | int main() 12 | { 13 | int x = 0, y = 0; 14 | #pragma omp parallel num_threads(2) 15 | { 16 | int thrd = omp_get_thread_num(); 17 | if (thrd == 0) { 18 | x = 10; 19 | #pragma omp critical 20 | { y = 1; } 21 | } else { 22 | int tmp = 0; 23 | while (tmp == 0) { 24 | #pragma omp critical 25 | { tmp = y; } 26 | } 27 | printf("x = %d\n", x); // always "x = 10" 28 | } 29 | } 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /synchronization/sources/acquire_release.1.f90: -------------------------------------------------------------------------------- 1 | ! @@name: acquire_release.1 2 | ! @@type: F-free 3 | ! @@operation: run 4 | ! @@expect: success 5 | ! @@version: omp_5.0 6 | program rel_acq_ex1 7 | use omp_lib 8 | integer :: x, y, thrd, tmp 9 | x = 0 10 | y = 0 11 | !$omp parallel num_threads(2) private(thrd, tmp) 12 | thrd = omp_get_thread_num() 13 | if (thrd == 0) then 14 | x = 10 15 | !$omp critical 16 | y = 1 17 | !$omp end critical 18 | else 19 | tmp = 0 20 | do while (tmp == 0) 21 | !$omp critical 22 | tmp = y 23 | !$omp end critical 24 | end do 25 | print *, "x = ", x !! always "x = 10" 26 | end if 27 | !$omp end parallel 28 | end program 29 | -------------------------------------------------------------------------------- /synchronization/sources/acquire_release.2.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: acquire_release.2 3 | * @@type: C 4 | * @@operation: run 5 | * @@expect: success 6 | * @@version: omp_5.0 7 | */ 8 | #include 9 | #include 10 | 11 | int main() 12 | { 13 | int x = 0, y = 0; 14 | #pragma omp parallel num_threads(2) 15 | { 16 | int thrd = omp_get_thread_num(); 17 | if (thrd == 0) { 18 | x = 10; 19 | #pragma omp atomic write release // or seq_cst 20 | y = 1; 21 | } else { 22 | int tmp = 0; 23 | while (tmp == 0) { 24 | #pragma omp atomic read acquire // or seq_cst 25 | tmp = y; 26 | } 27 | printf("x = %d\n", x); // always "x = 10" 28 | } 29 | } 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /synchronization/sources/atomic.2.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: atomic.2 3 | * @@type: C 4 | * @@operation: compile 5 | * @@expect: success 6 | * @@version: omp_3.1 7 | */ 8 | int atomic_read(const int *p) 9 | { 10 | int value; 11 | /* Guarantee that the entire value of *p is read atomically. No part of 12 | * *p can change during the read operation. 13 | */ 14 | #pragma omp atomic read 15 | value = *p; 16 | return value; 17 | } 18 | 19 | void atomic_write(int *p, int value) 20 | { 21 | /* Guarantee that value is stored atomically into *p. No part of *p can 22 | change 23 | * until after the entire write operation is completed. 24 | */ 25 | #pragma omp atomic write 26 | *p = value; 27 | } 28 | -------------------------------------------------------------------------------- /synchronization/sources/atomic.4.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: atomic.4 3 | * @@type: C 4 | * @@operation: compile 5 | * @@expect: success 6 | * @@version: omp_5.0 7 | */ 8 | #include 9 | 10 | void calc_val(float *val); 11 | 12 | void boxster(float *box_totals, float *vals, int *box, int N) 13 | { 14 | #pragma omp parallel for 15 | for(int idx=0; idx<=N; idx++) 16 | { 17 | calc_val(&vals[idx]); 18 | #pragma omp atomic hint(omp_sync_hint_uncontended) 19 | box_totals[ box[idx] ] = box_totals[ box[idx] ] + vals[idx]; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /synchronization/sources/atomic.4.f90: -------------------------------------------------------------------------------- 1 | ! @@name: atomic.4 2 | ! @@type: F-free 3 | ! @@operation: compile 4 | ! @@expect: success 5 | ! @@version: omp_5.0 6 | subroutine boxster(box_totals, vals, box, N) 7 | use omp_lib 8 | external calc_val 9 | real, intent(inout) :: box_totals(:) 10 | real, intent(in) :: vals(:) 11 | integer, intent(in) :: box(:) 12 | integer :: N, idx 13 | 14 | !$omp parallel do 15 | do idx=1,N 16 | call calc_val(vals(idx)) 17 | !$omp atomic hint(omp_sync_hint_uncontended) 18 | box_totals( box(idx) ) = box_totals( box(idx) ) + vals(idx) 19 | enddo 20 | 21 | end subroutine 22 | -------------------------------------------------------------------------------- /synchronization/sources/atomic_restrict.1.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: atomic_restrict.1 3 | * @@type: C 4 | * @@operation: compile 5 | * @@expect: unspecified 6 | * @@version: omp_3.1 7 | */ 8 | void atomic_wrong () 9 | { 10 | union {int n; float x;} u; 11 | 12 | #pragma omp parallel 13 | { 14 | #pragma omp atomic update 15 | u.n++; 16 | 17 | #pragma omp atomic update 18 | u.x += 1.0; 19 | 20 | /* Incorrect because the atomic constructs reference the same location 21 | through incompatible types */ 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /synchronization/sources/atomic_restrict.1.f: -------------------------------------------------------------------------------- 1 | ! @@name: atomic_restrict.1 2 | ! @@type: F-fixed 3 | ! @@operation: compile 4 | ! @@expect: unspecified 5 | ! @@version: omp_3.1 6 | SUBROUTINE ATOMIC_WRONG() 7 | INTEGER:: I 8 | REAL:: R 9 | EQUIVALENCE(I,R) 10 | 11 | !$OMP PARALLEL 12 | !$OMP ATOMIC UPDATE 13 | I = I + 1 14 | !$OMP ATOMIC UPDATE 15 | R = R + 1.0 16 | ! incorrect because I and R reference the same location 17 | ! but have different types 18 | !$OMP END PARALLEL 19 | END SUBROUTINE ATOMIC_WRONG 20 | -------------------------------------------------------------------------------- /synchronization/sources/atomic_restrict.2.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: atomic_restrict.2 3 | * @@type: C 4 | * @@operation: compile 5 | * @@expect: unspecified 6 | * @@version: omp_3.1 7 | */ 8 | void atomic_wrong2 () 9 | { 10 | int x; 11 | int *i; 12 | float *r; 13 | 14 | i = &x; 15 | r = (float *)&x; 16 | 17 | #pragma omp parallel 18 | { 19 | #pragma omp atomic update 20 | *i += 1; 21 | 22 | #pragma omp atomic update 23 | *r += 1.0; 24 | 25 | /* Incorrect because the atomic constructs reference the same location 26 | through incompatible types */ 27 | 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /synchronization/sources/atomic_restrict.2.f: -------------------------------------------------------------------------------- 1 | ! @@name: atomic_restrict.2 2 | ! @@type: F-fixed 3 | ! @@operation: compile 4 | ! @@expect: unspecified 5 | ! @@version: omp_3.1 6 | SUBROUTINE SUB() 7 | COMMON /BLK/ R 8 | REAL R 9 | 10 | !$OMP ATOMIC UPDATE 11 | R = R + 1.0 12 | END SUBROUTINE SUB 13 | 14 | SUBROUTINE ATOMIC_WRONG2() 15 | COMMON /BLK/ I 16 | INTEGER I 17 | 18 | !$OMP PARALLEL 19 | 20 | !$OMP ATOMIC UPDATE 21 | I = I + 1 22 | CALL SUB() 23 | !$OMP END PARALLEL 24 | END SUBROUTINE ATOMIC_WRONG2 25 | -------------------------------------------------------------------------------- /synchronization/sources/atomic_restrict.3.f: -------------------------------------------------------------------------------- 1 | ! @@name: atomic_restrict.3 2 | ! @@type: F-fixed 3 | ! @@operation: compile 4 | ! @@expect: unspecified 5 | ! @@version: omp_3.1 6 | SUBROUTINE ATOMIC_WRONG3 7 | INTEGER:: I 8 | REAL:: R 9 | EQUIVALENCE(I,R) 10 | 11 | !$OMP PARALLEL 12 | !$OMP ATOMIC UPDATE 13 | I = I + 1 14 | ! incorrect because I and R reference the same location 15 | ! but have different types 16 | !$OMP END PARALLEL 17 | 18 | !$OMP PARALLEL 19 | !$OMP ATOMIC UPDATE 20 | R = R + 1.0 21 | ! incorrect because I and R reference the same location 22 | ! but have different types 23 | !$OMP END PARALLEL 24 | 25 | END SUBROUTINE ATOMIC_WRONG3 26 | -------------------------------------------------------------------------------- /synchronization/sources/barrier_regions.1.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: barrier_regions.1 3 | * @@type: C 4 | * @@operation: link 5 | * @@expect: success 6 | * @@version: pre_omp_3.0 7 | */ 8 | void work(int n) {} 9 | 10 | void sub3(int n) 11 | { 12 | work(n); 13 | #pragma omp barrier 14 | work(n); 15 | } 16 | 17 | void sub2(int k) 18 | { 19 | #pragma omp parallel shared(k) 20 | sub3(k); 21 | } 22 | 23 | void sub1(int n) 24 | { 25 | int i; 26 | #pragma omp parallel private(i) shared(n) 27 | { 28 | #pragma omp for 29 | for (i=0; i 9 | 10 | int dequeue(float *a); 11 | void work(int i, float *a); 12 | 13 | void critical_example(float *x, float *y) 14 | { 15 | int ix_next, iy_next; 16 | 17 | #pragma omp parallel shared(x, y) private(ix_next, iy_next) 18 | { 19 | #pragma omp critical (xaxis) hint(omp_sync_hint_contended) 20 | ix_next = dequeue(x); 21 | work(ix_next, x); 22 | 23 | #pragma omp critical (yaxis) hint(omp_sync_hint_contended) 24 | iy_next = dequeue(y); 25 | work(iy_next, y); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /synchronization/sources/critical.2.f: -------------------------------------------------------------------------------- 1 | ! @@name: critical.2 2 | ! @@type: F-fixed 3 | ! @@operation: compile 4 | ! @@expect: success 5 | ! @@version: omp_5.0 6 | SUBROUTINE CRITICAL_EXAMPLE(X, Y) 7 | USE OMP_LIB ! or INCLUDE "omp_lib.h" 8 | 9 | REAL X(*), Y(*) 10 | INTEGER IX_NEXT, IY_NEXT 11 | 12 | !$OMP PARALLEL SHARED(X, Y) PRIVATE(IX_NEXT, IY_NEXT) 13 | 14 | !$OMP CRITICAL(XAXIS) HINT(OMP_SYNC_HINT_CONTENDED) 15 | CALL DEQUEUE(IX_NEXT, X) 16 | !$OMP END CRITICAL(XAXIS) 17 | CALL WORK(IX_NEXT, X) 18 | 19 | !$OMP CRITICAL(YAXIS) HINT(OMP_SYNC_HINT_CONTENDED) 20 | CALL DEQUEUE(IY_NEXT,Y) 21 | !$OMP END CRITICAL(YAXIS) 22 | CALL WORK(IY_NEXT, Y) 23 | 24 | !$OMP END PARALLEL 25 | 26 | END SUBROUTINE CRITICAL_EXAMPLE 27 | -------------------------------------------------------------------------------- /synchronization/sources/doacross.1.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: doacross.1 3 | * @@type: C 4 | * @@operation: compile 5 | * @@expect: success 6 | * @@version: omp_5.2 7 | */ 8 | float foo(int i); 9 | float bar(float a, float b); 10 | float baz(float b); 11 | 12 | void work( int N, float *A, float *B, float *C ) 13 | { 14 | int i; 15 | 16 | #pragma omp for ordered(1) 17 | for (i=1; i 9 | 10 | omp_lock_t *new_locks() { 11 | int i; 12 | omp_lock_t *lock = new omp_lock_t[1000]; 13 | 14 | #pragma omp parallel for private(i) 15 | for (i=0; i<1000; i++) 16 | { omp_init_lock(&lock[i]); } 17 | 18 | return lock; 19 | } 20 | -------------------------------------------------------------------------------- /synchronization/sources/init_lock.1.f: -------------------------------------------------------------------------------- 1 | ! @@name: init_lock.1 2 | ! @@type: F-fixed 3 | ! @@operation: compile 4 | ! @@expect: success 5 | ! @@version: pre_omp_3.0 6 | FUNCTION NEW_LOCKS() 7 | USE OMP_LIB ! or INCLUDE "omp_lib.h" 8 | INTEGER(OMP_LOCK_KIND), DIMENSION(1000) :: NEW_LOCKS 9 | INTEGER I 10 | 11 | !$OMP PARALLEL DO PRIVATE(I) 12 | DO I=1,1000 13 | CALL OMP_INIT_LOCK(NEW_LOCKS(I)) 14 | END DO 15 | !$OMP END PARALLEL DO 16 | 17 | END FUNCTION NEW_LOCKS 18 | -------------------------------------------------------------------------------- /synchronization/sources/init_lock_with_hint.1.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: init_lock_with_hint.1 3 | * @@type: C++ 4 | * @@operation: compile 5 | * @@expect: success 6 | * @@version: omp_5.0 7 | */ 8 | #include 9 | 10 | omp_lock_t *new_locks() 11 | { 12 | int i; 13 | omp_lock_t *lock = new omp_lock_t[1000]; 14 | 15 | #pragma omp parallel for private(i) 16 | for (i=0; i<1000; i++) 17 | { 18 | omp_init_lock_with_hint(&lock[i], 19 | static_cast(omp_sync_hint_contended | 20 | omp_sync_hint_speculative)); 21 | } 22 | return lock; 23 | } 24 | -------------------------------------------------------------------------------- /synchronization/sources/init_lock_with_hint.1.f: -------------------------------------------------------------------------------- 1 | ! @@name: init_lock_with_hint.1 2 | ! @@type: F-fixed 3 | ! @@operation: compile 4 | ! @@expect: success 5 | ! @@version: omp_5.0 6 | FUNCTION NEW_LOCKS() 7 | USE OMP_LIB ! or INCLUDE "omp_lib.h" 8 | INTEGER(OMP_LOCK_KIND), DIMENSION(1000) :: NEW_LOCKS 9 | 10 | INTEGER I 11 | 12 | !$OMP PARALLEL DO PRIVATE(I) 13 | DO I=1,1000 14 | CALL OMP_INIT_LOCK_WITH_HINT(NEW_LOCKS(I), 15 | & OMP_SYNC_HINT_CONTENDED + OMP_SYNC_HINT_SPECULATIVE) 16 | END DO 17 | !$OMP END PARALLEL DO 18 | 19 | END FUNCTION NEW_LOCKS 20 | -------------------------------------------------------------------------------- /synchronization/sources/lock_owner.1.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: lock_owner.1 3 | * @@type: C 4 | * @@operation: link 5 | * @@expect: success 6 | * @@version: omp_5.1 7 | */ 8 | #include 9 | #include 10 | #include 11 | 12 | int main() 13 | { 14 | int x; 15 | omp_lock_t lck; 16 | 17 | omp_init_lock (&lck); 18 | omp_set_lock (&lck); 19 | x = 0; 20 | 21 | #pragma omp parallel shared (x) 22 | { 23 | #pragma omp masked 24 | { 25 | x = x + 1; 26 | omp_unset_lock (&lck); 27 | } 28 | 29 | /* Some more stuff. */ 30 | } 31 | omp_destroy_lock (&lck); 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /synchronization/sources/lock_owner.1.f: -------------------------------------------------------------------------------- 1 | ! @@name: lock_owner.1 2 | ! @@type: F-fixed 3 | ! @@operation: link 4 | ! @@expect: success 5 | ! @@version: omp_5.1 6 | program lock 7 | use omp_lib 8 | integer :: x 9 | integer (kind=omp_lock_kind) :: lck 10 | 11 | call omp_init_lock (lck) 12 | call omp_set_lock(lck) 13 | x = 0 14 | 15 | !$omp parallel shared (x) 16 | !$omp masked 17 | x = x + 1 18 | call omp_unset_lock(lck) 19 | !$omp end masked 20 | 21 | ! Some more stuff. 22 | !$omp end parallel 23 | 24 | call omp_destroy_lock(lck) 25 | 26 | end 27 | -------------------------------------------------------------------------------- /synchronization/sources/ordered.1.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: ordered.1 3 | * @@type: C 4 | * @@operation: run 5 | * @@expect: success 6 | * @@version: pre_omp_3.0 7 | */ 8 | #include 9 | 10 | void work(int k) 11 | { 12 | #pragma omp ordered 13 | printf(" %d\n", k); 14 | } 15 | 16 | void ordered_example(int lb, int ub, int stride) 17 | { 18 | int i; 19 | 20 | #pragma omp parallel for ordered schedule(dynamic) 21 | for (i=lb; i 10) { 19 | #pragma omp ordered 20 | work(i+1); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /synchronization/sources/ordered.3.f: -------------------------------------------------------------------------------- 1 | ! @@name: ordered.3 2 | ! @@type: F-fixed 3 | ! @@operation: compile 4 | ! @@expect: success 5 | ! @@version: pre_omp_3.0 6 | SUBROUTINE ORDERED_GOOD(N) 7 | INTEGER N 8 | 9 | !$OMP DO ORDERED 10 | DO I = 1,N 11 | IF (I <= 10) THEN 12 | !$OMP ORDERED 13 | CALL WORK(I) 14 | !$OMP END ORDERED 15 | ENDIF 16 | 17 | IF (I > 10) THEN 18 | !$OMP ORDERED 19 | CALL WORK(I+1) 20 | !$OMP END ORDERED 21 | ENDIF 22 | ENDDO 23 | END SUBROUTINE ORDERED_GOOD 24 | -------------------------------------------------------------------------------- /synchronization/sources/worksharing_critical.1.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: worksharing_critical.1 3 | * @@type: C 4 | * @@operation: compile 5 | * @@expect: success 6 | * @@version: pre_omp_3.0 7 | */ 8 | void critical_work() 9 | { 10 | int i = 1; 11 | #pragma omp parallel sections 12 | { 13 | #pragma omp section 14 | { 15 | #pragma omp critical (name) 16 | { 17 | #pragma omp parallel 18 | { 19 | #pragma omp single 20 | { 21 | i++; 22 | } 23 | } 24 | } 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /synchronization/sources/worksharing_critical.1.f: -------------------------------------------------------------------------------- 1 | ! @@name: worksharing_critical.1 2 | ! @@type: F-fixed 3 | ! @@operation: compile 4 | ! @@expect: success 5 | ! @@version: pre_omp_3.0 6 | SUBROUTINE CRITICAL_WORK() 7 | 8 | INTEGER I 9 | I = 1 10 | 11 | !$OMP PARALLEL SECTIONS 12 | !$OMP SECTION 13 | !$OMP CRITICAL (NAME) 14 | !$OMP PARALLEL 15 | !$OMP SINGLE 16 | I = I + 1 17 | !$OMP END SINGLE 18 | !$OMP END PARALLEL 19 | !$OMP END CRITICAL (NAME) 20 | !$OMP END PARALLEL SECTIONS 21 | END SUBROUTINE CRITICAL_WORK 22 | -------------------------------------------------------------------------------- /tasking/sources/task_dep.1.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: task_dep.1 3 | * @@type: C 4 | * @@operation: run 5 | * @@expect: success 6 | * @@version: omp_4.0 7 | */ 8 | #include 9 | int main() { 10 | int x = 1; 11 | #pragma omp parallel 12 | #pragma omp single 13 | { 14 | #pragma omp task shared(x) depend(out: x) 15 | x = 2; 16 | #pragma omp task shared(x) depend(in: x) 17 | printf("x = %d\n", x); 18 | } 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /tasking/sources/task_dep.1.f90: -------------------------------------------------------------------------------- 1 | ! @@name: task_dep.1 2 | ! @@type: F-free 3 | ! @@operation: run 4 | ! @@expect: success 5 | ! @@version: omp_4.0 6 | program example 7 | integer :: x 8 | x = 1 9 | !$omp parallel 10 | !$omp single 11 | !$omp task shared(x) depend(out: x) 12 | x = 2 13 | !$omp end task 14 | !$omp task shared(x) depend(in: x) 15 | print*, "x = ", x 16 | !$omp end task 17 | !$omp end single 18 | !$omp end parallel 19 | end program 20 | -------------------------------------------------------------------------------- /tasking/sources/task_dep.10.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: task_dep.10 3 | * @@type: C 4 | * @@operation: compile 5 | * @@expect: success 6 | * @@version: omp_5.0 7 | */ 8 | extern int longTaskA(), shortTaskB(); 9 | extern int shortTaskAC(int,int), longTaskBC(int,int); 10 | void foo (void) 11 | { 12 | int a, b, c; 13 | c = 0; 14 | #pragma omp parallel 15 | #pragma omp single 16 | { 17 | #pragma omp task depend(out: a) 18 | a = longTaskA(); 19 | #pragma omp task depend(out: b) 20 | b = shortTaskB(); 21 | #pragma omp task depend(in: a) depend(mutexinoutset: c) 22 | c = shortTaskAC(a,c); 23 | #pragma omp task depend(in: b) depend(mutexinoutset: c) 24 | c = longTaskBC(b,c); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /tasking/sources/task_dep.10.f90: -------------------------------------------------------------------------------- 1 | ! @@name: task_dep.10 2 | ! @@type: F-free 3 | ! @@operation: compile 4 | ! @@expect: success 5 | ! @@version: omp_5.0 6 | subroutine foo 7 | integer :: a,b,c 8 | c = 0 9 | !$omp parallel 10 | !$omp single 11 | !$omp task depend(out: a) 12 | a = longTaskA() 13 | !$omp end task 14 | !$omp task depend(out: b) 15 | b = shortTaskB() 16 | !$omp end task 17 | !$omp task depend(in: a) depend(mutexinoutset: c) 18 | c = shortTaskAC(a,c) 19 | !$omp end task 20 | !$omp task depend(in: b) depend(mutexinoutset: c) 21 | c = longTaskBC(b,c) 22 | !$omp end task 23 | !$omp end single 24 | !$omp end parallel 25 | end subroutine foo 26 | -------------------------------------------------------------------------------- /tasking/sources/task_dep.12.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: task_dep.12 3 | * @@type: C 4 | * @@operation: run 5 | * @@expect: success 6 | * @@version: omp_4.0 7 | */ 8 | #include 9 | int main () 10 | { 11 | int x = 0; 12 | #pragma omp parallel 13 | #pragma omp single 14 | { 15 | /* first explicit task */ 16 | #pragma omp task shared(x) depend(out: x) 17 | x = 1; 18 | 19 | /* second explicit task */ 20 | #pragma omp task shared(x) depend(inout: x) if(0) 21 | x = 2; 22 | 23 | /* statement executed by parent implicit task 24 | prints: x = 2 */ 25 | printf("x = %d\n", x); 26 | } 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /tasking/sources/task_dep.12.f90: -------------------------------------------------------------------------------- 1 | ! @@name: task_dep.12 2 | ! @@type: F-free 3 | ! @@operation: run 4 | ! @@expect: success 5 | ! @@version: omp_4.0 6 | program example 7 | integer :: x 8 | x = 0 9 | !$omp parallel 10 | !$omp single 11 | !... first explicit task 12 | !$omp task shared(x) depend(out: x) 13 | x = 1 14 | !$omp end task 15 | 16 | !... second explicit task 17 | !$omp task shared(x) depend(inout: x) if(.false.) 18 | x = 2 19 | !$omp end task 20 | 21 | !... statement executed by parent implicit task 22 | ! prints: x = 2 23 | print*, "x = ", x 24 | !$omp end single 25 | !$omp end parallel 26 | end program 27 | -------------------------------------------------------------------------------- /tasking/sources/task_dep.2.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: task_dep.2 3 | * @@type: C 4 | * @@operation: run 5 | * @@expect: success 6 | * @@version: omp_4.0 7 | */ 8 | #include 9 | int main() 10 | { 11 | int x = 1; 12 | #pragma omp parallel 13 | #pragma omp single 14 | { 15 | #pragma omp task shared(x) depend(in: x) 16 | printf("x = %d\n", x); 17 | #pragma omp task shared(x) depend(out: x) 18 | x = 2; 19 | } 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /tasking/sources/task_dep.2.f90: -------------------------------------------------------------------------------- 1 | ! @@name: task_dep.2 2 | ! @@type: F-free 3 | ! @@operation: run 4 | ! @@expect: success 5 | ! @@version: omp_4.0 6 | program example 7 | integer :: x 8 | x = 1 9 | !$omp parallel 10 | !$omp single 11 | !$omp task shared(x) depend(in: x) 12 | print*, "x = ", x 13 | !$omp end task 14 | !$omp task shared(x) depend(out: x) 15 | x = 2 16 | !$omp end task 17 | !$omp end single 18 | !$omp end parallel 19 | end program 20 | -------------------------------------------------------------------------------- /tasking/sources/task_dep.3.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: task_dep.3 3 | * @@type: C 4 | * @@operation: run 5 | * @@expect: success 6 | * @@version: omp_4.0 7 | */ 8 | #include 9 | int main() { 10 | int x; 11 | #pragma omp parallel 12 | #pragma omp single 13 | { 14 | #pragma omp task shared(x) depend(out: x) 15 | x = 1; 16 | #pragma omp task shared(x) depend(out: x) 17 | x = 2; 18 | #pragma omp taskwait 19 | printf("x = %d\n", x); 20 | } 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /tasking/sources/task_dep.3.f90: -------------------------------------------------------------------------------- 1 | ! @@name: task_dep.3 2 | ! @@type: F-free 3 | ! @@operation: run 4 | ! @@expect: success 5 | ! @@version: omp_4.0 6 | program example 7 | integer :: x 8 | !$omp parallel 9 | !$omp single 10 | !$omp task shared(x) depend(out: x) 11 | x = 1 12 | !$omp end task 13 | !$omp task shared(x) depend(out: x) 14 | x = 2 15 | !$omp end task 16 | !$omp taskwait 17 | print*, "x = ", x 18 | !$omp end single 19 | !$omp end parallel 20 | end program 21 | -------------------------------------------------------------------------------- /tasking/sources/task_dep.4.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: task_dep.4 3 | * @@type: C 4 | * @@operation: run 5 | * @@expect: success 6 | * @@version: omp_4.0 7 | */ 8 | #include 9 | int main() { 10 | int x = 1; 11 | #pragma omp parallel 12 | #pragma omp single 13 | { 14 | #pragma omp task shared(x) depend(out: x) 15 | x = 2; 16 | #pragma omp task shared(x) depend(in: x) 17 | printf("x + 1 = %d. ", x+1); 18 | #pragma omp task shared(x) depend(in: x) 19 | printf("x + 2 = %d\n", x+2); 20 | } 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /tasking/sources/task_dep.4.f90: -------------------------------------------------------------------------------- 1 | ! @@name: task_dep.4 2 | ! @@type: F-free 3 | ! @@operation: run 4 | ! @@expect: success 5 | ! @@version: omp_4.0 6 | program example 7 | integer :: x 8 | 9 | x = 1 10 | 11 | !$omp parallel 12 | !$omp single 13 | 14 | !$omp task shared(x) depend(out: x) 15 | x = 2 16 | !$omp end task 17 | 18 | !$omp task shared(x) depend(in: x) 19 | print*, "x + 1 = ", x+1, "." 20 | !$omp end task 21 | 22 | !$omp task shared(x) depend(in: x) 23 | print*, "x + 2 = ", x+2, "." 24 | !$omp end task 25 | 26 | !$omp end single 27 | !$omp end parallel 28 | end program 29 | -------------------------------------------------------------------------------- /tasking/sources/task_dep.8.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: task_dep.8 3 | * @@type: C 4 | * @@operation: run 5 | * @@expect: success 6 | * @@version: omp_5.0 7 | */ 8 | #include 9 | 10 | void foo() 11 | { 12 | int x = 0, y = 2; 13 | 14 | #pragma omp task depend(inout: x) shared(x) 15 | x++; // 1st child task 16 | 17 | #pragma omp task depend(in: x) depend(inout: y) shared(x, y) 18 | y -= x; // 2st child task 19 | 20 | #pragma omp taskwait depend(in: x,y) 21 | 22 | printf("x=%d\n",x); 23 | printf("y=%d\n",y); 24 | 25 | } 26 | 27 | int main() 28 | { 29 | #pragma omp parallel 30 | #pragma omp single 31 | foo(); 32 | 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /tasking/sources/task_detach.1.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: task_detach.1 3 | * @@type: C 4 | * @@operation: compile 5 | * @@expect: success 6 | * @@version: omp_5.0 7 | */ 8 | #include 9 | 10 | void async_work(void (*)(void*), void*); 11 | void work(); 12 | 13 | int main() { 14 | int async=1; 15 | #pragma omp parallel 16 | #pragma omp masked 17 | { 18 | 19 | omp_event_handle_t event; 20 | #pragma omp task detach(event) 21 | { 22 | if(async) { 23 | async_work( (void (*)(void*)) omp_fulfill_event, (void*) event ); 24 | } else { 25 | work(); 26 | omp_fulfill_event(event); 27 | } 28 | } 29 | // Other work 30 | #pragma omp taskwait 31 | } 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /tasking/sources/task_detach.1.f90: -------------------------------------------------------------------------------- 1 | ! @@name: task_detach.1 2 | ! @@type: F-free 3 | ! @@operation: compile 4 | ! @@expect: success 5 | ! @@version: omp_5.0 6 | program main 7 | use omp_lib 8 | implicit none 9 | 10 | external :: async_work, work 11 | 12 | logical :: async=.true. 13 | integer(omp_event_handle_kind) :: event 14 | 15 | !$omp parallel 16 | !$omp masked 17 | 18 | !$omp task detach(event) 19 | 20 | if(async) then 21 | call async_work(omp_fulfill_event, event) 22 | else 23 | call work() 24 | call omp_fulfill_event(event) 25 | endif 26 | 27 | !$omp end task 28 | !! Other work 29 | 30 | !$omp taskwait 31 | 32 | !$omp end masked 33 | !$omp end parallel 34 | 35 | end program 36 | -------------------------------------------------------------------------------- /tasking/sources/task_priority.1.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: task_priority.1 3 | * @@type: C 4 | * @@operation: compile 5 | * @@expect: success 6 | * @@version: omp_4.5 7 | */ 8 | void compute_array (float *node, int M); 9 | 10 | void compute_matrix (float *array, int N, int M) 11 | { 12 | int i; 13 | #pragma omp parallel private(i) 14 | #pragma omp single 15 | { 16 | for (i=0;ileft) 18 | #pragma omp task // p is firstprivate by default 19 | traverse(p->left); 20 | if (p->right) 21 | #pragma omp task // p is firstprivate by default 22 | traverse(p->right); 23 | process(p); 24 | } 25 | -------------------------------------------------------------------------------- /tasking/sources/tasking.10.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: tasking.10 3 | * @@type: C 4 | * @@operation: compile 5 | * @@expect: success 6 | * @@version: omp_3.0 7 | */ 8 | #include 9 | void work() { 10 | omp_lock_t lock; 11 | omp_init_lock(&lock); 12 | #pragma omp parallel 13 | { 14 | int i; 15 | #pragma omp for 16 | for (i = 0; i < 100; i++) { 17 | #pragma omp task 18 | { 19 | // lock is shared by default in the task 20 | omp_set_lock(&lock); 21 | // Capture data for the following task 22 | #pragma omp task 23 | // Task Scheduling Point 1 24 | { /* do work here */ } 25 | omp_unset_lock(&lock); 26 | } 27 | } 28 | } 29 | omp_destroy_lock(&lock); 30 | } 31 | -------------------------------------------------------------------------------- /tasking/sources/tasking.11.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: tasking.11 3 | * @@type: C 4 | * @@operation: compile 5 | * @@expect: success 6 | * @@version: omp_3.1 7 | */ 8 | #include 9 | void foo ( ) 10 | { 11 | int x = 2; 12 | #pragma omp task shared(x) mergeable 13 | { 14 | x++; 15 | } 16 | #pragma omp taskwait 17 | printf("%d\n",x); // prints 3 18 | } 19 | -------------------------------------------------------------------------------- /tasking/sources/tasking.11.f90: -------------------------------------------------------------------------------- 1 | ! @@name: tasking.11 2 | ! @@type: F-free 3 | ! @@operation: compile 4 | ! @@expect: success 5 | ! @@version: omp_3.1 6 | subroutine foo() 7 | integer :: x 8 | x = 2 9 | !$omp task shared(x) mergeable 10 | x = x + 1 11 | !$omp end task 12 | !$omp taskwait 13 | print *, x ! prints 3 14 | end subroutine 15 | -------------------------------------------------------------------------------- /tasking/sources/tasking.12.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: tasking.12 3 | * @@type: C 4 | * @@operation: compile 5 | * @@expect: rt-error 6 | * @@version: omp_3.1 7 | */ 8 | #include 9 | void foo ( ) 10 | { 11 | int x = 2; 12 | #pragma omp task mergeable 13 | { 14 | x++; 15 | } 16 | #pragma omp taskwait 17 | printf("%d\n",x); // prints 2 or 3 18 | } 19 | -------------------------------------------------------------------------------- /tasking/sources/tasking.12.f90: -------------------------------------------------------------------------------- 1 | ! @@name: tasking.12 2 | ! @@type: F-free 3 | ! @@operation: compile 4 | ! @@expect: rt-error 5 | ! @@version: omp_3.1 6 | subroutine foo() 7 | integer :: x 8 | x = 2 9 | !$omp task mergeable 10 | x = x + 1 11 | !$omp end task 12 | !$omp taskwait 13 | print *, x ! prints 2 or 3 14 | end subroutine 15 | -------------------------------------------------------------------------------- /tasking/sources/tasking.14.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: tasking.14 3 | * @@type: C 4 | * @@operation: compile 5 | * @@expect: success 6 | * @@version: omp_3.1 7 | */ 8 | void bar(void); 9 | 10 | void foo ( ) 11 | { 12 | int i; 13 | #pragma omp task if(0) // This task is undeferred 14 | { 15 | #pragma omp task // This task is a regular task 16 | for (i = 0; i < 3; i++) { 17 | #pragma omp task // This task is a regular task 18 | bar(); 19 | } 20 | } 21 | #pragma omp task final(1) // This task is a regular task 22 | { 23 | #pragma omp task // This task is included 24 | for (i = 0; i < 3; i++) { 25 | #pragma omp task // This task is also included 26 | bar(); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /tasking/sources/tasking.14.f90: -------------------------------------------------------------------------------- 1 | ! @@name: tasking.14 2 | ! @@type: F-free 3 | ! @@operation: compile 4 | ! @@expect: success 5 | ! @@version: omp_3.1 6 | subroutine foo() 7 | integer i 8 | !$omp task if(.FALSE.) ! This task is undeferred 9 | !$omp task ! This task is a regular task 10 | do i = 1, 3 11 | !$omp task ! This task is a regular task 12 | call bar() 13 | !$omp end task 14 | enddo 15 | !$omp end task 16 | !$omp end task 17 | !$omp task final(.TRUE.) ! This task is a regular task 18 | !$omp task ! This task is included 19 | do i = 1, 3 20 | !$omp task ! This task is also included 21 | call bar() 22 | !$omp end task 23 | enddo 24 | !$omp end task 25 | !$omp end task 26 | end subroutine 27 | -------------------------------------------------------------------------------- /tasking/sources/tasking.2.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: tasking.2 3 | * @@type: C 4 | * @@operation: compile 5 | * @@expect: success 6 | * @@version: omp_3.0 7 | */ 8 | struct node { 9 | struct node *left; 10 | struct node *right; 11 | }; 12 | extern void process(struct node *); 13 | void postorder_traverse( struct node *p ) { 14 | if (p->left) 15 | #pragma omp task // p is firstprivate by default 16 | postorder_traverse(p->left); 17 | if (p->right) 18 | #pragma omp task // p is firstprivate by default 19 | postorder_traverse(p->right); 20 | #pragma omp taskwait 21 | process(p); 22 | } 23 | -------------------------------------------------------------------------------- /tasking/sources/tasking.3.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: tasking.3 3 | * @@type: C 4 | * @@operation: compile 5 | * @@expect: success 6 | * @@version: omp_3.0 7 | */ 8 | typedef struct node node; 9 | struct node { 10 | int data; 11 | node * next; 12 | }; 13 | 14 | void process(node * p) 15 | { 16 | /* do work here */ 17 | } 18 | 19 | void increment_list_items(node * head) 20 | { 21 | #pragma omp parallel 22 | { 23 | #pragma omp single 24 | { 25 | node * p = head; 26 | while (p) { 27 | #pragma omp task 28 | // p is firstprivate by default 29 | process(p); 30 | p = p->next; 31 | } 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /tasking/sources/tasking.4.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: tasking.4 3 | * @@type: C 4 | * @@operation: compile 5 | * @@expect: success 6 | * @@version: omp_3.0 7 | */ 8 | int fib(int n) { 9 | int i, j; 10 | if (n<2) 11 | return n; 12 | else { 13 | #pragma omp task shared(i) 14 | i=fib(n-1); 15 | #pragma omp task shared(j) 16 | j=fib(n-2); 17 | #pragma omp taskwait 18 | return i+j; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /tasking/sources/tasking.4.f: -------------------------------------------------------------------------------- 1 | ! @@name: tasking.4 2 | ! @@type: F-fixed 3 | ! @@operation: compile 4 | ! @@expect: success 5 | ! @@version: omp_3.0 6 | RECURSIVE INTEGER FUNCTION fib(n) RESULT(res) 7 | INTEGER n, i, j 8 | IF ( n .LT. 2) THEN 9 | res = n 10 | ELSE 11 | !$OMP TASK SHARED(i) 12 | i = fib( n-1 ) 13 | !$OMP END TASK 14 | !$OMP TASK SHARED(j) 15 | j = fib( n-2 ) 16 | !$OMP END TASK 17 | !$OMP TASKWAIT 18 | res = i+j 19 | END IF 20 | END FUNCTION 21 | -------------------------------------------------------------------------------- /tasking/sources/tasking.5.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @@name: tasking.5 3 | * @@type: C 4 | * @@operation: compile 5 | * @@expect: success 6 | * @@version: omp_3.0 7 | */ 8 | #define LARGE_NUMBER 10000000 9 | double item[LARGE_NUMBER]; 10 | extern void process(double); 11 | 12 | int main() 13 | { 14 | #pragma omp parallel 15 | { 16 | #pragma omp single 17 | { 18 | int i; 19 | for (i=0; i 9 | 10 | void something_useful ( void ); 11 | void something_critical ( void ); 12 | void foo ( omp_lock_t * lock, int n ) 13 | { 14 | int i; 15 | 16 | for ( i = 0; i < n; i++ ) 17 | #pragma omp task 18 | { 19 | something_useful(); 20 | while ( !omp_test_lock(lock) ) { 21 | #pragma omp taskyield 22 | } 23 | something_critical(); 24 | omp_unset_lock(lock); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /tasking/sources/taskyield.1.f90: -------------------------------------------------------------------------------- 1 | ! @@name: taskyield.1 2 | ! @@type: F-free 3 | ! @@operation: compile 4 | ! @@expect: success 5 | ! @@version: omp_3.1 6 | subroutine foo ( lock, n ) 7 | use omp_lib 8 | integer (kind=omp_lock_kind) :: lock 9 | integer n 10 | integer i 11 | 12 | do i = 1, n 13 | !$omp task 14 | call something_useful() 15 | do while ( .not. omp_test_lock(lock) ) 16 | !$omp taskyield 17 | end do 18 | call something_critical() 19 | call omp_unset_lock(lock) 20 | !$omp end task 21 | end do 22 | 23 | end subroutine 24 | -------------------------------------------------------------------------------- /tasking/taskyield.tex: -------------------------------------------------------------------------------- 1 | \pagebreak 2 | \section{\kcode{taskyield} Construct} 3 | \label{sec:taskyield} 4 | \index{constructs!taskyield@\kcode{taskyield}} 5 | \index{taskyield construct@\kcode{taskyield} construct} 6 | 7 | The following example illustrates the use of the \kcode{taskyield} construct. 8 | The tasks in the example compute something useful and then do some computation 9 | that must be done in a critical region. By using \kcode{taskyield} when a task 10 | cannot get access to the \kcode{critical} region the implementation can suspend 11 | the current task and schedule some other task that can do something useful. 12 | 13 | \cexample[3.1]{taskyield}{1} 14 | 15 | \ffreeexample[3.1]{taskyield}{1} 16 | 17 | -------------------------------------------------------------------------------- /util/Makefile: -------------------------------------------------------------------------------- 1 | CC=gcc 2 | CFLAGS=-O 3 | 4 | default: chk_tags.x 5 | 6 | chk_tags.x: chk_tags.c 7 | $(CC) -o $@ $(CFLAGS) $? 8 | 9 | clean: 10 | -rm -f *.o *.x 11 | -------------------------------------------------------------------------------- /util/cvt_fixed: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | dryrun=0 4 | if [ "$1" = "revert" ]; then 5 | for i in `ls */sources/*_orig`; do 6 | nf=`echo $i | sed -e 's/_orig$//'` 7 | echo "file -- $i --> $nf" 8 | if [ $dryrun -eq 0 ]; then 9 | mv $nf ${nf}_fix 10 | mv $i $nf 11 | fi 12 | done 13 | else 14 | for i in `ls */sources/*_fix`; do 15 | nf=`echo $i | sed -e 's/_fix$//'` 16 | echo "file -- $i --> $nf" 17 | if [ $dryrun -eq 0 ]; then 18 | mv $nf ${nf}_orig 19 | mv $i $nf 20 | fi 21 | done 22 | fi 23 | -------------------------------------------------------------------------------- /util/latexdiff/VERSION: -------------------------------------------------------------------------------- 1 | The current version of latexdiff comes from: 2 | git clone -b openmp-rebased git@github.com:jprotze/latexdiff.git 3 | 4 | The commit is 1ed71be6fb71927473bd9468ce42f42e1431b5ab -------------------------------------------------------------------------------- /versioninfo: -------------------------------------------------------------------------------- 1 | # Examples Document Version (VER) 2 | version=6.0 3 | 4 | # Supported Spec Version (SVER) 5 | version_spec=6.0 6 | 7 | # Document Release Date (VERDATE) 8 | version_date=November 2024 9 | --------------------------------------------------------------------------------