Commit 061f4578 by Thomas Rodgers Committed by Jonathan Wakely

Integrate C++17 parallel algorithms

This is the Intel implementation of the C++17 parallel
algorithms, which has been donated to both GCC and LLVM. The upstream
project is at -

	https://reviews.llvm.org/source/pstl/

The new files in the include/pstl sub-directory are covered by the
LICENSE.txt in that sub-directory, as are the tests in
testsuite/**/pstl/*

	* include/Makefile.am (std_header): Add ${std_srcdir}/execution.
	(pstl_srcdir, pstl_builddir, pstl_headers): New variables.
	(allstamped): Add stamp-pstl.
	(install-headers): Add ptsl_builddir.
	* include/Makefile.in: Regenerate.
	* include/bits/c++config: Add pstl configuration.
	* include/pstl/LICENSE.txt: New file.
	* include/pstl/algorithm_fwd.h: New file.
	* include/pstl/algorithm_impl.h: New file.
	* include/pstl/execution_defs.h: New file.
	* include/pstl/execution_impl.h: New file.
	* include/pstl/glue_algorithm_defs.h: New file.
	* include/pstl/glue_algorithm_impl.h: New file.
	* include/pstl/glue_execution_defs.h: New file.
	* include/pstl/glue_memory_defs.h: New file.
	* include/pstl/glue_memory_impl.h: New file.
	* include/pstl/glue_numeric_defs.h: New file.
	* include/pstl/glue_numeric_impl.h: New file.
	* include/pstl/memory_impl.h: New file.
	* include/pstl/numeric_fwd.h: New file.
	* include/pstl/numeric_impl.h: New file.
	* include/pstl/parallel_backend.h: New file.
	* include/pstl/parallel_backend_tbb.h: New file.
	* include/pstl/parallel_backend_utils.h: New file.
	* include/pstl/parallel_impl.h: New file.
	* include/pstl/pstl_config.h: New file.
	* include/pstl/unseq_backend_simd.h: New file.
	* include/pstl/utils.h: New file.
	* include/std/algorithm: Include parallel algorithm implementations.
	* include/std/execution: New file.
	* include/std/memory: Include parallel algorithm implementations.
	* include/std/numeric: Include parallel algorithm implementations.
	* include/std/version: Add parallel algorithms feature test macro.
	* testsuite/util/pstl/pstl_test_config.h: New file.
	* testsuite/util/pstl/test_utils.h: New file.
	* testsuite/20_util/specialized_algorithms/pstl/uninitialized_construct.cc: New file.
	* testsuite/20_util/specialized_algorithms/pstl/uninitialized_copy_move.cc: New file.
	* testsuite/20_util/specialized_algorithms/pstl/uninitialized_fill_destroy.cc: New file.
	* testsuite/25_algorithms/pstl/alg_merge/inplace_merge.cc: New file.
	* testsuite/25_algorithms/pstl/alg_merge/merge.cc: New file.
	* testsuite/25_algorithms/pstl/alg_modifying_operations/copy_if.cc: New file.
	* testsuite/25_algorithms/pstl/alg_modifying_operations/copy_move.cc: New file.
	* testsuite/25_algorithms/pstl/alg_modifying_operations/fill.cc: New file.
	* testsuite/25_algorithms/pstl/alg_modifying_operations/generate.cc: New file.
	* testsuite/25_algorithms/pstl/alg_modifying_operations/is_partitioned.cc: New file.
	* testsuite/25_algorithms/pstl/alg_modifying_operations/partition.cc: New file.
	* testsuite/25_algorithms/pstl/alg_modifying_operations/partition_copy.cc: New file.
	* testsuite/25_algorithms/pstl/alg_modifying_operations/remove.cc: New file.
	* testsuite/25_algorithms/pstl/alg_modifying_operations/remove_copy.cc: New file.
	* testsuite/25_algorithms/pstl/alg_modifying_operations/replace.cc: New file.
	* testsuite/25_algorithms/pstl/alg_modifying_operations/replace_copy.cc: New file.
	* testsuite/25_algorithms/pstl/alg_modifying_operations/rotate.cc: New file.
	* testsuite/25_algorithms/pstl/alg_modifying_operations/rotate_copy.cc: New file.
	* testsuite/25_algorithms/pstl/alg_modifying_operations/swap_ranges.cc: New file.
	* testsuite/25_algorithms/pstl/alg_modifying_operations/transform_binary.cc: New file.
	* testsuite/25_algorithms/pstl/alg_modifying_operations/transform_unary.cc: New file.
	* testsuite/25_algorithms/pstl/alg_modifying_operations/unique.cc: New file.
	* testsuite/25_algorithms/pstl/alg_modifying_operations/unique_copy_equal.cc: New file.
	* testsuite/25_algorithms/pstl/alg_nonmodifying/adjacent_find.cc: New file.
	* testsuite/25_algorithms/pstl/alg_nonmodifying/all_of.cc: New file.
	* testsuite/25_algorithms/pstl/alg_nonmodifying/any_of.cc: New file.
	* testsuite/25_algorithms/pstl/alg_nonmodifying/count.cc: New file.
	* testsuite/25_algorithms/pstl/alg_nonmodifying/equal.cc: New file.
	* testsuite/25_algorithms/pstl/alg_nonmodifying/find.cc: New file.
	* testsuite/25_algorithms/pstl/alg_nonmodifying/find_end.cc: New file.
	* testsuite/25_algorithms/pstl/alg_nonmodifying/find_first_of.cc: New file.
	* testsuite/25_algorithms/pstl/alg_nonmodifying/find_if.cc: New file.
	* testsuite/25_algorithms/pstl/alg_nonmodifying/for_each.cc: New file.
	* testsuite/25_algorithms/pstl/alg_nonmodifying/mismatch.cc: New file.
	* testsuite/25_algorithms/pstl/alg_nonmodifying/none_of.cc: New file.
	* testsuite/25_algorithms/pstl/alg_nonmodifying/nth_element.cc: New file.
	* testsuite/25_algorithms/pstl/alg_nonmodifying/reverse.cc: New file.
	* testsuite/25_algorithms/pstl/alg_nonmodifying/reverse_copy.cc: New file.
	* testsuite/25_algorithms/pstl/alg_nonmodifying/search_n.cc: New file.
	* testsuite/25_algorithms/pstl/alg_sorting/includes.cc: New file.
	* testsuite/25_algorithms/pstl/alg_sorting/is_heap.cc: New file.
	* testsuite/25_algorithms/pstl/alg_sorting/is_sorted.cc: New file.
	* testsuite/25_algorithms/pstl/alg_sorting/lexicographical_compare.cc: New file.
	* testsuite/25_algorithms/pstl/alg_sorting/minmax_element.cc: New file.
	* testsuite/25_algorithms/pstl/alg_sorting/partial_sort.cc: New file.
	* testsuite/25_algorithms/pstl/alg_sorting/partial_sort_copy.cc: New file.
	* testsuite/25_algorithms/pstl/alg_sorting/set.cc: New file.
	* testsuite/25_algorithms/pstl/alg_sorting/sort.cc: New file.
	* testsuite/26_numerics/pstl/numeric_ops/adjacent_difference.cc: New file.
	* testsuite/26_numerics/pstl/numeric_ops/reduce.cc: New file.
	* testsuite/26_numerics/pstl/numeric_ops/scan.cc: New file.
	* testsuite/26_numerics/pstl/numeric_ops/transform_reduce.cc: New file.
	* testsuite/26_numerics/pstl/numeric_ops/transform_scan.cc: New file.
	* testsuite/testsuite/20_util/specialized_algorithms/pstl/uninitialized_construct.cc: New file.
	* testsuite/testsuite/20_util/specialized_algorithms/pstl/uninitialized_copy_move.cc: New file.
	* testsuite/testsuite/20_util/specialized_algorithms/pstl/uninitialized_fill_destroy.cc: New file.
	* testsuite/testsuite/25_algorithms/pstl/alg_merge/inplace_merge.cc: New file.
	* testsuite/testsuite/25_algorithms/pstl/alg_merge/merge.cc: New file.
	* testsuite/testsuite/25_algorithms/pstl/alg_modifying_operations/copy_if.cc: New file.
	* testsuite/testsuite/25_algorithms/pstl/alg_modifying_operations/copy_move.cc: New file.
	* testsuite/testsuite/25_algorithms/pstl/alg_modifying_operations/fill.cc: New file.
	* testsuite/testsuite/25_algorithms/pstl/alg_modifying_operations/generate.cc: New file.
	* testsuite/testsuite/25_algorithms/pstl/alg_modifying_operations/is_partitioned.cc: New file.
	* testsuite/testsuite/25_algorithms/pstl/alg_modifying_operations/partition.cc: New file.
	* testsuite/testsuite/25_algorithms/pstl/alg_modifying_operations/partition_copy.cc: New file.
	* testsuite/testsuite/25_algorithms/pstl/alg_modifying_operations/remove.cc: New file.
	* testsuite/testsuite/25_algorithms/pstl/alg_modifying_operations/remove_copy.cc: New file.
	* testsuite/testsuite/25_algorithms/pstl/alg_modifying_operations/replace.cc: New file.
	* testsuite/testsuite/25_algorithms/pstl/alg_modifying_operations/replace_copy.cc: New file.
	* testsuite/testsuite/25_algorithms/pstl/alg_modifying_operations/rotate.cc: New file.
	* testsuite/testsuite/25_algorithms/pstl/alg_modifying_operations/rotate_copy.cc: New file.
	* testsuite/testsuite/25_algorithms/pstl/alg_modifying_operations/swap_ranges.cc: New file.
	* testsuite/testsuite/25_algorithms/pstl/alg_modifying_operations/transform_binary.cc: New file.
	* testsuite/testsuite/25_algorithms/pstl/alg_modifying_operations/transform_unary.cc: New file.
	* testsuite/testsuite/25_algorithms/pstl/alg_modifying_operations/unique.cc: New file.
	* testsuite/testsuite/25_algorithms/pstl/alg_modifying_operations/unique_copy_equal.cc: New file.
	* testsuite/testsuite/25_algorithms/pstl/alg_nonmodifying/adjacent_find.cc: New file.
	* testsuite/testsuite/25_algorithms/pstl/alg_nonmodifying/all_of.cc: New file.
	* testsuite/testsuite/25_algorithms/pstl/alg_nonmodifying/any_of.cc: New file.
	* testsuite/testsuite/25_algorithms/pstl/alg_nonmodifying/count.cc: New file.
	* testsuite/testsuite/25_algorithms/pstl/alg_nonmodifying/equal.cc: New file.
	* testsuite/testsuite/25_algorithms/pstl/alg_nonmodifying/find.cc: New file.
	* testsuite/testsuite/25_algorithms/pstl/alg_nonmodifying/find_end.cc: New file.
	* testsuite/testsuite/25_algorithms/pstl/alg_nonmodifying/find_first_of.cc: New file.
	* testsuite/testsuite/25_algorithms/pstl/alg_nonmodifying/find_if.cc: New file.
	* testsuite/testsuite/25_algorithms/pstl/alg_nonmodifying/for_each.cc: New file.
	* testsuite/testsuite/25_algorithms/pstl/alg_nonmodifying/mismatch.cc: New file.
	* testsuite/testsuite/25_algorithms/pstl/alg_nonmodifying/none_of.cc: New file.
	* testsuite/testsuite/25_algorithms/pstl/alg_nonmodifying/nth_element.cc: New file.
	* testsuite/testsuite/25_algorithms/pstl/alg_nonmodifying/reverse.cc: New file.
	* testsuite/testsuite/25_algorithms/pstl/alg_nonmodifying/reverse_copy.cc: New file.
	* testsuite/testsuite/25_algorithms/pstl/alg_nonmodifying/search_n.cc: New file.
	* testsuite/testsuite/25_algorithms/pstl/alg_sorting/includes.cc: New file.
	* testsuite/testsuite/25_algorithms/pstl/alg_sorting/is_heap.cc: New file.
	* testsuite/testsuite/25_algorithms/pstl/alg_sorting/is_sorted.cc: New file.
	* testsuite/testsuite/25_algorithms/pstl/alg_sorting/lexicographical_compare.cc: New file.
	* testsuite/testsuite/25_algorithms/pstl/alg_sorting/minmax_element.cc: New file.
	* testsuite/testsuite/25_algorithms/pstl/alg_sorting/partial_sort.cc: New file.
	* testsuite/testsuite/25_algorithms/pstl/alg_sorting/partial_sort_copy.cc: New file.
	* testsuite/testsuite/25_algorithms/pstl/alg_sorting/set.cc: New file.
	* testsuite/testsuite/25_algorithms/pstl/alg_sorting/sort.cc: New file.
	* testsuite/testsuite/26_numerics/pstl/numeric_ops/adjacent_difference.cc: New file.
	* testsuite/testsuite/26_numerics/pstl/numeric_ops/reduce.cc: New file.
	* testsuite/testsuite/26_numerics/pstl/numeric_ops/scan.cc: New file.
	* testsuite/testsuite/26_numerics/pstl/numeric_ops/transform_reduce.cc: New file.
	* testsuite/testsuite/26_numerics/pstl/numeric_ops/transform_scan.cc: New file.

From-SVN: r269863
parent 774856e3
...@@ -38,6 +38,7 @@ std_headers = \ ...@@ -38,6 +38,7 @@ std_headers = \
${std_srcdir}/complex \ ${std_srcdir}/complex \
${std_srcdir}/condition_variable \ ${std_srcdir}/condition_variable \
${std_srcdir}/deque \ ${std_srcdir}/deque \
${std_srcdir}/execution \
${std_srcdir}/filesystem \ ${std_srcdir}/filesystem \
${std_srcdir}/forward_list \ ${std_srcdir}/forward_list \
${std_srcdir}/fstream \ ${std_srcdir}/fstream \
...@@ -225,6 +226,32 @@ bits_sup_headers = \ ...@@ -225,6 +226,32 @@ bits_sup_headers = \
${bits_sup_srcdir}/hash_bytes.h \ ${bits_sup_srcdir}/hash_bytes.h \
${bits_sup_srcdir}/nested_exception.h ${bits_sup_srcdir}/nested_exception.h
# C++17 Parallel Algorithm Includes.
pstl_srcdir = ${glibcxx_srcdir}/include/pstl
pstl_builddir = ./pstl
pstl_headers = \
${pstl_srcdir}/algorithm_fwd.h \
${pstl_srcdir}/algorithm_impl.h \
${pstl_srcdir}/execution_defs.h \
${pstl_srcdir}/execution_impl.h \
${pstl_srcdir}/glue_algorithm_defs.h \
${pstl_srcdir}/glue_algorithm_impl.h \
${pstl_srcdir}/glue_execution_defs.h \
${pstl_srcdir}/glue_memory_defs.h \
${pstl_srcdir}/glue_memory_impl.h \
${pstl_srcdir}/glue_numeric_defs.h \
${pstl_srcdir}/glue_numeric_impl.h \
${pstl_srcdir}/memory_impl.h \
${pstl_srcdir}/numeric_fwd.h \
${pstl_srcdir}/numeric_impl.h \
${pstl_srcdir}/parallel_backend.h \
${pstl_srcdir}/parallel_backend_tbb.h \
${pstl_srcdir}/parallel_backend_utils.h \
${pstl_srcdir}/parallel_impl.h \
${pstl_srcdir}/pstl_config.h \
${pstl_srcdir}/unseq_backend_simd.h \
${pstl_srcdir}/utils.h
backward_srcdir = ${glibcxx_srcdir}/include/backward backward_srcdir = ${glibcxx_srcdir}/include/backward
backward_builddir = ./backward backward_builddir = ./backward
backward_headers = \ backward_headers = \
...@@ -1014,7 +1041,7 @@ endif ...@@ -1014,7 +1041,7 @@ endif
# List of all timestamp files. By keeping only one copy of this list, both # List of all timestamp files. By keeping only one copy of this list, both
# CLEANFILES and all-local are kept up-to-date. # CLEANFILES and all-local are kept up-to-date.
allstamped = \ allstamped = \
stamp-std stamp-bits stamp-bits-sup stamp-c_base stamp-c_compatibility \ stamp-std stamp-bits stamp-bits-sup stamp-pstl stamp-c_base stamp-c_compatibility \
stamp-backward stamp-ext stamp-pb stamp-tr1 stamp-tr2 stamp-decimal \ stamp-backward stamp-ext stamp-pb stamp-tr1 stamp-tr2 stamp-decimal \
stamp-experimental stamp-experimental-bits stamp-debug stamp-parallel \ stamp-experimental stamp-experimental-bits stamp-debug stamp-parallel \
stamp-profile stamp-profile-impl stamp-host stamp-profile stamp-profile-impl stamp-host
...@@ -1047,6 +1074,11 @@ stamp-bits-sup: stamp-bits ${bits_sup_headers} ...@@ -1047,6 +1074,11 @@ stamp-bits-sup: stamp-bits ${bits_sup_headers}
@-cd ${bits_builddir} && $(LN_S) ${bits_sup_headers} . 2>/dev/null @-cd ${bits_builddir} && $(LN_S) ${bits_sup_headers} . 2>/dev/null
@$(STAMP) stamp-bits-sup @$(STAMP) stamp-bits-sup
stamp-pstl: ${pstl_headers}
@-mkdir -p ${pstl_builddir}
@-cd ${pstl_builddir} && $(LN_S) $? . 2>/dev/null
@$(STAMP) stamp-pstl
stamp-c_base: ${c_base_headers} stamp-c_base: ${c_base_headers}
@-mkdir -p ${c_base_builddir} @-mkdir -p ${c_base_builddir}
@-cd ${c_base_builddir} && $(LN_S) $? . 2>/dev/null @-cd ${c_base_builddir} && $(LN_S) $? . 2>/dev/null
...@@ -1480,7 +1512,9 @@ install-headers: ...@@ -1480,7 +1512,9 @@ install-headers:
$(mkinstalldirs) $(DESTDIR)${host_installdir}/../ext $(mkinstalldirs) $(DESTDIR)${host_installdir}/../ext
for file in ${ext_host_headers}; do \ for file in ${ext_host_headers}; do \
$(INSTALL_DATA) $${file} $(DESTDIR)${host_installdir}/../ext; done $(INSTALL_DATA) $${file} $(DESTDIR)${host_installdir}/../ext; done
$(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${pstl_builddir}
for file in ${pstl_headers}; do \
$(INSTALL_DATA) $${file} $(DESTDIR)${gxx_include_dir}/${pstl_builddir}; done
# By adding these files here, automake will remove them for 'make clean' # By adding these files here, automake will remove them for 'make clean'
CLEANFILES = ${pch_output} ${pch_output_anchors} stamp-host CLEANFILES = ${pch_output} ${pch_output_anchors} stamp-host
......
...@@ -382,6 +382,7 @@ std_headers = \ ...@@ -382,6 +382,7 @@ std_headers = \
${std_srcdir}/complex \ ${std_srcdir}/complex \
${std_srcdir}/condition_variable \ ${std_srcdir}/condition_variable \
${std_srcdir}/deque \ ${std_srcdir}/deque \
${std_srcdir}/execution \
${std_srcdir}/filesystem \ ${std_srcdir}/filesystem \
${std_srcdir}/forward_list \ ${std_srcdir}/forward_list \
${std_srcdir}/fstream \ ${std_srcdir}/fstream \
...@@ -569,6 +570,33 @@ bits_sup_headers = \ ...@@ -569,6 +570,33 @@ bits_sup_headers = \
${bits_sup_srcdir}/hash_bytes.h \ ${bits_sup_srcdir}/hash_bytes.h \
${bits_sup_srcdir}/nested_exception.h ${bits_sup_srcdir}/nested_exception.h
# C++17 Parallel Algorithm Includes.
pstl_srcdir = ${glibcxx_srcdir}/include/pstl
pstl_builddir = ./pstl
pstl_headers = \
${pstl_srcdir}/algorithm_fwd.h \
${pstl_srcdir}/algorithm_impl.h \
${pstl_srcdir}/execution_defs.h \
${pstl_srcdir}/execution_impl.h \
${pstl_srcdir}/glue_algorithm_defs.h \
${pstl_srcdir}/glue_algorithm_impl.h \
${pstl_srcdir}/glue_execution_defs.h \
${pstl_srcdir}/glue_memory_defs.h \
${pstl_srcdir}/glue_memory_impl.h \
${pstl_srcdir}/glue_numeric_defs.h \
${pstl_srcdir}/glue_numeric_impl.h \
${pstl_srcdir}/memory_impl.h \
${pstl_srcdir}/numeric_fwd.h \
${pstl_srcdir}/numeric_impl.h \
${pstl_srcdir}/parallel_backend.h \
${pstl_srcdir}/parallel_backend_tbb.h \
${pstl_srcdir}/parallel_backend_utils.h \
${pstl_srcdir}/parallel_impl.h \
${pstl_srcdir}/pstl_config.h \
${pstl_srcdir}/unseq_backend_simd.h \
${pstl_srcdir}/utils.h
backward_srcdir = ${glibcxx_srcdir}/include/backward backward_srcdir = ${glibcxx_srcdir}/include/backward
backward_builddir = ./backward backward_builddir = ./backward
backward_headers = \ backward_headers = \
...@@ -1346,7 +1374,7 @@ PCHFLAGS = -x c++-header -nostdinc++ $(CXXFLAGS) $(VTV_PCH_CXXFLAGS) ...@@ -1346,7 +1374,7 @@ PCHFLAGS = -x c++-header -nostdinc++ $(CXXFLAGS) $(VTV_PCH_CXXFLAGS)
# List of all timestamp files. By keeping only one copy of this list, both # List of all timestamp files. By keeping only one copy of this list, both
# CLEANFILES and all-local are kept up-to-date. # CLEANFILES and all-local are kept up-to-date.
allstamped = \ allstamped = \
stamp-std stamp-bits stamp-bits-sup stamp-c_base stamp-c_compatibility \ stamp-std stamp-bits stamp-bits-sup stamp-pstl stamp-c_base stamp-c_compatibility \
stamp-backward stamp-ext stamp-pb stamp-tr1 stamp-tr2 stamp-decimal \ stamp-backward stamp-ext stamp-pb stamp-tr1 stamp-tr2 stamp-decimal \
stamp-experimental stamp-experimental-bits stamp-debug stamp-parallel \ stamp-experimental stamp-experimental-bits stamp-debug stamp-parallel \
stamp-profile stamp-profile-impl stamp-host stamp-profile stamp-profile-impl stamp-host
...@@ -1362,7 +1390,6 @@ allcreated = \ ...@@ -1362,7 +1390,6 @@ allcreated = \
# Host includes for threads # Host includes for threads
uppercase = [ABCDEFGHIJKLMNOPQRSTUVWXYZ_] uppercase = [ABCDEFGHIJKLMNOPQRSTUVWXYZ_]
# By adding these files here, automake will remove them for 'make clean' # By adding these files here, automake will remove them for 'make clean'
CLEANFILES = ${pch_output} ${pch_output_anchors} stamp-host CLEANFILES = ${pch_output} ${pch_output_anchors} stamp-host
all: all-am all: all-am
...@@ -1550,6 +1577,11 @@ stamp-bits-sup: stamp-bits ${bits_sup_headers} ...@@ -1550,6 +1577,11 @@ stamp-bits-sup: stamp-bits ${bits_sup_headers}
@-cd ${bits_builddir} && $(LN_S) ${bits_sup_headers} . 2>/dev/null @-cd ${bits_builddir} && $(LN_S) ${bits_sup_headers} . 2>/dev/null
@$(STAMP) stamp-bits-sup @$(STAMP) stamp-bits-sup
stamp-pstl: ${pstl_headers}
@-mkdir -p ${pstl_builddir}
@-cd ${pstl_builddir} && $(LN_S) $? . 2>/dev/null
@$(STAMP) stamp-pstl
stamp-c_base: ${c_base_headers} stamp-c_base: ${c_base_headers}
@-mkdir -p ${c_base_builddir} @-mkdir -p ${c_base_builddir}
@-cd ${c_base_builddir} && $(LN_S) $? . 2>/dev/null @-cd ${c_base_builddir} && $(LN_S) $? . 2>/dev/null
...@@ -1956,6 +1988,9 @@ install-headers: ...@@ -1956,6 +1988,9 @@ install-headers:
$(mkinstalldirs) $(DESTDIR)${host_installdir}/../ext $(mkinstalldirs) $(DESTDIR)${host_installdir}/../ext
for file in ${ext_host_headers}; do \ for file in ${ext_host_headers}; do \
$(INSTALL_DATA) $${file} $(DESTDIR)${host_installdir}/../ext; done $(INSTALL_DATA) $${file} $(DESTDIR)${host_installdir}/../ext; done
$(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${pstl_builddir}
for file in ${pstl_headers}; do \
$(INSTALL_DATA) $${file} $(DESTDIR)${gxx_include_dir}/${pstl_builddir}; done
# To remove directories. # To remove directories.
clean-local: clean-local:
......
...@@ -665,4 +665,103 @@ namespace std ...@@ -665,4 +665,103 @@ namespace std
# endif # endif
#endif // GCC #endif // GCC
// PSTL configuration
#if __cplusplus >= 201703L
// Preserved here so we have some idea which version of upstream we've pulled in
// #define PSTL_VERSION 104
// #define PSTL_VERSION_MAJOR (PSTL_VERSION/100)
// #define PSTL_VERSION_MINOR (PSTL_VERSION - PSTL_VERSION_MAJOR * 100)
// For now this defaults to being based on the presence of Thread Building Blocks
# ifndef _GLIBCXX_USE_TBB_PAR_BACKEND
# define _GLIBCXX_USE_TBB_PAR_BACKEND __has_include(<tbb/tbb.h>)
# endif
// This section will need some rework when a new (default) backend type is added
# if _GLIBCXX_USE_TBB_PAR_BACKEND
# define __PSTL_USE_PAR_POLICIES 1
# endif
# if __PSTL_USE_PAR_POLICIES
# if !defined(__PSTL_PAR_BACKEND_TBB)
# define __PSTL_PAR_BACKEND_TBB 1
# endif
# else
# undef __PSTL_PAR_BACKEND_TBB
# endif
# define __PSTL_PRAGMA(x) _Pragma (#x)
# define __PSTL_STRING_AUX(x) #x
# define __PSTL_STRING(x) __PSTL_STRING_AUX(x)
# define __PSTL_STRING_CONCAT(x, y) x#y
# define __PSTL_GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + \
__GNUC_PATCHLEVEL__)
// Enable SIMD for compilers that support OpenMP 4.0
# if (__PSTL_GCC_VERSION >= 40900)
# define __PSTL_PRAGMA_SIMD __PSTL_PRAGMA(omp simd)
#define __PSTL_PRAGMA_DECLARE_SIMD __PSTL_PRAGMA(omp declare simd)
# define __PSTL_PRAGMA_SIMD_REDUCTION(PRM) __PSTL_PRAGMA(omp simd reduction(PRM))
# else //no simd
# define __PSTL_PRAGMA_SIMD
# define __PSTL_PRAGMA_SIMD_REDUCTION(PRM)
# endif //Enable SIMD
#define __PSTL_PRAGMA_SIMD_SCAN(PRM)
#define __PSTL_PRAGMA_SIMD_INCLUSIVE_SCAN(PRM)
#define __PSTL_PRAGMA_SIMD_EXCLUSIVE_SCAN(PRM)
#define __PSTL_PRAGMA_FORCEINLINE
// Should be defined to 1 for environments with a vendor implementation
// of C++17 execution policies
// #define __PSTL_CPP17_EXECUTION_POLICIES_PRESENT (_MSC_VER >= 1912)
// TODO define libstdc++ policies
# define __PSTL_CPP14_2RANGE_MISMATCH_EQUAL_PRESENT \
(__cplusplus >= 201300L || __cpp_lib_robust_nonmodifying_seq_ops == 201304)
# define __PSTL_CPP14_MAKE_REVERSE_ITERATOR_PRESENT \
(__cplusplus >= 201402L || __cpp_lib_make_reverse_iterator == 201402)
# define __PSTL_CPP14_INTEGER_SEQUENCE_PRESENT (__cplusplus >= 201402L)
# define __PSTL_CPP14_VARIABLE_TEMPLATES_PRESENT (__cplusplus >= 201402L)
# if __PSTL_MONOTONIC_PRESENT
# define __PSTL_PRAGMA_SIMD_ORDERED_MONOTONIC(PRM) \
__PSTL_PRAGMA(omp ordered simd monotonic(PRM))
# define __PSTL_PRAGMA_SIMD_ORDERED_MONOTONIC_2ARGS(PRM1, PRM2) \
__PSTL_PRAGMA(omp ordered simd monotonic(PRM1, PRM2))
# else
# define __PSTL_PRAGMA_SIMD_ORDERED_MONOTONIC(PRM)
# define __PSTL_PRAGMA_SIMD_ORDERED_MONOTONIC_2ARGS(PRM1, PRM2)
# endif
// Declaration of reduction functor, where
// NAME - the name of the functor
// OP - type of the callable object with the reduction operation
// omp_in - refers to the local partial result
// omp_out - refers to the final value of the combiner operator
// omp_priv - refers to the private copy of the initial value
// omp_orig - refers to the original variable to be reduced
#define __PSTL_PRAGMA_DECLARE_REDUCTION(NAME, OP) \
__PSTL_PRAGMA(omp declare reduction(NAME : OP : omp_out(omp_in)) initializer(omp_priv = omp_orig))
# define __PSTL_PRAGMA_VECTOR_UNALIGNED
# define __PSTL_USE_NONTEMPORAL_STORES_IF_ALLOWED
# define __PSTL_PRAGMA_LOCATION
# define __PSTL_PRAGMA_MESSAGE_IMPL(x) \
__PSTL_PRAGMA(message(__PSTL_STRING_CONCAT(__PSTL_PRAGMA_LOCATION, x)))
# define __PSTL_PRAGMA_MESSAGE_POLICIES(x) __PSTL_PRAGMA_MESSAGE_IMPL(x)
//Too many warnings in output, switched off
# define __PSTL_PRAGMA_MESSAGE(x)
# if defined(__GLIBCXX__)
# define __PSTL_CPP11_STD_ROTATE_BROKEN \
(__PSTL_GCC_VERSION < 50100) //GCC 5.1 release
# endif
#endif
// End of prewritten config; the settings discovered at configure time follow. // End of prewritten config; the settings discovered at configure time follow.
This source diff could not be displayed because it is too large. You can view the blob instead.
// -*- C++ -*-
//===-- execution_defs.h --------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef __PSTL_execution_policy_defs_H
#define __PSTL_execution_policy_defs_H
#include <type_traits>
namespace __pstl
{
namespace execution
{
inline namespace v1
{
// 2.4, Sequential execution policy
class sequenced_policy
{
public:
// For internal use only
static constexpr std::false_type
__allow_unsequenced()
{
return std::false_type{};
}
static constexpr std::false_type
__allow_vector()
{
return std::false_type{};
}
static constexpr std::false_type
__allow_parallel()
{
return std::false_type{};
}
};
#if __PSTL_USE_PAR_POLICIES
// 2.5, Parallel execution policy
class parallel_policy
{
public:
// For internal use only
static constexpr std::false_type
__allow_unsequenced()
{
return std::false_type{};
}
static constexpr std::false_type
__allow_vector()
{
return std::false_type{};
}
static constexpr std::true_type
__allow_parallel()
{
return std::true_type{};
}
};
// 2.6, Parallel+Vector execution policy
class parallel_unsequenced_policy
{
public:
// For internal use only
static constexpr std::true_type
__allow_unsequenced()
{
return std::true_type{};
}
static constexpr std::true_type
__allow_vector()
{
return std::true_type{};
}
static constexpr std::true_type
__allow_parallel()
{
return std::true_type{};
}
};
#endif
class unsequenced_policy
{
public:
// For internal use only
static constexpr std::true_type
__allow_unsequenced()
{
return std::true_type{};
}
static constexpr std::true_type
__allow_vector()
{
return std::true_type{};
}
static constexpr std::false_type
__allow_parallel()
{
return std::false_type{};
}
};
// 2.8, Execution policy objects
constexpr sequenced_policy seq{};
#if __PSTL_USE_PAR_POLICIES
constexpr parallel_policy par{};
constexpr parallel_unsequenced_policy par_unseq{};
#endif
constexpr unsequenced_policy unseq{};
// 2.3, Execution policy type trait
template <class T>
struct is_execution_policy : std::false_type
{
};
template <>
struct is_execution_policy<sequenced_policy> : std::true_type
{
};
#if __PSTL_USE_PAR_POLICIES
template <>
struct is_execution_policy<parallel_policy> : std::true_type
{
};
template <>
struct is_execution_policy<parallel_unsequenced_policy> : std::true_type
{
};
#endif
template <>
struct is_execution_policy<unsequenced_policy> : std::true_type
{
};
#if __PSTL_CPP14_VARIABLE_TEMPLATES_PRESENT
template <class T>
constexpr bool is_execution_policy_v = is_execution_policy<T>::value;
#endif
} // namespace v1
} // namespace execution
namespace __internal
{
template <class ExecPolicy, class T>
using __enable_if_execution_policy =
typename std::enable_if<__pstl::execution::is_execution_policy<typename std::decay<ExecPolicy>::type>::value,
T>::type;
} // namespace __internal
} // namespace __pstl
#endif /* __PSTL_execution_policy_defs_H */
// -*- C++ -*-
//===-- execution_impl.h --------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef __PSTL_execution_impl_H
#define __PSTL_execution_impl_H
#include <iterator>
#include <type_traits>
#include "execution_defs.h"
namespace __pstl
{
namespace __internal
{
using namespace __pstl::execution;
/* predicate */
template <typename _Tp>
std::false_type __lazy_and(_Tp, std::false_type)
{
return std::false_type{};
};
template <typename _Tp>
inline _Tp
__lazy_and(_Tp __a, std::true_type)
{
return __a;
}
template <typename _Tp>
std::true_type __lazy_or(_Tp, std::true_type)
{
return std::true_type{};
};
template <typename _Tp>
inline _Tp
__lazy_or(_Tp __a, std::false_type)
{
return __a;
}
/* iterator */
template <typename _IteratorType, typename... _OtherIteratorTypes>
struct __is_random_access_iterator
{
static constexpr bool value =
__is_random_access_iterator<_IteratorType>::value && __is_random_access_iterator<_OtherIteratorTypes...>::value;
typedef std::integral_constant<bool, value> type;
};
template <typename _IteratorType>
struct __is_random_access_iterator<_IteratorType>
: std::is_same<typename std::iterator_traits<_IteratorType>::iterator_category, std::random_access_iterator_tag>
{
};
/* policy */
template <typename Policy>
struct __policy_traits
{
};
template <>
struct __policy_traits<sequenced_policy>
{
typedef std::false_type allow_parallel;
typedef std::false_type allow_unsequenced;
typedef std::false_type allow_vector;
};
template <>
struct __policy_traits<unsequenced_policy>
{
typedef std::false_type allow_parallel;
typedef std::true_type allow_unsequenced;
typedef std::true_type allow_vector;
};
#if __PSTL_USE_PAR_POLICIES
template <>
struct __policy_traits<parallel_policy>
{
typedef std::true_type allow_parallel;
typedef std::false_type allow_unsequenced;
typedef std::false_type allow_vector;
};
template <>
struct __policy_traits<parallel_unsequenced_policy>
{
typedef std::true_type allow_parallel;
typedef std::true_type allow_unsequenced;
typedef std::true_type allow_vector;
};
#endif
template <typename _ExecutionPolicy>
using __collector_t = typename __policy_traits<typename std::decay<_ExecutionPolicy>::type>::__collector_type;
template <typename _ExecutionPolicy>
using __allow_vector = typename __policy_traits<typename std::decay<_ExecutionPolicy>::type>::__allow_vector;
template <typename _ExecutionPolicy>
using __allow_unsequenced = typename __policy_traits<typename std::decay<_ExecutionPolicy>::type>::__allow_unsequenced;
template <typename _ExecutionPolicy>
using __allow_parallel = typename __policy_traits<typename std::decay<_ExecutionPolicy>::type>::__allow_parallel;
template <typename _ExecutionPolicy, typename... _IteratorTypes>
auto
__is_vectorization_preferred(_ExecutionPolicy&& __exec)
-> decltype(__lazy_and(__exec.__allow_vector(), typename __is_random_access_iterator<_IteratorTypes...>::type()))
{
return __lazy_and(__exec.__allow_vector(), typename __is_random_access_iterator<_IteratorTypes...>::type());
}
template <typename _ExecutionPolicy, typename... _IteratorTypes>
auto
__is_parallelization_preferred(_ExecutionPolicy&& __exec)
-> decltype(__lazy_and(__exec.__allow_parallel(), typename __is_random_access_iterator<_IteratorTypes...>::type()))
{
return __lazy_and(__exec.__allow_parallel(), typename __is_random_access_iterator<_IteratorTypes...>::type());
}
template <typename policy, typename... _IteratorTypes>
struct __prefer_unsequenced_tag
{
static constexpr bool value =
__allow_unsequenced<policy>::value && __is_random_access_iterator<_IteratorTypes...>::value;
typedef std::integral_constant<bool, value> type;
};
template <typename policy, typename... _IteratorTypes>
struct __prefer_parallel_tag
{
static constexpr bool value =
__allow_parallel<policy>::value && __is_random_access_iterator<_IteratorTypes...>::value;
typedef std::integral_constant<bool, value> type;
};
} // namespace __internal
} // namespace __pstl
#endif /* __PSTL_execution_impl_H */
// -*- C++ -*-
//===-- glue_execution_defs.h ---------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef __PSTL_glue_execution_defs_H
#define __PSTL_glue_execution_defs_H
#include <type_traits>
#include "execution_defs.h"
namespace std
{
// Type trait
using __pstl::execution::is_execution_policy;
#if __PSTL_CPP14_VARIABLE_TEMPLATES_PRESENT
#if __INTEL_COMPILER
template <class T>
constexpr bool is_execution_policy_v = is_execution_policy<T>::value;
#else
using __pstl::execution::is_execution_policy_v;
#endif
#endif
namespace execution
{
// Standard C++ policy classes
using __pstl::execution::sequenced_policy;
#if __PSTL_USE_PAR_POLICIES
using __pstl::execution::parallel_policy;
using __pstl::execution::parallel_unsequenced_policy;
#endif
// Standard predefined policy instances
using __pstl::execution::seq;
#if __PSTL_USE_PAR_POLICIES
using __pstl::execution::par;
using __pstl::execution::par_unseq;
#endif
// Implementation-defined names
// Unsequenced policy is not yet standard, but for consistency
// we include it into namespace std::execution as well
using __pstl::execution::unseq;
using __pstl::execution::unsequenced_policy;
} // namespace execution
} // namespace std
#include "algorithm_impl.h"
#include "numeric_impl.h"
#include "parallel_backend.h"
#endif /* __PSTL_glue_execution_defs_H */
// -*- C++ -*-
//===-- glue_memory_defs.h ------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef __PSTL_glue_memory_defs_H
#define __PSTL_glue_memory_defs_H
#include "execution_defs.h"
namespace std
{
// [uninitialized.copy]
template <class _ExecutionPolicy, class _InputIterator, class _ForwardIterator>
__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
uninitialized_copy(_ExecutionPolicy&& __exec, _InputIterator __first, _InputIterator __last, _ForwardIterator __result);
template <class _ExecutionPolicy, class _InputIterator, class _Size, class _ForwardIterator>
__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
uninitialized_copy_n(_ExecutionPolicy&& __exec, _InputIterator __first, _Size __n, _ForwardIterator __result);
// [uninitialized.move]
template <class _ExecutionPolicy, class _InputIterator, class _ForwardIterator>
__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
uninitialized_move(_ExecutionPolicy&& __exec, _InputIterator __first, _InputIterator __last, _ForwardIterator __result);
template <class _ExecutionPolicy, class _InputIterator, class _Size, class _ForwardIterator>
__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
uninitialized_move_n(_ExecutionPolicy&& __exec, _InputIterator __first, _Size __n, _ForwardIterator __result);
// [uninitialized.fill]
template <class _ExecutionPolicy, class _ForwardIterator, class _Tp>
__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
uninitialized_fill(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value);
template <class _ExecutionPolicy, class _ForwardIterator, class _Size, class _Tp>
__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
uninitialized_fill_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Size __n, const _Tp& __value);
// [specialized.destroy]
template <class _ExecutionPolicy, class _ForwardIterator>
__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
destroy(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last);
template <class _ExecutionPolicy, class _ForwardIterator, class _Size>
__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
destroy_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Size __n);
// [uninitialized.construct.default]
template <class _ExecutionPolicy, class _ForwardIterator>
__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
uninitialized_default_construct(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last);
template <class _ExecutionPolicy, class _ForwardIterator, class _Size>
__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
uninitialized_default_construct_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Size __n);
// [uninitialized.construct.value]
template <class _ExecutionPolicy, class _ForwardIterator>
__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
uninitialized_value_construct(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last);
template <class _ExecutionPolicy, class _ForwardIterator, class _Size>
__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
uninitialized_value_construct_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Size __n);
} // namespace std
#endif /* __PSTL_glue_memory_defs_H */
// -*- C++ -*-
//===-- glue_numeric_defs.h -----------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef __PSTL_glue_numeric_defs_H
#define __PSTL_glue_numeric_defs_H
#include "execution_defs.h"
namespace std
{
// [reduce]
template <class _ExecutionPolicy, class _ForwardIterator, class _Tp, class _BinaryOperation>
__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _Tp>
reduce(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Tp __init,
_BinaryOperation __binary_op);
template <class _ExecutionPolicy, class _ForwardIterator, class _Tp>
__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _Tp>
reduce(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Tp __init);
template <class _ExecutionPolicy, class _ForwardIterator>
__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy,
typename iterator_traits<_ForwardIterator>::value_type>
reduce(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last);
template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Tp>
__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _Tp>
transform_reduce(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1,
_ForwardIterator2 __first2, _Tp __init);
template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Tp, class _BinaryOperation1,
class _BinaryOperation2>
__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _Tp>
transform_reduce(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1,
_ForwardIterator2 __first2, _Tp __init, _BinaryOperation1 __binary_op1,
_BinaryOperation2 __binary_op2);
template <class _ExecutionPolicy, class _ForwardIterator, class _Tp, class _BinaryOperation, class _UnaryOperation>
__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _Tp>
transform_reduce(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Tp __init,
_BinaryOperation __binary_op, _UnaryOperation __unary_op);
// [exclusive.scan]
template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Tp>
__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2>
exclusive_scan(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last,
_ForwardIterator2 __result, _Tp __init);
template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Tp, class _BinaryOperation>
_ForwardIterator2
exclusive_scan(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last,
_ForwardIterator2 __result, _Tp __init, _BinaryOperation __binary_op);
// [inclusive.scan]
template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2>
inclusive_scan(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last,
_ForwardIterator2 __result);
template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryOperation>
__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2>
inclusive_scan(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last,
_ForwardIterator2 __result, _BinaryOperation __binary_op);
template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Tp, class _BinaryOperation>
__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2>
inclusive_scan(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last,
_ForwardIterator2 __result, _BinaryOperation __binary_op, _Tp __init);
// [transform.exclusive.scan]
template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Tp, class _BinaryOperation,
class _UnaryOperation>
__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2>
transform_exclusive_scan(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last,
_ForwardIterator2 __result, _Tp __init, _BinaryOperation __binary_op,
_UnaryOperation __unary_op);
// [transform.inclusive.scan]
template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryOperation,
class _UnaryOperation, class _Tp>
__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2>
transform_inclusive_scan(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last,
_ForwardIterator2 __result, _BinaryOperation __binary_op, _UnaryOperation __unary_op,
_Tp __init);
template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _UnaryOperation,
class _BinaryOperation>
__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2>
transform_inclusive_scan(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last,
_ForwardIterator2 __result, _BinaryOperation __binary_op, _UnaryOperation __unary_op);
// [adjacent.difference]
template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryOperation>
__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2>
adjacent_difference(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last,
_ForwardIterator2 __d_first, _BinaryOperation op);
template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2>
adjacent_difference(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last,
_ForwardIterator2 __d_first);
} // namespace std
#endif /* __PSTL_glue_numeric_defs_H */
// -*- C++ -*-
//===-- memory_impl.h -----------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef __PSTL_memory_impl_H
#define __PSTL_memory_impl_H
#include <iterator>
#include "unseq_backend_simd.h"
namespace __pstl
{
namespace __internal
{
//------------------------------------------------------------------------
// uninitialized_move
//------------------------------------------------------------------------
template <class _ForwardIterator, class _OutputIterator>
_OutputIterator
__brick_uninitialized_move(_ForwardIterator __first, _ForwardIterator __last, _OutputIterator __result,
/*vector=*/std::false_type) noexcept
{
typedef typename std::iterator_traits<_OutputIterator>::value_type _ValueType2;
for (; __first != __last; ++__first, ++__result)
{
::new (std::addressof(*__result)) _ValueType2(std::move(*__first));
}
return __result;
}
template <class _ForwardIterator, class _OutputIterator>
_OutputIterator
__brick_uninitialized_move(_ForwardIterator __first, _ForwardIterator __last, _OutputIterator __result,
/*vector=*/std::true_type) noexcept
{
typedef typename std::iterator_traits<_OutputIterator>::value_type __ValueType2;
typedef typename std::iterator_traits<_ForwardIterator>::reference _ReferenceType1;
typedef typename std::iterator_traits<_OutputIterator>::reference _ReferenceType2;
return __unseq_backend::__simd_walk_2(
__first, __last - __first, __result,
[](_ReferenceType1 __x, _ReferenceType2 __y) { ::new (std::addressof(__y)) __ValueType2(std::move(__x)); });
}
} // namespace __internal
} // namespace __pstl
#endif /* __PSTL_memory_impl_H */
// -*- C++ -*-
//===-- numeric_fwd.h --------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef __PSTL_numeric_fwd_H
#define __PSTL_numeric_fwd_H
#include <type_traits>
#include <utility>
namespace __pstl
{
namespace __internal
{
//------------------------------------------------------------------------
// transform_reduce (version with two binary functions, according to draft N4659)
//------------------------------------------------------------------------
template <class _ForwardIterator1, class _ForwardIterator2, class _Tp, class _BinaryOperation1, class _BinaryOperation2>
_Tp __brick_transform_reduce(_ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _Tp, _BinaryOperation1,
_BinaryOperation2,
/*__is_vector=*/std::true_type) noexcept;
template <class _ForwardIterator1, class _ForwardIterator2, class _Tp, class _BinaryOperation1, class _BinaryOperation2>
_Tp __brick_transform_reduce(_ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _Tp, _BinaryOperation1,
_BinaryOperation2,
/*__is_vector=*/std::false_type) noexcept;
template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Tp, class _BinaryOperation1,
class _BinaryOperation2, class _IsVector>
_Tp
__pattern_transform_reduce(_ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _Tp,
_BinaryOperation1, _BinaryOperation2, _IsVector,
/*is_parallel=*/std::false_type) noexcept;
#if __PSTL_USE_PAR_POLICIES
template <class _ExecutionPolicy, class _RandomAccessIterator1, class _RandomAccessIterator2, class _Tp,
class _BinaryOperation1, class _BinaryOperation2, class _IsVector>
_Tp
__pattern_transform_reduce(_ExecutionPolicy&&, _RandomAccessIterator1, _RandomAccessIterator1, _RandomAccessIterator2,
_Tp, _BinaryOperation1, _BinaryOperation2, _IsVector __is_vector,
/*is_parallel=*/std::true_type);
#endif
//------------------------------------------------------------------------
// transform_reduce (version with unary and binary functions)
//------------------------------------------------------------------------
template <class _ForwardIterator, class _Tp, class _UnaryOperation, class _BinaryOperation>
_Tp __brick_transform_reduce(_ForwardIterator, _ForwardIterator, _Tp, _BinaryOperation, _UnaryOperation,
/*is_vector=*/std::true_type) noexcept;
template <class _ForwardIterator, class _Tp, class _BinaryOperation, class _UnaryOperation>
_Tp __brick_transform_reduce(_ForwardIterator, _ForwardIterator, _Tp, _BinaryOperation, _UnaryOperation,
/*is_vector=*/std::false_type) noexcept;
template <class _ExecutionPolicy, class _ForwardIterator, class _Tp, class _BinaryOperation, class _UnaryOperation,
class _IsVector>
_Tp
__pattern_transform_reduce(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Tp, _BinaryOperation,
_UnaryOperation, _IsVector,
/*is_parallel=*/std::false_type) noexcept;
#if __PSTL_USE_PAR_POLICIES
template <class _ExecutionPolicy, class _ForwardIterator, class _Tp, class _BinaryOperation, class _UnaryOperation,
class _IsVector>
_Tp
__pattern_transform_reduce(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Tp, _BinaryOperation,
_UnaryOperation, _IsVector,
/*is_parallel=*/std::true_type);
#endif
//------------------------------------------------------------------------
// transform_exclusive_scan
//
// walk3 evaluates f(x,y,z) for (x,y,z) drawn from [first1,last1), [first2,...), [first3,...)
//------------------------------------------------------------------------
template <class _ForwardIterator, class _OutputIterator, class _UnaryOperation, class _Tp, class _BinaryOperation>
std::pair<_OutputIterator, _Tp> __brick_transform_scan(_ForwardIterator, _ForwardIterator, _OutputIterator,
_UnaryOperation, _Tp, _BinaryOperation,
/*Inclusive*/ std::false_type) noexcept;
template <class _ForwardIterator, class _OutputIterator, class _UnaryOperation, class _Tp, class _BinaryOperation>
std::pair<_OutputIterator, _Tp> __brick_transform_scan(_ForwardIterator, _ForwardIterator, _OutputIterator,
_UnaryOperation, _Tp, _BinaryOperation,
/*Inclusive*/ std::true_type) noexcept;
template <class _ExecutionPolicy, class _ForwardIterator, class _OutputIterator, class _UnaryOperation, class _Tp,
class _BinaryOperation, class _Inclusive, class _IsVector>
_OutputIterator
__pattern_transform_scan(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _OutputIterator, _UnaryOperation, _Tp,
_BinaryOperation, _Inclusive, _IsVector,
/*is_parallel=*/std::false_type) noexcept;
#if __PSTL_USE_PAR_POLICIES
template <class _ExecutionPolicy, class _RandomAccessIterator, class _OutputIterator, class _UnaryOperation, class _Tp,
class _BinaryOperation, class _Inclusive, class _IsVector>
typename std::enable_if<!std::is_floating_point<_Tp>::value, _OutputIterator>::type
__pattern_transform_scan(_ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _OutputIterator,
_UnaryOperation, _Tp, _BinaryOperation, _Inclusive, _IsVector, /*is_parallel=*/std::true_type);
#endif
#if __PSTL_USE_PAR_POLICIES
template <class _ExecutionPolicy, class _RandomAccessIterator, class _OutputIterator, class _UnaryOperation, class _Tp,
class _BinaryOperation, class _Inclusive, class _IsVector>
typename std::enable_if<std::is_floating_point<_Tp>::value, _OutputIterator>::type
__pattern_transform_scan(_ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _OutputIterator,
_UnaryOperation, _Tp, _BinaryOperation, _Inclusive, _IsVector, /*is_parallel=*/std::true_type);
#endif
//------------------------------------------------------------------------
// adjacent_difference
//------------------------------------------------------------------------
template <class _ForwardIterator, class _OutputIterator, class _BinaryOperation>
_OutputIterator __brick_adjacent_difference(_ForwardIterator, _ForwardIterator, _OutputIterator, _BinaryOperation,
/*is_vector*/ std::false_type) noexcept;
template <class _ForwardIterator, class _OutputIterator, class _BinaryOperation>
_OutputIterator __brick_adjacent_difference(_ForwardIterator, _ForwardIterator, _OutputIterator, _BinaryOperation,
/*is_vector*/ std::true_type) noexcept;
template <class _ExecutionPolicy, class _ForwardIterator, class _OutputIterator, class _BinaryOperation,
class _IsVector>
_OutputIterator
__pattern_adjacent_difference(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _OutputIterator, _BinaryOperation,
_IsVector, /*is_parallel*/ std::false_type) noexcept;
#if __PSTL_USE_PAR_POLICIES
template <class _ExecutionPolicy, class _ForwardIterator, class _OutputIterator, class _BinaryOperation,
class _IsVector>
_OutputIterator
__pattern_adjacent_difference(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _OutputIterator, _BinaryOperation,
_IsVector, /*is_parallel*/ std::true_type);
#endif
} // namespace __internal
} // namespace __pstl
#endif /* __PSTL_numeric_fwd_H */
// -*- C++ -*-
//===-- parallel_backend.h ------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef __PSTL_parallel_backend_H
#define __PSTL_parallel_backend_H
#if __PSTL_PAR_BACKEND_TBB
#include "parallel_backend_tbb.h"
#else
__PSTL_PRAGMA_MESSAGE("Parallel backend was not specified");
#endif
#endif /* __PSTL_parallel_backend_H */
// -*- C++ -*-
//===-- parallel_backend_utils.h ------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef __PSTL_parallel_backend_utils_H
#define __PSTL_parallel_backend_utils_H
#include <iterator>
#include <utility>
#include "utils.h"
namespace __pstl
{
namespace __par_backend
{
//! Destroy sequence [xs,xe)
struct __serial_destroy
{
template <typename _RandomAccessIterator>
void
operator()(_RandomAccessIterator __zs, _RandomAccessIterator __ze)
{
typedef typename std::iterator_traits<_RandomAccessIterator>::value_type _ValueType;
while (__zs != __ze)
{
--__ze;
(*__ze).~_ValueType();
}
}
};
//! Merge sequences [__xs,__xe) and [__ys,__ye) to output sequence [__zs,(__xe-__xs)+(__ye-__ys)), using std::move
template <class _MoveValues, class _MoveSequences>
struct __serial_move_merge
{
const std::size_t _M_nmerge;
_MoveValues _M_move_values;
_MoveSequences _M_move_sequences;
explicit __serial_move_merge(std::size_t __nmerge, _MoveValues __move_values, _MoveSequences __move_sequences)
: _M_nmerge(__nmerge), _M_move_values(__move_values), _M_move_sequences(__move_sequences)
{
}
template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _RandomAccessIterator3, class _Compare>
void
operator()(_RandomAccessIterator1 __xs, _RandomAccessIterator1 __xe, _RandomAccessIterator2 __ys,
_RandomAccessIterator2 __ye, _RandomAccessIterator3 __zs, _Compare __comp)
{
auto __n = _M_nmerge;
assert(__n > 0);
if (__xs != __xe)
{
if (__ys != __ye)
{
for (;;)
{
if (__comp(*__ys, *__xs))
{
_M_move_values(__ys, __zs);
++__zs, --__n;
if (++__ys == __ye)
{
break;
}
else if (__n == 0)
{
__zs = _M_move_sequences(__ys, __ye, __zs);
break;
}
else
{
}
}
else
{
_M_move_values(__xs, __zs);
++__zs, --__n;
if (++__xs == __xe)
{
_M_move_sequences(__ys, __ye, __zs);
return;
}
else if (__n == 0)
{
__zs = _M_move_sequences(__xs, __xe, __zs);
_M_move_sequences(__ys, __ye, __zs);
return;
}
else
{
}
}
}
}
__ys = __xs;
__ye = __xe;
}
_M_move_sequences(__ys, __ye, __zs);
}
};
template <typename _RandomAccessIterator1, typename _OutputIterator>
void
__init_buf(_RandomAccessIterator1 __xs, _RandomAccessIterator1 __xe, _OutputIterator __zs, bool __bMove)
{
const _OutputIterator __ze = __zs + (__xe - __xs);
typedef typename std::iterator_traits<_OutputIterator>::value_type _ValueType;
if (__bMove)
{
// Initialize the temporary buffer and move keys to it.
for (; __zs != __ze; ++__xs, ++__zs)
new (&*__zs) _ValueType(std::move(*__xs));
}
else
{
// Initialize the temporary buffer
for (; __zs != __ze; ++__zs)
new (&*__zs) _ValueType;
}
}
// TODO is this actually used anywhere?
template <typename _Buf>
class __stack
{
typedef typename std::iterator_traits<decltype(_Buf(0).get())>::value_type _ValueType;
typedef typename std::iterator_traits<_ValueType*>::difference_type _DifferenceType;
_Buf _M_buf;
_ValueType* _M_ptr;
_DifferenceType _M_maxsize;
__stack(const __stack&) = delete;
void
operator=(const __stack&) = delete;
public:
__stack(_DifferenceType __max_size) : _M_buf(__max_size), _M_maxsize(__max_size) { _M_ptr = _M_buf.get(); }
~__stack()
{
assert(size() <= _M_maxsize);
while (!empty())
pop();
}
const _Buf&
buffer() const
{
return _M_buf;
}
size_t
size() const
{
assert(_M_ptr - _M_buf.get() <= _M_maxsize);
assert(_M_ptr - _M_buf.get() >= 0);
return _M_ptr - _M_buf.get();
}
bool
empty() const
{
assert(_M_ptr >= _M_buf.get());
return _M_ptr == _M_buf.get();
}
void
push(const _ValueType& __v)
{
assert(size() < _M_maxsize);
new (_M_ptr) _ValueType(__v);
++_M_ptr;
}
const _ValueType&
top() const
{
return *(_M_ptr - 1);
}
void
pop()
{
assert(_M_ptr > _M_buf.get());
--_M_ptr;
(*_M_ptr).~_ValueType();
}
};
} // namespace __par_backend
} // namespace __pstl
#endif /* __PSTL_parallel_backend_utils_H */
// -*- C++ -*-
//===-- parallel_impl.h ---------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef __PSTL_parallel_impl_H
#define __PSTL_parallel_impl_H
#include <atomic>
// This header defines the minimum set of parallel routines required to support Parallel STL,
// implemented on top of Intel(R) Threading Building Blocks (Intel(R) TBB) library
namespace __pstl
{
namespace __internal
{
//------------------------------------------------------------------------
// parallel_find
//-----------------------------------------------------------------------
/** Return extremum value returned by brick f[i,j) for subranges [i,j) of [first,last)
Each f[i,j) must return a value in [i,j). */
template <class _ExecutionPolicy, class _Index, class _Brick, class _Compare>
_Index
__parallel_find(_ExecutionPolicy&& __exec, _Index __first, _Index __last, _Brick __f, _Compare __comp, bool __b_first)
{
typedef typename std::iterator_traits<_Index>::difference_type _DifferenceType;
const _DifferenceType __n = __last - __first;
_DifferenceType __initial_dist = __b_first ? __n : -1;
std::atomic<_DifferenceType> __extremum(__initial_dist);
// TODO: find out what is better here: parallel_for or parallel_reduce
__par_backend::__parallel_for(std::forward<_ExecutionPolicy>(__exec), __first, __last,
[__comp, __f, __first, &__extremum](_Index __i, _Index __j) {
// See "Reducing Contention Through Priority Updates", PPoPP '13, for discussion of
// why using a shared variable scales fairly well in this situation.
if (__comp(__i - __first, __extremum))
{
_Index __res = __f(__i, __j);
// If not '__last' returned then we found what we want so put this to extremum
if (__res != __j)
{
const _DifferenceType __k = __res - __first;
for (_DifferenceType __old = __extremum; __comp(__k, __old);
__old = __extremum)
{
__extremum.compare_exchange_weak(__old, __k);
}
}
}
});
return __extremum != __initial_dist ? __first + __extremum : __last;
}
//------------------------------------------------------------------------
// parallel_or
//------------------------------------------------------------------------
//! Return true if brick f[i,j) returns true for some subrange [i,j) of [first,last)
template <class _ExecutionPolicy, class _Index, class _Brick>
bool
__parallel_or(_ExecutionPolicy&& __exec, _Index __first, _Index __last, _Brick __f)
{
std::atomic<bool> __found(false);
__par_backend::__parallel_for(std::forward<_ExecutionPolicy>(__exec), __first, __last,
[__f, &__found](_Index __i, _Index __j) {
if (!__found.load(std::memory_order_relaxed) && __f(__i, __j))
{
__found.store(true, std::memory_order_relaxed);
__par_backend::__cancel_execution();
}
});
return __found;
}
} // namespace __internal
} // namespace __pstl
#endif /* __PSTL_parallel_impl_H */
// -*- C++ -*-
//===-- pstl_config.h -----------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef __PSTL_config_H
#define __PSTL_config_H
#define PSTL_VERSION 203
#define PSTL_VERSION_MAJOR (PSTL_VERSION / 100)
#define PSTL_VERSION_MINOR (PSTL_VERSION - PSTL_VERSION_MAJOR * 100)
// Check the user-defined macro for parallel policies
#if defined(PSTL_USE_PARALLEL_POLICIES)
#undef __PSTL_USE_PAR_POLICIES
#define __PSTL_USE_PAR_POLICIES PSTL_USE_PARALLEL_POLICIES
// Check the internal macro for parallel policies
#elif !defined(__PSTL_USE_PAR_POLICIES)
#define __PSTL_USE_PAR_POLICIES 1
#endif
#if __PSTL_USE_PAR_POLICIES
#if !defined(__PSTL_PAR_BACKEND_TBB)
#define __PSTL_PAR_BACKEND_TBB 1
#endif
#else
#undef __PSTL_PAR_BACKEND_TBB
#endif
// Check the user-defined macro for warnings
#if defined(PSTL_USAGE_WARNINGS)
#undef __PSTL_USAGE_WARNINGS
#define __PSTL_USAGE_WARNINGS PSTL_USAGE_WARNINGS
// Check the internal macro for warnings
#elif !defined(__PSTL_USAGE_WARNINGS)
#define __PSTL_USAGE_WARNINGS 0
#endif
// Portability "#pragma" definition
#ifdef _MSC_VER
#define __PSTL_PRAGMA(x) __pragma(x)
#else
#define __PSTL_PRAGMA(x) _Pragma(#x)
#endif
#define __PSTL_STRING_AUX(x) #x
#define __PSTL_STRING(x) __PSTL_STRING_AUX(x)
#define __PSTL_STRING_CONCAT(x, y) x #y
// note that when ICC or Clang is in use, __PSTL_GCC_VERSION might not fully match
// the actual GCC version on the system.
#define __PSTL_GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
#if __clang__
// according to clang documentation, version can be vendor specific
#define __PSTL_CLANG_VERSION (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__)
#endif
// Enable SIMD for compilers that support OpenMP 4.0
#if (_OPENMP >= 201307) || (__INTEL_COMPILER >= 1600) || (!defined(__INTEL_COMPILER) && __PSTL_GCC_VERSION >= 40900)
#define __PSTL_PRAGMA_SIMD __PSTL_PRAGMA(omp simd)
#define __PSTL_PRAGMA_DECLARE_SIMD __PSTL_PRAGMA(omp declare simd)
#define __PSTL_PRAGMA_SIMD_REDUCTION(PRM) __PSTL_PRAGMA(omp simd reduction(PRM))
#elif !defined(_MSC_VER) //#pragma simd
#define __PSTL_PRAGMA_SIMD __PSTL_PRAGMA(simd)
#define __PSTL_PRAGMA_DECLARE_SIMD
#define __PSTL_PRAGMA_SIMD_REDUCTION(PRM) __PSTL_PRAGMA(simd reduction(PRM))
#else //no simd
#define __PSTL_PRAGMA_SIMD
#define __PSTL_PRAGMA_DECLARE_SIMD
#define __PSTL_PRAGMA_SIMD_REDUCTION(PRM)
#endif //Enable SIMD
#if (__INTEL_COMPILER)
#define __PSTL_PRAGMA_FORCEINLINE __PSTL_PRAGMA(forceinline)
#else
#define __PSTL_PRAGMA_FORCEINLINE
#endif
#if (__INTEL_COMPILER >= 1900)
#define __PSTL_PRAGMA_SIMD_SCAN(PRM) __PSTL_PRAGMA(omp simd reduction(inscan, PRM))
#define __PSTL_PRAGMA_SIMD_INCLUSIVE_SCAN(PRM) __PSTL_PRAGMA(omp scan inclusive(PRM))
#define __PSTL_PRAGMA_SIMD_EXCLUSIVE_SCAN(PRM) __PSTL_PRAGMA(omp scan exclusive(PRM))
#else
#define __PSTL_PRAGMA_SIMD_SCAN(PRM)
#define __PSTL_PRAGMA_SIMD_INCLUSIVE_SCAN(PRM)
#define __PSTL_PRAGMA_SIMD_EXCLUSIVE_SCAN(PRM)
#endif
// Should be defined to 1 for environments with a vendor implementation of C++17 execution policies
#define __PSTL_CPP17_EXECUTION_POLICIES_PRESENT (_MSC_VER >= 1912)
#define __PSTL_CPP14_2RANGE_MISMATCH_EQUAL_PRESENT \
(_MSC_VER >= 1900 || __cplusplus >= 201300L || __cpp_lib_robust_nonmodifying_seq_ops == 201304)
#define __PSTL_CPP14_MAKE_REVERSE_ITERATOR_PRESENT \
(_MSC_VER >= 1900 || __cplusplus >= 201402L || __cpp_lib_make_reverse_iterator == 201402)
#define __PSTL_CPP14_INTEGER_SEQUENCE_PRESENT (_MSC_VER >= 1900 || __cplusplus >= 201402L)
#define __PSTL_CPP14_VARIABLE_TEMPLATES_PRESENT \
(!__INTEL_COMPILER || __INTEL_COMPILER >= 1700) && (_MSC_FULL_VER >= 190023918 || __cplusplus >= 201402L)
#define __PSTL_EARLYEXIT_PRESENT (__INTEL_COMPILER >= 1800)
#define __PSTL_MONOTONIC_PRESENT (__INTEL_COMPILER >= 1800)
#if (__INTEL_COMPILER >= 1900 || !defined(__INTEL_COMPILER) && __PSTL_GCC_VERSION >= 40900 || _OPENMP >= 201307)
#define __PSTL_UDR_PRESENT 1
#else
#define __PSTL_UDR_PRESENT 0
#endif
#define __PSTL_UDS_PRESENT (__INTEL_COMPILER >= 1900 && __INTEL_COMPILER_BUILD_DATE >= 20180626)
#if __PSTL_EARLYEXIT_PRESENT
#define __PSTL_PRAGMA_SIMD_EARLYEXIT __PSTL_PRAGMA(omp simd early_exit)
#else
#define __PSTL_PRAGMA_SIMD_EARLYEXIT
#endif
#if __PSTL_MONOTONIC_PRESENT
#define __PSTL_PRAGMA_SIMD_ORDERED_MONOTONIC(PRM) __PSTL_PRAGMA(omp ordered simd monotonic(PRM))
#define __PSTL_PRAGMA_SIMD_ORDERED_MONOTONIC_2ARGS(PRM1, PRM2) __PSTL_PRAGMA(omp ordered simd monotonic(PRM1, PRM2))
#else
#define __PSTL_PRAGMA_SIMD_ORDERED_MONOTONIC(PRM)
#define __PSTL_PRAGMA_SIMD_ORDERED_MONOTONIC_2ARGS(PRM1, PRM2)
#endif
// Declaration of reduction functor, where
// NAME - the name of the functor
// OP - type of the callable object with the reduction operation
// omp_in - refers to the local partial result
// omp_out - refers to the final value of the combiner operator
// omp_priv - refers to the private copy of the initial value
// omp_orig - refers to the original variable to be reduced
#define __PSTL_PRAGMA_DECLARE_REDUCTION(NAME, OP) \
__PSTL_PRAGMA(omp declare reduction(NAME : OP : omp_out(omp_in)) initializer(omp_priv = omp_orig))
#if (__INTEL_COMPILER >= 1600)
#define __PSTL_PRAGMA_VECTOR_UNALIGNED __PSTL_PRAGMA(vector unaligned)
#else
#define __PSTL_PRAGMA_VECTOR_UNALIGNED
#endif
// Check the user-defined macro to use non-temporal stores
#if defined(PSTL_USE_NONTEMPORAL_STORES) && (__INTEL_COMPILER >= 1600)
#define __PSTL_USE_NONTEMPORAL_STORES_IF_ALLOWED __PSTL_PRAGMA(vector nontemporal)
#else
#define __PSTL_USE_NONTEMPORAL_STORES_IF_ALLOWED
#endif
#if _MSC_VER || __INTEL_COMPILER //the preprocessors don't type a message location
#define __PSTL_PRAGMA_LOCATION __FILE__ ":" __PSTL_STRING(__LINE__) ": [Parallel STL message]: "
#else
#define __PSTL_PRAGMA_LOCATION " [Parallel STL message]: "
#endif
#define __PSTL_PRAGMA_MESSAGE_IMPL(x) __PSTL_PRAGMA(message(__PSTL_STRING_CONCAT(__PSTL_PRAGMA_LOCATION, x)))
#if __PSTL_USAGE_WARNINGS
#define __PSTL_PRAGMA_MESSAGE(x) __PSTL_PRAGMA_MESSAGE_IMPL(x)
#define __PSTL_PRAGMA_MESSAGE_POLICIES(x) __PSTL_PRAGMA_MESSAGE_IMPL(x)
#else
#define __PSTL_PRAGMA_MESSAGE(x)
#define __PSTL_PRAGMA_MESSAGE_POLICIES(x)
#endif
// broken macros
#define __PSTL_CPP11_STD_ROTATE_BROKEN ((__GLIBCXX__ && __GLIBCXX__ < 20150716) || (_MSC_VER && _MSC_VER < 1800))
#define __PSTL_ICC_18_OMP_SIMD_BROKEN (__INTEL_COMPILER == 1800)
#endif /* __PSTL_config_H */
// -*- C++ -*-
//===-- utils.h -----------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef __PSTL_utils_H
#define __PSTL_utils_H
#include <new>
#include <iterator>
namespace __pstl
{
namespace __internal
{
template <typename _Fp>
typename std::result_of<_Fp()>::type
__except_handler(_Fp __f)
{
try
{
return __f();
}
catch (const std::bad_alloc&)
{
throw; // re-throw bad_alloc according to the standard [algorithms.parallel.exceptions]
}
catch (...)
{
std::terminate(); // Good bye according to the standard [algorithms.parallel.exceptions]
}
}
template <typename _Fp>
void
__invoke_if(std::true_type, _Fp __f)
{
__f();
}
template <typename _Fp>
void
__invoke_if(std::false_type, _Fp __f)
{
}
template <typename _Fp>
void
__invoke_if_not(std::false_type, _Fp __f)
{
__f();
}
template <typename _Fp>
void
__invoke_if_not(std::true_type, _Fp __f)
{
}
template <typename _F1, typename _F2>
typename std::result_of<_F1()>::type
__invoke_if_else(std::true_type, _F1 __f1, _F2 __f2)
{
return __f1();
}
template <typename _F1, typename _F2>
typename std::result_of<_F2()>::type
__invoke_if_else(std::false_type, _F1 __f1, _F2 __f2)
{
return __f2();
}
//! Unary operator that returns reference to its argument.
struct __no_op
{
template <typename _Tp>
_Tp&&
operator()(_Tp&& __a) const
{
return std::forward<_Tp>(__a);
}
};
//! Logical negation of a predicate
template <typename _Pred>
class __not_pred
{
_Pred _M_pred;
public:
explicit __not_pred(_Pred __pred) : _M_pred(__pred) {}
template <typename... _Args>
bool
operator()(_Args&&... __args)
{
return !_M_pred(std::forward<_Args>(__args)...);
}
};
template <typename _Pred>
class __reorder_pred
{
_Pred _M_pred;
public:
explicit __reorder_pred(_Pred __pred) : _M_pred(__pred) {}
template <typename _FTp, typename _STp>
bool
operator()(_FTp&& __a, _STp&& __b)
{
return _M_pred(std::forward<_STp>(__b), std::forward<_FTp>(__a));
}
};
//! "==" comparison.
/** Not called "equal" to avoid (possibly unfounded) concerns about accidental invocation via
argument-dependent name lookup by code expecting to find the usual std::equal. */
class __pstl_equal
{
public:
explicit __pstl_equal() {}
template <typename _Xp, typename _Yp>
bool
operator()(_Xp&& __x, _Yp&& __y) const
{
return std::forward<_Xp>(__x) == std::forward<_Yp>(__y);
}
};
//! "<" comparison.
class __pstl_less
{
public:
explicit __pstl_less() {}
template <typename _Xp, typename _Yp>
bool
operator()(_Xp&& __x, _Yp&& __y) const
{
return std::forward<_Xp>(__x) < std::forward<_Yp>(__y);
}
};
//! Like a polymorphic lambda for pred(...,value)
template <typename _Tp, typename _Predicate>
class __equal_value_by_pred
{
const _Tp& _M_value;
_Predicate _M_pred;
public:
__equal_value_by_pred(const _Tp& __value, _Predicate __pred) : _M_value(__value), _M_pred(__pred) {}
template <typename _Arg>
bool
operator()(_Arg&& __arg)
{
return _M_pred(std::forward<_Arg>(__arg), _M_value);
}
};
//! Like a polymorphic lambda for ==value
template <typename _Tp>
class __equal_value
{
const _Tp& _M_value;
public:
explicit __equal_value(const _Tp& __value) : _M_value(__value) {}
template <typename _Arg>
bool
operator()(_Arg&& __arg) const
{
return std::forward<_Arg>(__arg) == _M_value;
}
};
//! Logical negation of ==value
template <typename _Tp>
class __not_equal_value
{
const _Tp& _M_value;
public:
explicit __not_equal_value(const _Tp& __value) : _M_value(__value) {}
template <typename _Arg>
bool
operator()(_Arg&& __arg) const
{
return !(std::forward<_Arg>(__arg) == _M_value);
}
};
template <typename _ForwardIterator, typename _Compare>
_ForwardIterator
__cmp_iterators_by_values(_ForwardIterator __a, _ForwardIterator __b, _Compare __comp)
{
if (__a < __b)
{ // we should return closer iterator
return __comp(*__b, *__a) ? __b : __a;
}
else
{
return __comp(*__a, *__b) ? __a : __b;
}
}
} // namespace __internal
} // namespace __pstl
#endif /* __PSTL_utils_H */
...@@ -61,6 +61,21 @@ ...@@ -61,6 +61,21 @@
#include <bits/stl_algobase.h> #include <bits/stl_algobase.h>
#include <bits/stl_algo.h> #include <bits/stl_algo.h>
#if __cplusplus > 201402L
// Parallel STL algorithms
# if __PSTL_EXECUTION_POLICIES_DEFINED
// If <execution> has already been included, pull in implementations
# include <pstl/glue_algorithm_impl.h>
# else
// Otherwise just pull in forward declarations
# include <pstl/glue_algorithm_defs.h>
# define __PSTL_ALGORITHM_FORWARD_DECLARED 1
# endif
// Feature test macro for parallel algorithms
# define __cpp_lib_parallel_algorithm 201703L
#endif // C++17
#ifdef _GLIBCXX_PARALLEL #ifdef _GLIBCXX_PARALLEL
# include <parallel/algorithm> # include <parallel/algorithm>
#endif #endif
......
// <execution> -*- C++ -*-
// Copyright (C) 2018-2019 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
#ifndef _GLIBCXX_EXECUTION
#define _GLIBCXX_EXECUTION 1
#pragma GCC system_header
#if __cplusplus >= 201703L
# include <bits/c++config.h>
# include <pstl/glue_execution_defs.h>
# define __PSTL_EXECUTION_POLICIES_DEFINED 1
// Algorithm implementation
# if __PSTL_ALGORITHM_FORWARD_DECLARED
# include <pstl/glue_algorithm_impl.h>
# endif
// Numeric implementation
# if __PSTL_NUMERIC_FORWARD_DECLARED
# include <pstl/glue_numeric_impl.h>
# endif
// Memory implementation
# if __PSTL_NUMERIC_FORWARD_DECLARED
# include <pstl/glue_memory_impl.h>
# endif
// Feature test macro for parallel algorithms
# define __cpp_lib_parallel_algorithm 201603L
#endif // C++17
#endif /* _GLIBCXX_EXECUTION */
...@@ -363,4 +363,18 @@ _GLIBCXX_END_NAMESPACE_VERSION ...@@ -363,4 +363,18 @@ _GLIBCXX_END_NAMESPACE_VERSION
} // namespace } // namespace
#endif // C++11 #endif // C++11
#if __cplusplus > 201402L
// Parallel STL algorithms
# if __PSTL_EXECUTION_POLICIES_DEFINED
// If <execution> has already been included, pull in implementations
# include <pstl/glue_memory_impl.h>
# else
// Otherwise just pull in forward declarations
# include <pstl/glue_memory_defs.h>
# endif
// Feature test macro for parallel algorithms
# define __cpp_lib_parallel_algorithm 201703L
#endif // C++17
#endif /* _GLIBCXX_MEMORY */ #endif /* _GLIBCXX_MEMORY */
...@@ -205,5 +205,19 @@ _GLIBCXX_END_NAMESPACE_VERSION ...@@ -205,5 +205,19 @@ _GLIBCXX_END_NAMESPACE_VERSION
#endif // C++14 #endif // C++14
#if __cplusplus > 201402L
// Parallel STL algorithms
# if __PSTL_EXECUTION_POLICIES_DEFINED
// If <execution> has already been included, pull in implementations
# include <pstl/glue_numeric_impl.h>
# else
// Otherwise just pull in forward declarations
# include <pstl/glue_numeric_defs.h>
# define __PSTL_NUMERIC_FORWARD_DECLARED 1
# endif
// Feature test macro for parallel algorithms
# define __cpp_lib_parallel_algorithm 201703L
#endif // C++17
#endif /* _GLIBCXX_NUMERIC */ #endif /* _GLIBCXX_NUMERIC */
...@@ -145,6 +145,7 @@ ...@@ -145,6 +145,7 @@
#define __cpp_lib_unordered_map_try_emplace 201411 #define __cpp_lib_unordered_map_try_emplace 201411
#define __cpp_lib_variant 201606L #define __cpp_lib_variant 201606L
#define __cpp_lib_void_t 201411 #define __cpp_lib_void_t 201411
#define __cpp_lib_parallel_algorithm 201603L
#if __cplusplus > 201703L #if __cplusplus > 201703L
// c++2a // c++2a
......
// -*- C++ -*-
// { dg-options "-std=gnu++17 -ltbb" }
// { dg-do run { target c++17 } }
// { dg-require-effective-target tbb-backend }
//===-- uninitialized_construct.pass.cpp ----------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
// Tests for uninitialized_default_construct, uninitialized_default_construct_n,
// uninitialized_value_construct, uninitialized_value_construct_n
#include "pstl/pstl_test_config.h"
#ifdef PSTL_STANDALONE_TESTS
#include "pstl/execution"
#include "pstl/memory"
#else
#include <execution>
#include <memory>
#endif // PSTL_STANDALONE_TESTS
#include "pstl/test_utils.h"
using namespace TestUtils;
// function of checking correctness for uninitialized.construct.value
template <typename T, typename Iterator>
bool
IsCheckValueCorrectness(Iterator begin, Iterator end)
{
for (; begin != end; ++begin)
{
if (*begin != T())
{
return false;
}
}
return true;
}
struct test_uninit_construct
{
template <typename Policy, typename Iterator>
void
operator()(Policy&& exec, Iterator begin, Iterator end, size_t n, /*is_trivial<T>=*/std::false_type)
{
typedef typename std::iterator_traits<Iterator>::value_type T;
// it needs for cleaning memory that was filled by default constructors in unique_ptr<T[]> p(new T[n])
// and for cleaning memory after last calling of uninitialized_value_construct_n.
// It is important for non-trivial types
std::destroy_n(exec, begin, n);
// reset counter of constructors
T::SetCount(0);
// run algorithm
std::uninitialized_default_construct(exec, begin, end);
// compare counter of constructors to length of container
EXPECT_TRUE(T::Count() == n, "wrong uninitialized_default_construct");
// destroy objects for testing new algorithms on same memory
std::destroy(exec, begin, end);
std::uninitialized_default_construct_n(exec, begin, n);
EXPECT_TRUE(T::Count() == n, "wrong uninitialized_default_construct_n");
std::destroy_n(exec, begin, n);
std::uninitialized_value_construct(exec, begin, end);
EXPECT_TRUE(T::Count() == n, "wrong uninitialized_value_construct");
std::destroy(exec, begin, end);
std::uninitialized_value_construct_n(exec, begin, n);
EXPECT_TRUE(T::Count() == n, "wrong uninitialized_value_construct_n");
}
template <typename Policy, typename Iterator>
void
operator()(Policy&& exec, Iterator begin, Iterator end, size_t n, /*is_trivial<T>=*/std::true_type)
{
typedef typename std::iterator_traits<Iterator>::value_type T;
std::uninitialized_default_construct(exec, begin, end);
std::destroy(exec, begin, end);
std::uninitialized_default_construct_n(exec, begin, n);
std::destroy_n(exec, begin, n);
std::uninitialized_value_construct(exec, begin, end);
// check correctness for uninitialized.construct.value
EXPECT_TRUE(IsCheckValueCorrectness<T>(begin, end), "wrong uninitialized_value_construct");
std::destroy(exec, begin, end);
std::uninitialized_value_construct_n(exec, begin, n);
EXPECT_TRUE(IsCheckValueCorrectness<T>(begin, end), "wrong uninitialized_value_construct_n");
std::destroy_n(exec, begin, n);
}
};
template <typename T>
void
test_uninit_construct_by_type()
{
std::size_t N = 100000;
for (size_t n = 0; n <= N; n = n <= 16 ? n + 1 : size_t(3.1415 * n))
{
std::unique_ptr<T[]> p(new T[n]);
invoke_on_all_policies(test_uninit_construct(), p.get(), std::next(p.get(), n), n, std::is_trivial<T>());
}
}
int32_t
main()
{
// for user-defined types
#if !__PSTL_ICC_16_VC14_TEST_PAR_TBB_RT_RELEASE_64_BROKEN
test_uninit_construct_by_type<Wrapper<int32_t>>();
test_uninit_construct_by_type<Wrapper<std::vector<std::string>>>();
#endif
// for trivial types
test_uninit_construct_by_type<int8_t>();
test_uninit_construct_by_type<float64_t>();
std::cout << done() << std::endl;
return 0;
}
// -*- C++ -*-
// { dg-options "-std=gnu++17 -ltbb" }
// { dg-do run { target c++17 } }
// { dg-require-effective-target tbb-backend }
//===-- uninitialized_copy_move.pass.cpp ----------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
// Tests for uninitialized_copy, uninitialized_copy_n, uninitialized_move, uninitialized_move_n
#include "pstl/pstl_test_config.h"
#ifdef PSTL_STANDALONE_TESTS
#include "pstl/execution"
#include "pstl/memory"
#else
#include <execution>
#include <memory>
#endif // PSTL_STANDALONE_TESTS
#include "pstl/test_utils.h"
using namespace TestUtils;
// function of checking correctness for uninitialized.construct.value
template <typename InputIterator, typename OutputIterator, typename Size>
bool
IsCheckValueCorrectness(InputIterator first1, OutputIterator first2, Size n)
{
for (Size i = 0; i < n; ++i, ++first1, ++first2)
{
if (*first1 != *first2)
{
return false;
}
}
return true;
}
struct test_uninitialized_copy_move
{
template <typename Policy, typename InputIterator, typename OutputIterator>
void
operator()(Policy&& exec, InputIterator first, InputIterator last, OutputIterator out_first, size_t n,
/*is_trivial<T>=*/std::false_type)
{
typedef typename std::iterator_traits<InputIterator>::value_type T;
// it needs for cleaning memory that was filled by default constructors in unique_ptr<T[]> p(new T[n])
// and for cleaning memory after last calling of uninitialized_value_construct_n.
// It is important for non-trivial types
std::destroy_n(exec, out_first, n);
// reset counter of constructors
T::SetCount(0);
// run algorithm
std::uninitialized_copy(exec, first, last, out_first);
// compare counter of constructors to length of container
EXPECT_TRUE(T::Count() == n, "wrong uninitialized_copy");
// destroy objects for testing new algorithms on same memory
std::destroy_n(exec, out_first, n);
std::uninitialized_copy_n(exec, first, n, out_first);
EXPECT_TRUE(T::Count() == n, "wrong uninitialized_copy_n");
std::destroy_n(exec, out_first, n);
// For move
std::uninitialized_move(exec, first, last, out_first);
// compare counter of constructors to length of container
EXPECT_TRUE(T::MoveCount() == n, "wrong uninitialized_move");
// destroy objects for testing new algorithms on same memory
std::destroy_n(exec, out_first, n);
std::uninitialized_move_n(exec, first, n, out_first);
EXPECT_TRUE(T::MoveCount() == n, "wrong uninitialized_move_n");
std::destroy_n(exec, out_first, n);
}
#if __PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN || __PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN
template <typename InputIterator, typename OutputIterator>
void
operator()(pstl::execution::unsequenced_policy, InputIterator first, InputIterator last, OutputIterator out_first,
size_t n, /*is_trivial<T>=*/std::true_type)
{
}
template <typename InputIterator, typename OutputIterator>
void
operator()(pstl::execution::parallel_unsequenced_policy, InputIterator first, InputIterator last,
OutputIterator out_first, size_t n, /*is_trivial<T>=*/std::true_type)
{
}
#endif
template <typename Policy, typename InputIterator, typename OutputIterator>
void
operator()(Policy&& exec, InputIterator first, InputIterator last, OutputIterator out_first, size_t n,
/*is_trivial<T>=*/std::true_type)
{
typedef typename std::iterator_traits<InputIterator>::value_type T;
std::uninitialized_copy(exec, first, last, out_first);
EXPECT_TRUE(IsCheckValueCorrectness(first, out_first, n), "wrong uninitialized_copy");
std::destroy_n(exec, out_first, n);
std::uninitialized_copy_n(exec, first, n, out_first);
EXPECT_TRUE(IsCheckValueCorrectness(first, out_first, n), "wrong uninitialized_copy_n");
std::destroy_n(exec, out_first, n);
std::uninitialized_move(exec, first, last, out_first);
EXPECT_TRUE(IsCheckValueCorrectness(first, out_first, n), "wrong uninitialized_move");
std::destroy_n(exec, out_first, n);
std::uninitialized_move_n(exec, first, n, out_first);
EXPECT_TRUE(IsCheckValueCorrectness(first, out_first, n), "wrong uninitialized_move_n");
std::destroy_n(exec, out_first, n);
}
};
template <typename T>
void
test_uninitialized_copy_move_by_type()
{
std::size_t N = 100000;
for (size_t n = 0; n <= N; n = n <= 16 ? n + 1 : size_t(3.1415 * n))
{
Sequence<T> in(n, [=](size_t k) -> T { return T(k); });
std::unique_ptr<T[]> p(new T[n]);
invoke_on_all_policies(test_uninitialized_copy_move(), in.begin(), in.end(), p.get(), n, std::is_trivial<T>());
}
}
int32_t
main()
{
// for trivial types
test_uninitialized_copy_move_by_type<int16_t>();
test_uninitialized_copy_move_by_type<float64_t>();
// for user-defined types
#if !__PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN && !__PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN && \
!__PSTL_ICC_16_VC14_TEST_PAR_TBB_RT_RELEASE_64_BROKEN
test_uninitialized_copy_move_by_type<Wrapper<int8_t>>();
#endif
std::cout << done() << std::endl;
return 0;
}
// -*- C++ -*-
// { dg-options "-std=gnu++17 -ltbb" }
// { dg-do run { target c++17 } }
// { dg-require-effective-target tbb-backend }
//===-- uninitialized_fill_destroy.pass.cpp -------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "pstl/pstl_test_config.h"
#ifdef PSTL_STANDALONE_TESTS
#include "pstl/execution"
#include "pstl/memory"
#include "pstl/algorithm"
#else
#include <execution>
#include <algorithm>
#endif // PSTL_STANDALONE_TESTS
#include "pstl/test_utils.h"
using namespace TestUtils;
struct test_uninitialized_fill_destroy
{
template <typename Policy, typename Iterator, typename T>
void
operator()(Policy&& exec, Iterator first, Iterator last, const T& in, std::size_t n, std::false_type)
{
using namespace std;
{
T::SetCount(0);
uninitialized_fill(exec, first, last, in);
size_t count = count_if(first, last, [&in](T& x) -> bool { return x == in; });
EXPECT_TRUE(n == count, "wrong work of uninitialized_fill");
destroy(exec, first, last);
EXPECT_TRUE(T::Count() == 0, "wrong work of destroy");
}
{
auto res = uninitialized_fill_n(exec, first, n, in);
EXPECT_TRUE(res == last, "wrong result of uninitialized_fill_n");
size_t count = count_if(first, last, [&in](T& x) -> bool { return x == in; });
EXPECT_TRUE(n == count, "wrong work of uninitialized_fill_n");
destroy_n(exec, first, n);
EXPECT_TRUE(T::Count() == 0, "wrong work of destroy_n");
}
}
template <typename Policy, typename Iterator, typename T>
void
operator()(Policy&& exec, Iterator first, Iterator last, const T& in, std::size_t n, std::true_type)
{
using namespace std;
{
destroy(exec, first, last);
uninitialized_fill(exec, first, last, in);
size_t count = count_if(first, last, [&in](T& x) -> bool { return x == in; });
EXPECT_EQ(n, count, "wrong work of uninitialized:_fill");
}
{
destroy_n(exec, first, n);
auto res = uninitialized_fill_n(exec, first, n, in);
size_t count = count_if(first, last, [&in](T& x) -> bool { return x == in; });
EXPECT_EQ(n, count, "wrong work of uninitialized_fill_n");
EXPECT_TRUE(res == last, "wrong result of uninitialized_fill_n");
}
}
};
template <typename T>
void
test_uninitialized_fill_destroy_by_type()
{
std::size_t N = 100000;
for (size_t n = 0; n <= N; n = n <= 16 ? n + 1 : size_t(3.1415 * n))
{
std::unique_ptr<T[]> p(new T[n]);
invoke_on_all_policies(test_uninitialized_fill_destroy(), p.get(), std::next(p.get(), n), T(), n,
std::is_trivial<T>());
}
}
int32_t
main()
{
// for trivial types
test_uninitialized_fill_destroy_by_type<int32_t>();
test_uninitialized_fill_destroy_by_type<float64_t>();
// for user-defined types
test_uninitialized_fill_destroy_by_type<Wrapper<std::string>>();
test_uninitialized_fill_destroy_by_type<Wrapper<int8_t*>>();
std::cout << done() << std::endl;
return 0;
}
// -*- C++ -*-
// { dg-options "-std=gnu++17 -ltbb" }
// { dg-do run { target c++17 } }
// { dg-require-effective-target tbb-backend }
//===-- inplace_merge.pass.cpp --------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "pstl/pstl_test_config.h"
#ifdef PSTL_STANDALONE_TESTS
#include <algorithm>
#include "pstl/execution"
#include "pstl/algorithm"
#else
#include <execution>
#include <algorithm>
#endif // PSTL_STANDALONE_TESTS
#include "pstl/test_utils.h"
using namespace TestUtils;
struct test_one_policy
{
#if __PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN || \
__PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN // dummy specialization by policy type, in case of broken configuration
template <typename BiDirIt1, typename Size, typename Generator1, typename Generator2, typename Compare>
void
operator()(pstl::execution::unsequenced_policy, BiDirIt1 first1, BiDirIt1 last1, BiDirIt1 first2, BiDirIt1 last2,
Size n, Size m, Generator1 generator1, Generator2 generator2, Compare comp)
{
}
template <typename BiDirIt1, typename Size, typename Generator1, typename Generator2, typename Compare>
void
operator()(pstl::execution::parallel_unsequenced_policy, BiDirIt1 first1, BiDirIt1 last1, BiDirIt1 first2,
BiDirIt1 last2, Size n, Size m, Generator1 generator1, Generator2 generator2, Compare comp)
{
}
#endif
// inplace_merge works with bidirectional iterators at least
template <typename Policy, typename BiDirIt1, typename Size, typename Generator1, typename Generator2,
typename Compare>
typename std::enable_if<!is_same_iterator_category<BiDirIt1, std::forward_iterator_tag>::value, void>::type
operator()(Policy&& exec, BiDirIt1 first1, BiDirIt1 last1, BiDirIt1 first2, BiDirIt1 last2, Size n, Size m,
Generator1 generator1, Generator2 generator2, Compare comp)
{
using T = typename std::iterator_traits<BiDirIt1>::value_type;
const BiDirIt1 mid1 = std::next(first1, m);
fill_data(first1, mid1, generator1);
fill_data(mid1, last1, generator2);
const BiDirIt1 mid2 = std::next(first2, m);
fill_data(first2, mid2, generator1);
fill_data(mid2, last2, generator2);
std::inplace_merge(first1, mid1, last1, comp);
std::inplace_merge(exec, first2, mid2, last2, comp);
EXPECT_EQ_N(first1, first2, n, "wrong effect from inplace_merge with predicate");
}
template <typename Policy, typename BiDirIt1, typename Size, typename Generator1, typename Generator2,
typename Compare>
typename std::enable_if<is_same_iterator_category<BiDirIt1, std::forward_iterator_tag>::value, void>::type
operator()(Policy&& exec, BiDirIt1 first1, BiDirIt1 last1, BiDirIt1 first2, BiDirIt1 last2, Size n, Size m,
Generator1 generator1, Generator2 generator2, Compare comp)
{
}
};
template <typename T, typename Generator1, typename Generator2, typename Compare>
void
test_by_type(Generator1 generator1, Generator2 generator2, Compare comp)
{
using namespace std;
size_t max_size = 100000;
Sequence<T> in1(max_size, [](size_t v) { return T(v); });
Sequence<T> exp(max_size, [](size_t v) { return T(v); });
size_t m;
for (size_t n = 0; n <= max_size; n = n <= 16 ? n + 1 : size_t(3.1415 * n))
{
m = 0;
invoke_on_all_policies(test_one_policy(), in1.begin(), in1.begin() + n, exp.begin(), exp.begin() + n, n, m,
generator1, generator2, comp);
m = n / 3;
invoke_on_all_policies(test_one_policy(), in1.begin(), in1.begin() + n, exp.begin(), exp.begin() + n, n, m,
generator1, generator2, comp);
m = 2 * n / 3;
invoke_on_all_policies(test_one_policy(), in1.begin(), in1.begin() + n, exp.begin(), exp.begin() + n, n, m,
generator1, generator2, comp);
}
}
template <typename T>
struct LocalWrapper
{
explicit LocalWrapper(int32_t k) : my_val(k) {}
LocalWrapper(LocalWrapper&& input) { my_val = std::move(input.my_val); }
LocalWrapper&
operator=(LocalWrapper&& input)
{
my_val = std::move(input.my_val);
return *this;
}
bool
operator<(const LocalWrapper<T>& w) const
{
return my_val < w.my_val;
}
friend bool
operator==(const LocalWrapper<T>& x, const LocalWrapper<T>& y)
{
return x.my_val == y.my_val;
}
friend std::ostream&
operator<<(std::ostream& stream, const LocalWrapper<T>& input)
{
return stream << input.my_val;
}
private:
T my_val;
};
template <typename T>
struct test_non_const
{
template <typename Policy, typename Iterator>
void
operator()(Policy&& exec, Iterator iter)
{
invoke_if(exec, [&]() { inplace_merge(exec, iter, iter, iter, non_const(std::less<T>())); });
}
};
int32_t
main()
{
test_by_type<float64_t>([](int32_t i) { return -2 * i; }, [](int32_t i) { return -(2 * i + 1); },
[](const float64_t x, const float64_t y) { return x > y; });
test_by_type<int32_t>([](int32_t i) { return 10 * i; }, [](int32_t i) { return i + 1; }, std::less<int32_t>());
test_by_type<LocalWrapper<float32_t>>([](int32_t i) { return LocalWrapper<float32_t>(2 * i + 1); },
[](int32_t i) { return LocalWrapper<float32_t>(2 * i); },
std::less<LocalWrapper<float32_t>>());
test_algo_basic_single<int32_t>(run_for_rnd_bi<test_non_const<int32_t>>());
std::cout << done() << std::endl;
return 0;
}
// -*- C++ -*-
// { dg-options "-std=gnu++17 -ltbb" }
// { dg-do run { target c++17 } }
// { dg-require-effective-target tbb-backend }
//===-- merge.pass.cpp ----------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "pstl/pstl_test_config.h"
#ifdef PSTL_STANDALONE_TESTS
#include <algorithm>
#include <functional>
#include "pstl/execution"
#include "pstl/algorithm"
#else
#include <execution>
#include <algorithm>
#endif // PSTL_STANDALONE_TESTS
#include "pstl/test_utils.h"
using namespace TestUtils;
struct test_merge
{
template <typename Policy, typename InputIterator1, typename InputIterator2, typename OutputIterator,
typename Compare>
void
operator()(Policy&& exec, InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2,
OutputIterator out_first, OutputIterator out_last, Compare comp)
{
using namespace std;
{
const auto res = merge(exec, first1, last1, first2, last2, out_first, comp);
EXPECT_TRUE(res == out_last, "wrong return result from merge with predicate");
EXPECT_TRUE(is_sorted(out_first, res, comp), "wrong result from merge with predicate");
EXPECT_TRUE(includes(out_first, res, first1, last1, comp), "first sequence is not a part of result");
EXPECT_TRUE(includes(out_first, res, first2, last2, comp), "second sequence is not a part of result");
}
{
const auto res = merge(exec, first1, last1, first2, last2, out_first);
EXPECT_TRUE(res == out_last, "wrong return result from merge");
EXPECT_TRUE(is_sorted(out_first, res), "wrong result from merge");
}
}
// for reverse iterators
template <typename Policy, typename InputIterator1, typename InputIterator2, typename OutputIterator,
typename Compare>
void
operator()(Policy&& exec, std::reverse_iterator<InputIterator1> first1, std::reverse_iterator<InputIterator1> last1,
std::reverse_iterator<InputIterator2> first2, std::reverse_iterator<InputIterator2> last2,
std::reverse_iterator<OutputIterator> out_first, std::reverse_iterator<OutputIterator> out_last,
Compare comp)
{
using namespace std;
typedef typename std::iterator_traits<std::reverse_iterator<InputIterator1>>::value_type T;
const auto res = merge(exec, first1, last1, first2, last2, out_first, std::greater<T>());
EXPECT_TRUE(res == out_last, "wrong return result from merge with predicate");
EXPECT_TRUE(is_sorted(out_first, res, std::greater<T>()), "wrong result from merge with predicate");
EXPECT_TRUE(includes(out_first, res, first1, last1, std::greater<T>()),
"first sequence is not a part of result");
EXPECT_TRUE(includes(out_first, res, first2, last2, std::greater<T>()),
"second sequence is not a part of result");
}
};
template <typename T, typename Generator1, typename Generator2>
void
test_merge_by_type(Generator1 generator1, Generator2 generator2)
{
using namespace std;
size_t max_size = 100000;
Sequence<T> in1(max_size, generator1);
Sequence<T> in2(max_size / 2, generator2);
Sequence<T> out(in1.size() + in2.size());
std::sort(in1.begin(), in1.end());
std::sort(in2.begin(), in2.end());
for (size_t size = 0; size <= max_size; size = size <= 16 ? size + 1 : size_t(3.1415 * size))
{
invoke_on_all_policies(test_merge(), in1.cbegin(), in1.cbegin() + size, in2.data(), in2.data() + size / 2,
out.begin(), out.begin() + 1.5 * size, std::less<T>());
invoke_on_all_policies(test_merge(), in1.data(), in1.data() + size, in2.cbegin(), in2.cbegin() + size / 2,
out.begin(), out.begin() + 3 * size / 2, std::less<T>());
}
}
template <typename T>
struct test_non_const
{
template <typename Policy, typename InputIterator, typename OutputIterator>
void
operator()(Policy&& exec, InputIterator input_iter, OutputIterator out_iter)
{
merge(exec, input_iter, input_iter, input_iter, input_iter, out_iter, non_const(std::less<T>()));
}
};
int32_t
main()
{
test_merge_by_type<int32_t>([](size_t v) { return (v % 2 == 0 ? v : -v) * 3; }, [](size_t v) { return v * 2; });
test_merge_by_type<float64_t>([](size_t v) { return float64_t(v); }, [](size_t v) { return float64_t(v - 100); });
#if !__PSTL_ICC_16_17_TEST_64_TIMEOUT
test_merge_by_type<Wrapper<int16_t>>([](size_t v) { return Wrapper<int16_t>(v % 100); },
[](size_t v) { return Wrapper<int16_t>(v % 10); });
#endif
test_algo_basic_double<int32_t>(run_for_rnd_fw<test_non_const<int32_t>>());
std::cout << done() << std::endl;
return 0;
}
// -*- C++ -*-
// { dg-options "-std=gnu++17 -ltbb" }
// { dg-do run { target c++17 } }
// { dg-require-effective-target tbb-backend }
//===-- copy_if.pass.cpp --------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
// Tests for copy_if and remove_copy_if
#include "pstl/pstl_test_config.h"
#ifdef PSTL_STANDALONE_TESTS
#include "pstl/execution"
#include "pstl/algorithm"
#else
#include <execution>
#include <algorithm>
#endif // PSTL_STANDALONE_TESTS
#include "pstl/test_utils.h"
using namespace TestUtils;
struct run_copy_if
{
#if __PSTL_ICC_16_VC14_TEST_PAR_TBB_RT_RELEASE_64_BROKEN // dummy specializations to skip testing in case of broken configuration
template <typename InputIterator, typename OutputIterator, typename OutputIterator2, typename Size,
typename Predicate, typename T>
void
operator()(__pstl::execution::parallel_policy, InputIterator first, InputIterator last, OutputIterator out_first,
OutputIterator out_last, OutputIterator2 expected_first, OutputIterator2 expected_last, Size n,
Predicate pred, T trash)
{
}
template <typename InputIterator, typename OutputIterator, typename OutputIterator2, typename Size,
typename Predicate, typename T>
void
operator()(__pstl::execution::parallel_unsequenced_policy, InputIterator first, InputIterator last,
OutputIterator out_first, OutputIterator out_last, OutputIterator2 expected_first,
OutputIterator2 expected_last, Size n, Predicate pred, T trash)
{
}
#endif
template <typename Policy, typename InputIterator, typename OutputIterator, typename OutputIterator2, typename Size,
typename Predicate, typename T>
void
operator()(Policy&& exec, InputIterator first, InputIterator last, OutputIterator out_first,
OutputIterator out_last, OutputIterator2 expected_first, OutputIterator2 expected_last, Size n,
Predicate pred, T trash)
{
// Cleaning
std::fill_n(expected_first, n, trash);
std::fill_n(out_first, n, trash);
// Run copy_if
auto i = copy_if(first, last, expected_first, pred);
auto k = copy_if(exec, first, last, out_first, pred);
EXPECT_EQ_N(expected_first, out_first, n, "wrong copy_if effect");
for (size_t j = 0; j < GuardSize; ++j)
{
++k;
}
EXPECT_TRUE(out_last == k, "wrong return value from copy_if");
// Cleaning
std::fill_n(expected_first, n, trash);
std::fill_n(out_first, n, trash);
// Run remove_copy_if
i = remove_copy_if(first, last, expected_first, [=](const T& x) { return !pred(x); });
k = remove_copy_if(exec, first, last, out_first, [=](const T& x) { return !pred(x); });
EXPECT_EQ_N(expected_first, out_first, n, "wrong remove_copy_if effect");
for (size_t j = 0; j < GuardSize; ++j)
{
++k;
}
EXPECT_TRUE(out_last == k, "wrong return value from remove_copy_if");
}
};
template <typename T, typename Predicate, typename Convert>
void
test(T trash, Predicate pred, Convert convert, bool check_weakness = true)
{
// Try sequences of various lengths.
for (size_t n = 0; n <= 100000; n = n <= 16 ? n + 1 : size_t(3.1415 * n))
{
// count is number of output elements, plus a handful
// more for sake of detecting buffer overruns.
size_t count = GuardSize;
Sequence<T> in(n, [&](size_t k) -> T {
T val = convert(n ^ k);
count += pred(val) ? 1 : 0;
return val;
});
Sequence<T> out(count, [=](size_t) { return trash; });
Sequence<T> expected(count, [=](size_t) { return trash; });
if (check_weakness)
{
auto expected_result = copy_if(in.cfbegin(), in.cfend(), expected.begin(), pred);
size_t m = expected_result - expected.begin();
EXPECT_TRUE(n / 4 <= m && m <= 3 * (n + 1) / 4, "weak test for copy_if");
}
invoke_on_all_policies(run_copy_if(), in.begin(), in.end(), out.begin(), out.end(), expected.begin(),
expected.end(), count, pred, trash);
invoke_on_all_policies(run_copy_if(), in.cbegin(), in.cend(), out.begin(), out.end(), expected.begin(),
expected.end(), count, pred, trash);
}
}
struct test_non_const
{
template <typename Policy, typename InputIterator, typename OutputInterator>
void
operator()(Policy&& exec, InputIterator input_iter, OutputInterator out_iter)
{
auto is_even = [&](float64_t v) {
uint32_t i = (uint32_t)v;
return i % 2 == 0;
};
copy_if(exec, input_iter, input_iter, out_iter, non_const(is_even));
invoke_if(exec, [&]() { remove_copy_if(exec, input_iter, input_iter, out_iter, non_const(is_even)); });
}
};
int32_t
main()
{
test<float64_t>(-666.0, [](const float64_t& x) { return x * x <= 1024; },
[](size_t j) { return ((j + 1) % 7 & 2) != 0 ? float64_t(j % 32) : float64_t(j % 33 + 34); });
test<int32_t>(-666, [](const int32_t& x) { return x != 42; },
[](size_t j) { return ((j + 1) % 5 & 2) != 0 ? int32_t(j + 1) : 42; });
#if !__PSTL_ICC_17_TEST_MAC_RELEASE_32_BROKEN
test<Number>(Number(42, OddTag()), IsMultiple(3, OddTag()), [](int32_t j) { return Number(j, OddTag()); });
#endif
#if !__PSTL_ICC_16_17_TEST_REDUCTION_RELEASE_BROKEN
test<int32_t>(-666, [](const int32_t& x) { return true; }, [](size_t j) { return j; }, false);
#endif
test_algo_basic_double<int32_t>(run_for_rnd_fw<test_non_const>());
std::cout << done() << std::endl;
return 0;
}
// -*- C++ -*-
// { dg-options "-std=gnu++17 -ltbb" }
// { dg-do run { target c++17 } }
// { dg-require-effective-target tbb-backend }
//===-- copy_move.pass.cpp ------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
// Tests for copy, move and copy_n
#include "pstl/pstl_test_config.h"
#ifdef PSTL_STANDALONE_TESTS
#include "pstl/execution"
#include "pstl/algorithm"
#else
#include <execution>
#include <algorithm>
#endif // PSTL_STANDALONE_TESTS
#include "pstl/test_utils.h"
using namespace TestUtils;
struct run_copy
{
#if __PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN || \
__PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN //dummy specialization by policy type, in case of broken configuration
template <typename InputIterator, typename OutputIterator, typename OutputIterator2, typename Size, typename T>
void
operator()(pstl::execution::unsequenced_policy, InputIterator first, InputIterator last, OutputIterator out_first,
OutputIterator out_last, OutputIterator2 expected_first, OutputIterator2 expected_last, Size size,
Size n, T trash)
{
}
template <typename InputIterator, typename OutputIterator, typename OutputIterator2, typename Size, typename T>
void
operator()(pstl::execution::parallel_unsequenced_policy, InputIterator first, InputIterator last,
OutputIterator out_first, OutputIterator out_last, OutputIterator2 expected_first,
OutputIterator2 expected_last, Size size, Size n, T trash)
{
}
#endif
template <typename Policy, typename InputIterator, typename OutputIterator, typename OutputIterator2, typename Size,
typename T>
void
operator()(Policy&& exec, InputIterator first, InputIterator last, OutputIterator out_first,
OutputIterator out_last, OutputIterator2 expected_first, OutputIterator2 expected_last, Size size,
Size n, T trash)
{
// Cleaning
std::fill_n(expected_first, size, trash);
std::fill_n(out_first, size, trash);
// Run copy
copy(first, last, expected_first);
auto k = copy(exec, first, last, out_first);
for (size_t j = 0; j < GuardSize; ++j)
++k;
EXPECT_EQ_N(expected_first, out_first, size, "wrong effect from copy");
EXPECT_TRUE(out_last == k, "wrong return value from copy");
// Cleaning
std::fill_n(out_first, size, trash);
// Run copy_n
k = copy_n(exec, first, n, out_first);
for (size_t j = 0; j < GuardSize; ++j)
++k;
EXPECT_EQ_N(expected_first, out_first, size, "wrong effect from copy_n");
EXPECT_TRUE(out_last == k, "wrong return value from copy_n");
}
};
template <typename T>
struct run_move
{
#if __PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN || \
__PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN //dummy specialization by policy type, in case of broken configuration
template <typename InputIterator, typename OutputIterator, typename OutputIterator2, typename Size>
void
operator()(pstl::execution::unsequenced_policy, InputIterator first, InputIterator last, OutputIterator out_first,
OutputIterator out_last, OutputIterator2 expected_first, OutputIterator2 expected_last, Size size,
Size n, T trash)
{
}
template <typename InputIterator, typename OutputIterator, typename OutputIterator2, typename Size>
void
operator()(pstl::execution::parallel_unsequenced_policy, InputIterator first, InputIterator last,
OutputIterator out_first, OutputIterator out_last, OutputIterator2 expected_first,
OutputIterator2 expected_last, Size size, Size n, T trash)
{
}
#endif
template <typename Policy, typename InputIterator, typename OutputIterator, typename OutputIterator2, typename Size>
void
operator()(Policy&& exec, InputIterator first, InputIterator last, OutputIterator out_first,
OutputIterator out_last, OutputIterator2 expected_first, OutputIterator2 expected_last, Size size,
Size n, T trash)
{
// Cleaning
std::fill_n(expected_first, size, trash);
std::fill_n(out_first, size, trash);
// Run move
move(first, last, expected_first);
auto k = move(exec, first, last, out_first);
for (size_t j = 0; j < GuardSize; ++j)
++k;
EXPECT_EQ_N(expected_first, out_first, size, "wrong effect from move");
EXPECT_TRUE(out_last == k, "wrong return value from move");
}
};
template <typename T>
struct run_move<Wrapper<T>>
{
#if __PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN || \
__PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN //dummy specialization by policy type, in case of broken configuration
template <typename InputIterator, typename OutputIterator, typename OutputIterator2, typename Size>
void
operator()(pstl::execution::unsequenced_policy, InputIterator first, InputIterator last, OutputIterator out_first,
OutputIterator out_last, OutputIterator2 expected_first, OutputIterator2 expected_last, Size size,
Size n, Wrapper<T> trash)
{
}
template <typename InputIterator, typename OutputIterator, typename OutputIterator2, typename Size>
void
operator()(pstl::execution::parallel_unsequenced_policy, InputIterator first, InputIterator last,
OutputIterator out_first, OutputIterator out_last, OutputIterator2 expected_first,
OutputIterator2 expected_last, Size size, Size n, Wrapper<T> trash)
{
}
#endif
template <typename Policy, typename InputIterator, typename OutputIterator, typename OutputIterator2, typename Size>
void
operator()(Policy&& exec, InputIterator first, InputIterator last, OutputIterator out_first,
OutputIterator out_last, OutputIterator2 expected_first, OutputIterator2 expected_last, Size size,
Size n, Wrapper<T> trash)
{
// Cleaning
std::fill_n(out_first, size, trash);
Wrapper<T>::SetMoveCount(0);
// Run move
auto k = move(exec, first, last, out_first);
for (size_t j = 0; j < GuardSize; ++j)
++k;
EXPECT_TRUE(Wrapper<T>::MoveCount() == size, "wrong effect from move");
EXPECT_TRUE(out_last == k, "wrong return value from move");
}
};
template <typename T, typename Convert>
void
test(T trash, Convert convert)
{
// Try sequences of various lengths.
for (size_t n = 0; n <= 100000; n = n <= 16 ? n + 1 : size_t(3.1415 * n))
{
// count is number of output elements, plus a handful
// more for sake of detecting buffer overruns.
Sequence<T> in(n, [&](size_t k) -> T {
T val = convert(n ^ k);
return val;
});
const size_t outN = n + GuardSize;
Sequence<T> out(outN, [=](size_t) { return trash; });
Sequence<T> expected(outN, [=](size_t) { return trash; });
invoke_on_all_policies(run_copy(), in.begin(), in.end(), out.begin(), out.end(), expected.begin(),
expected.end(), outN, n, trash);
invoke_on_all_policies(run_copy(), in.cbegin(), in.cend(), out.begin(), out.end(), expected.begin(),
expected.end(), outN, n, trash);
invoke_on_all_policies(run_move<T>(), in.begin(), in.end(), out.begin(), out.end(), expected.begin(),
expected.end(), n, n, trash);
// For this test const iterator isn't suitable
// because const rvalue-reference call copy assignment operator
}
}
int32_t
main()
{
test<int32_t>(-666, [](size_t j) { return int32_t(j); });
test<Wrapper<float64_t>>(Wrapper<float64_t>(-666.0), [](int32_t j) { return Wrapper<float64_t>(j); });
#if !__PSTL_ICC_16_17_TEST_64_TIMEOUT
test<float64_t>(-666.0, [](size_t j) { return float64_t(j); });
test<Number>(Number(42, OddTag()), [](int32_t j) { return Number(j, OddTag()); });
#endif
std::cout << done() << std::endl;
return 0;
}
// -*- C++ -*-
// { dg-options "-std=gnu++17 -ltbb" }
// { dg-do run { target c++17 } }
// { dg-require-effective-target tbb-backend }
//===-- fill.pass.cpp -----------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "pstl/pstl_test_config.h"
#ifdef PSTL_STANDALONE_TESTS
#include "pstl/execution"
#include "pstl/algorithm"
#else
#include <execution>
#include <algorithm>
#endif // PSTL_STANDALONE_TESTS
#include "pstl/test_utils.h"
using namespace TestUtils;
struct test_fill
{
template <typename It, typename T>
bool
check(It first, It last, const T& value)
{
for (; first != last; ++first)
if (*first != value)
return false;
return true;
}
template <typename Policy, typename Iterator, typename T>
void
operator()(Policy&& exec, Iterator first, Iterator last, const T& value)
{
fill(first, last, T(value + 1)); // initialize memory with different value
fill(exec, first, last, value);
EXPECT_TRUE(check(first, last, value), "fill wrong result");
}
};
struct test_fill_n
{
template <typename It, typename Size, typename T>
bool
check(It first, Size n, const T& value)
{
for (Size i = 0; i < n; ++i, ++first)
if (*first != value)
return false;
return true;
}
template <typename Policy, typename Iterator, typename Size, typename T>
void
operator()(Policy&& exec, Iterator first, Size n, const T& value)
{
fill_n(first, n, T(value + 1)); // initialize memory with different value
const Iterator one_past_last = fill_n(exec, first, n, value);
const Iterator expected_return = std::next(first, n);
EXPECT_TRUE(expected_return == one_past_last, "fill_n should return Iterator to one past the element assigned");
EXPECT_TRUE(check(first, n, value), "fill_n wrong result");
//n == -1
const Iterator res = fill_n(exec, first, -1, value);
EXPECT_TRUE(res == first, "fill_n wrong result for n == -1");
}
};
template <typename T>
void
test_fill_by_type(std::size_t n)
{
Sequence<T> in(n, [](std::size_t v) -> T { return T(0); }); //fill with zeros
T value = -1;
invoke_on_all_policies(test_fill(), in.begin(), in.end(), value);
invoke_on_all_policies(test_fill_n(), in.begin(), n, value);
}
int32_t
main()
{
const std::size_t N = 100000;
for (std::size_t n = 0; n < N; n = n < 16 ? n + 1 : size_t(3.1415 * n))
{
test_fill_by_type<int32_t>(n);
test_fill_by_type<float64_t>(n);
}
std::cout << done() << std::endl;
return 0;
}
// -*- C++ -*-
// { dg-options "-std=gnu++17 -ltbb" }
// { dg-do run { target c++17 } }
// { dg-require-effective-target tbb-backend }
//===-- generate.pass.cpp -------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "pstl/pstl_test_config.h"
#ifdef PSTL_STANDALONE_TESTS
#include <atomic>
#include "pstl/execution"
#include "pstl/algorithm"
#else
#include <execution>
#include <algorithm>
#endif // PSTL_STANDALONE_TESTS
#include "pstl/test_utils.h"
using namespace TestUtils;
template <typename T>
struct Generator_count
{
const T def_val = T(-1);
T
operator()()
{
return def_val;
}
T
default_value() const
{
return def_val;
}
};
struct test_generate
{
template <typename Policy, typename Iterator, typename Size>
void
operator()(Policy&& exec, Iterator first, Iterator last, Size n)
{
using namespace std;
typedef typename std::iterator_traits<Iterator>::value_type T;
// Try random-access iterator
{
Generator_count<T> g;
generate(exec, first, last, g);
EXPECT_TRUE(std::count(first, last, g.default_value()) == n, "generate wrong result for generate");
std::fill(first, last, T(0));
}
{
Generator_count<T> g;
const auto m = n / 2;
auto last = generate_n(exec, first, m, g);
EXPECT_TRUE(std::count(first, last, g.default_value()) == m && last == std::next(first, m),
"generate_n wrong result for generate_n");
std::fill(first, last, T(0));
}
}
};
template <typename T>
void
test_generate_by_type()
{
for (size_t n = 0; n <= 100000; n = n < 16 ? n + 1 : size_t(3.1415 * n))
{
Sequence<T> in(n, [](size_t v) -> T { return T(0); }); //fill by zero
invoke_on_all_policies(test_generate(), in.begin(), in.end(), in.size());
}
}
template <typename T>
struct test_non_const
{
template <typename Policy, typename Iterator>
void
operator()(Policy&& exec, Iterator iter)
{
auto gen = []() { return T(0); };
generate(exec, iter, iter, non_const(gen));
generate_n(exec, iter, 0, non_const(gen));
}
};
int32_t
main()
{
test_generate_by_type<int32_t>();
test_generate_by_type<float64_t>();
test_algo_basic_single<int32_t>(run_for_rnd_fw<test_non_const<int32_t>>());
std::cout << done() << std::endl;
return 0;
}
// -*- C++ -*-
// { dg-options "-std=gnu++17 -ltbb" }
// { dg-do run { target c++17 } }
// { dg-require-effective-target tbb-backend }
//===-- is_partitioned.pass.cpp -------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "pstl/pstl_test_config.h"
#ifdef PSTL_STANDALONE_TESTS
#include "pstl/execution"
#include "pstl/algorithm"
#else
#include <execution>
#include <algorithm>
#endif // PSTL_STANDALONE_TESTS
#include "pstl/test_utils.h"
using namespace TestUtils;
struct test_one_policy
{
//dummy specialization by policy type, in case of broken configuration
#if __PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN || __PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN
template <typename Iterator1, typename Predicate>
void
operator()(pstl::execution::unsequenced_policy, Iterator1 begin1, Iterator1 end1, Predicate pred)
{
}
template <typename Iterator1, typename Predicate>
void
operator()(pstl::execution::parallel_unsequenced_policy, Iterator1 begin1, Iterator1 end1, Predicate pred)
{
}
#endif
template <typename ExecutionPolicy, typename Iterator1, typename Predicate>
void
operator()(ExecutionPolicy&& exec, Iterator1 begin1, Iterator1 end1, Predicate pred)
{
const bool expected = std::is_partitioned(begin1, end1, pred);
const bool actual = std::is_partitioned(exec, begin1, end1, pred);
EXPECT_TRUE(actual == expected, "wrong return result from is_partitioned");
}
};
template <typename T, typename Predicate>
void
test(Predicate pred)
{
const std::size_t max_n = 1000000;
Sequence<T> in(max_n, [](std::size_t k) { return T(k); });
for (std::size_t n1 = 0; n1 <= max_n; n1 = n1 <= 16 ? n1 + 1 : std::size_t(3.1415 * n1))
{
invoke_on_all_policies(test_one_policy(), in.begin(), in.begin() + n1, pred);
std::partition(in.begin(), in.begin() + n1, pred);
invoke_on_all_policies(test_one_policy(), in.cbegin(), in.cbegin() + n1, pred);
}
}
template <typename T>
struct LocalWrapper
{
explicit LocalWrapper(std::size_t k) : my_val(k) {}
private:
T my_val;
};
struct test_non_const
{
template <typename Policy, typename Iterator>
void
operator()(Policy&& exec, Iterator iter)
{
auto is_even = [&](float64_t v) {
uint32_t i = (uint32_t)v;
return i % 2 == 0;
};
invoke_if(exec, [&]() { is_partitioned(exec, iter, iter, non_const(is_even)); });
}
};
int32_t
main()
{
test<float64_t>([](const float64_t x) { return x < 0; });
test<int32_t>([](const int32_t x) { return x > 1000; });
test<uint16_t>([](const uint16_t x) { return x % 5 < 3; });
#if !__PSTL_ICC_18_TEST_EARLY_EXIT_MONOTONIC_RELEASE_BROKEN && !__PSTL_ICC_19_TEST_IS_PARTITIONED_RELEASE_BROKEN
test<LocalWrapper<float64_t>>([](const LocalWrapper<float64_t>& x) { return true; });
#endif
test_algo_basic_single<int32_t>(run_for_rnd_fw<test_non_const>());
std::cout << done() << std::endl;
return 0;
}
// -*- C++ -*-
// { dg-options "-std=gnu++17 -ltbb" }
// { dg-do run { target c++17 } }
// { dg-require-effective-target tbb-backend }
//===-- partition.pass.cpp ------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
// Tests for stable_partition and partition
#include "pstl/pstl_test_config.h"
#ifdef PSTL_STANDALONE_TESTS
#include "pstl/execution"
#include "pstl/algorithm"
#else
#include <execution>
#include <algorithm>
#endif // PSTL_STANDALONE_TESTS
#include "pstl/test_utils.h"
#include <iterator>
#include <type_traits>
using namespace TestUtils;
template <typename T>
struct DataType
{
explicit DataType(int32_t k) : my_val(k) {}
DataType(DataType&& input) { my_val = std::move(input.my_val); }
DataType&
operator=(DataType&& input)
{
my_val = std::move(input.my_val);
return *this;
}
T
get_val() const
{
return my_val;
}
friend std::ostream&
operator<<(std::ostream& stream, const DataType<T>& input)
{
return stream << input.my_val;
}
private:
T my_val;
};
template <typename Iterator>
typename std::enable_if<std::is_trivial<typename std::iterator_traits<Iterator>::value_type>::value, bool>::type
is_equal(Iterator first, Iterator last, Iterator d_first)
{
return std::equal(first, last, d_first);
}
template <typename Iterator>
typename std::enable_if<!std::is_trivial<typename std::iterator_traits<Iterator>::value_type>::value, bool>::type
is_equal(Iterator first, Iterator last, Iterator d_first)
{
return true;
}
struct test_one_policy
{
#if __PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN || \
__PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN //dummy specializations to skip testing in case of broken configuration
template <typename BiDirIt, typename Size, typename UnaryOp, typename Generator>
void
operator()(__pstl::execution::unsequenced_policy, BiDirIt first, BiDirIt last, BiDirIt exp_first, BiDirIt exp_last,
Size n, UnaryOp unary_op, Generator generator)
{
}
template <typename BiDirIt, typename Size, typename UnaryOp, typename Generator>
void
operator()(__pstl::execution::parallel_unsequenced_policy, BiDirIt first, BiDirIt last, BiDirIt exp_first,
BiDirIt exp_last, Size n, UnaryOp unary_op, Generator generator)
{
}
#elif __PSTL_ICC_16_VC14_TEST_PAR_TBB_RT_RELEASE_64_BROKEN //dummy specializations to skip testing in case of broken configuration
template <typename BiDirIt, typename Size, typename UnaryOp, typename Generator>
void
operator()(__pstl::execution::parallel_policy, BiDirIt first, BiDirIt last, BiDirIt exp_first, BiDirIt exp_last,
Size n, UnaryOp unary_op, Generator generator)
{
}
template <typename BiDirIt, typename Size, typename UnaryOp, typename Generator>
void
operator()(__pstl::execution::parallel_unsequenced_policy, BiDirIt first, BiDirIt last, BiDirIt exp_first,
BiDirIt exp_last, Size n, UnaryOp unary_op, Generator generator)
{
}
#endif
template <typename Policy, typename BiDirIt, typename Size, typename UnaryOp, typename Generator>
typename std::enable_if<!is_same_iterator_category<BiDirIt, std::forward_iterator_tag>::value, void>::type
operator()(Policy&& exec, BiDirIt first, BiDirIt last, BiDirIt exp_first, BiDirIt exp_last, Size n,
UnaryOp unary_op, Generator generator)
{
// partition
{
fill_data(first, last, generator);
BiDirIt actual_ret = std::partition(exec, first, last, unary_op);
EXPECT_TRUE(std::all_of(first, actual_ret, unary_op) && !std::any_of(actual_ret, last, unary_op),
"wrong effect from partition");
}
// stable_partition
{
fill_data(exp_first, exp_last, generator);
BiDirIt exp_ret = std::stable_partition(exp_first, exp_last, unary_op);
fill_data(first, last, generator);
BiDirIt actual_ret = std::stable_partition(exec, first, last, unary_op);
EXPECT_TRUE(std::distance(first, actual_ret) == std::distance(exp_first, exp_ret),
"wrong result from stable_partition");
EXPECT_TRUE((is_equal<BiDirIt>(exp_first, exp_last, first)), "wrong effect from stable_partition");
}
}
template <typename Policy, typename BiDirIt, typename Size, typename UnaryOp, typename Generator>
typename std::enable_if<is_same_iterator_category<BiDirIt, std::forward_iterator_tag>::value, void>::type
operator()(Policy&& exec, BiDirIt first, BiDirIt last, BiDirIt exp_first, BiDirIt exp_last, Size n,
UnaryOp unary_op, Generator generator)
{
}
};
template <typename T, typename Generator, typename UnaryPred>
void
test_by_type(Generator generator, UnaryPred pred)
{
using namespace std;
size_t max_size = 100000;
Sequence<T> in(max_size, [](size_t v) { return T(v); });
Sequence<T> exp(max_size, [](size_t v) { return T(v); });
for (size_t n = 0; n <= max_size; n = n <= 16 ? n + 1 : size_t(3.1415 * n))
{
invoke_on_all_policies(test_one_policy(), in.begin(), in.begin() + n, exp.begin(), exp.begin() + n, n, pred,
generator);
}
}
struct test_non_const
{
template <typename Policy, typename Iterator>
void
operator()(Policy&& exec, Iterator iter)
{
auto is_even = [&](float64_t v) {
uint32_t i = (uint32_t)v;
return i % 2 == 0;
};
invoke_if(exec, [&]() {
partition(exec, iter, iter, non_const(is_even));
stable_partition(exec, iter, iter, non_const(is_even));
});
}
};
int32_t
main()
{
#if !__PSTL_ICC_16_17_TEST_REDUCTION_RELEASE_BROKEN
test_by_type<int32_t>([](int32_t i) { return i; }, [](int32_t) { return true; });
#endif
test_by_type<float64_t>([](int32_t i) { return -i; }, [](const float64_t x) { return x < 0; });
test_by_type<int64_t>([](int32_t i) { return i + 1; }, [](int64_t x) { return x % 3 == 0; });
test_by_type<DataType<float32_t>>([](int32_t i) { return DataType<float32_t>(2 * i + 1); },
[](const DataType<float32_t>& x) { return x.get_val() < 0; });
test_algo_basic_single<int32_t>(run_for_rnd_bi<test_non_const>());
std::cout << done() << std::endl;
return 0;
}
// -*- C++ -*-
// { dg-options "-std=gnu++17 -ltbb" }
// { dg-do run { target c++17 } }
// { dg-require-effective-target tbb-backend }
//===-- partition_copy.pass.cpp -------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
// Tests for stable_partition and partition_copy
#include "pstl/pstl_test_config.h"
#ifdef PSTL_STANDALONE_TESTS
#include "pstl/execution"
#include "pstl/algorithm"
#else
#include <execution>
#include <algorithm>
#endif // PSTL_STANDALONE_TESTS
#include "pstl/test_utils.h"
#include <cstdlib>
#include <iterator>
using namespace TestUtils;
struct test_partition_copy
{
template <typename Policy, typename InputIterator, typename OutputIterator, typename OutputIterator2,
typename UnaryOp>
void
operator()(Policy&& exec, InputIterator first, InputIterator last, OutputIterator true_first,
OutputIterator true_last, OutputIterator2 false_first, OutputIterator2 false_last, UnaryOp unary_op)
{
auto actual_ret = std::partition_copy(exec, first, last, true_first, false_first, unary_op);
EXPECT_TRUE(std::distance(true_first, actual_ret.first) == std::count_if(first, last, unary_op),
"partition_copy has wrong effect from true sequence");
EXPECT_TRUE(std::distance(false_first, actual_ret.second) ==
std::count_if(first, last, __pstl::__internal::__not_pred<UnaryOp>(unary_op)),
"partition_copy has wrong effect from false sequence");
}
//dummy specialization by iterator type and policy type, in case of broken configuration
#if __PSTL_ICC_1800_TEST_MONOTONIC_RELEASE_64_BROKEN
template <typename InputIterator, typename OutputIterator, typename OutputIterator2, typename UnaryOp>
void
operator()(pstl::execution::unsequenced_policy, std::reverse_iterator<InputIterator> first,
std::reverse_iterator<InputIterator> last, std::reverse_iterator<OutputIterator> true_first,
std::reverse_iterator<OutputIterator> true_last, std::reverse_iterator<OutputIterator2> false_first,
OutputIterator2 false_last, UnaryOp unary_op)
{
}
template <typename InputIterator, typename OutputIterator, typename OutputIterator2, typename UnaryOp>
void
operator()(pstl::execution::parallel_unsequenced_policy, std::reverse_iterator<InputIterator> first,
std::reverse_iterator<InputIterator> last, std::reverse_iterator<OutputIterator> true_first,
std::reverse_iterator<OutputIterator> true_last, std::reverse_iterator<OutputIterator2> false_first,
OutputIterator2 false_last, UnaryOp unary_op)
{
}
#endif
};
template <typename T, typename UnaryPred>
void
test(UnaryPred pred)
{
const std::size_t max_size = 100000;
Sequence<T> in(max_size, [](std::size_t v) -> T { return T(v); });
Sequence<T> actual_true(max_size);
Sequence<T> actual_false(max_size);
for (std::size_t n = 0; n <= max_size; n = n <= 16 ? n + 1 : std::size_t(3.1415 * n))
{
// for non-const input iterators
invoke_on_all_policies(test_partition_copy(), in.begin(), in.begin() + n, actual_true.begin(),
actual_true.begin() + n, actual_false.begin(), actual_false.begin() + n, pred);
// for const input iterators
invoke_on_all_policies(test_partition_copy(), in.cbegin(), in.cbegin() + n, actual_true.begin(),
actual_true.begin() + n, actual_false.begin(), actual_false.begin() + n, pred);
}
}
struct test_non_const
{
template <typename Policy, typename InputIterator, typename OutputInterator>
void
operator()(Policy&& exec, InputIterator input_iter, OutputInterator out_iter)
{
auto is_even = [&](float64_t v) {
uint32_t i = (uint32_t)v;
return i % 2 == 0;
};
partition_copy(exec, input_iter, input_iter, out_iter, out_iter, non_const(is_even));
}
};
int32_t
main()
{
test<int32_t>([](const int32_t value) { return value % 2; });
#if !__PSTL_ICC_16_17_TEST_REDUCTION_RELEASE_BROKEN
test<int32_t>([](const int32_t value) { return true; });
#endif
test<float64_t>([](const float64_t value) { return value > 2 << 6; });
test<Wrapper<float64_t>>([](const Wrapper<float64_t>& value) -> bool { return value.get_my_field() != nullptr; });
test_algo_basic_double<int32_t>(run_for_rnd_bi<test_non_const>());
std::cout << done() << std::endl;
return 0;
}
// -*- C++ -*-
// { dg-options "-std=gnu++17 -ltbb" }
// { dg-do run { target c++17 } }
// { dg-require-effective-target tbb-backend }
//===-- remove.pass.cpp ---------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
// Test for remove, remove_if
#include "pstl/pstl_test_config.h"
#ifdef PSTL_STANDALONE_TESTS
#include "pstl/execution"
#include "pstl/algorithm"
#else
#include <execution>
#include <algorithm>
#endif // PSTL_STANDALONE_TESTS
#include "pstl/test_utils.h"
using namespace TestUtils;
struct run_remove
{
#if __PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN || \
__PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN //dummy specialization by policy type, in case of broken configuration
template <typename InputIterator, typename OutputIterator, typename Size, typename T>
void
operator()(pstl::execution::unsequenced_policy, InputIterator first, InputIterator last, OutputIterator out_first,
OutputIterator out_last, OutputIterator expected_first, OutputIterator expected_last, Size n,
const T& value)
{
}
template <typename InputIterator, typename OutputIterator, typename Size, typename T>
void
operator()(pstl::execution::parallel_unsequenced_policy, InputIterator first, InputIterator last,
OutputIterator out_first, OutputIterator out_last, OutputIterator expected_first,
OutputIterator expected_last, Size n, const T& value)
{
}
#endif
template <typename Policy, typename InputIterator, typename OutputIterator, typename Size, typename T>
void
operator()(Policy&& exec, InputIterator first, InputIterator last, OutputIterator out_first,
OutputIterator out_last, OutputIterator expected_first, OutputIterator expected_last, Size,
const T& value)
{
// Cleaning
std::copy(first, last, expected_first);
std::copy(first, last, out_first);
// Run remove
OutputIterator i = remove(expected_first, expected_last, value);
OutputIterator k = remove(exec, out_first, out_last, value);
EXPECT_TRUE(std::distance(expected_first, i) == std::distance(out_first, k), "wrong return value from remove");
EXPECT_EQ_N(expected_first, out_first, std::distance(expected_first, i), "wrong remove effect");
}
};
struct run_remove_if
{
#if __PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN || \
__PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN //dummy specialization by policy type, in case of broken configuration
template <typename InputIterator, typename OutputIterator, typename Size, typename Predicate>
void
operator()(pstl::execution::unsequenced_policy, InputIterator first, InputIterator last, OutputIterator out_first,
OutputIterator out_last, OutputIterator expected_first, OutputIterator expected_last, Size n,
Predicate pred)
{
}
template <typename InputIterator, typename OutputIterator, typename Size, typename Predicate>
void
operator()(pstl::execution::parallel_unsequenced_policy, InputIterator first, InputIterator last,
OutputIterator out_first, OutputIterator out_last, OutputIterator expected_first,
OutputIterator expected_last, Size n, Predicate pred)
{
}
#endif
template <typename Policy, typename InputIterator, typename OutputIterator, typename Size, typename Predicate>
void
operator()(Policy&& exec, InputIterator first, InputIterator last, OutputIterator out_first,
OutputIterator out_last, OutputIterator expected_first, OutputIterator expected_last, Size,
Predicate pred)
{
// Cleaning
std::copy(first, last, expected_first);
std::copy(first, last, out_first);
// Run remove_if
OutputIterator i = remove_if(expected_first, expected_last, pred);
OutputIterator k = remove_if(exec, out_first, out_last, pred);
EXPECT_TRUE(std::distance(expected_first, i) == std::distance(out_first, k),
"wrong return value from remove_if");
EXPECT_EQ_N(expected_first, out_first, std::distance(expected_first, i), "wrong remove_if effect");
}
};
template <typename T, typename Predicate, typename Convert>
void
test(T trash, const T& value, Predicate pred, Convert convert)
{
const std::size_t max_size = 100000;
Sequence<T> out(max_size, [trash](size_t) { return trash; });
Sequence<T> expected(max_size, [trash](size_t) { return trash; });
for (size_t n = 0; n <= max_size; n = n <= 16 ? n + 1 : size_t(3.1415 * n))
{
Sequence<T> data(n, [&](size_t k) -> T { return convert(k); });
invoke_on_all_policies(run_remove(), data.begin(), data.end(), out.begin(), out.begin() + n, expected.begin(),
expected.begin() + n, n, value);
invoke_on_all_policies(run_remove_if(), data.begin(), data.end(), out.begin(), out.begin() + n,
expected.begin(), expected.begin() + n, n, pred);
}
}
struct test_non_const
{
template <typename Policy, typename Iterator>
void
operator()(Policy&& exec, Iterator iter)
{
auto is_even = [&](float64_t v) {
uint32_t i = (uint32_t)v;
return i % 2 == 0;
};
invoke_if(exec, [&]() { remove_if(exec, iter, iter, non_const(is_even)); });
}
};
int32_t
main()
{
#if !__PSTL_ICC_18_TEST_EARLY_EXIT_MONOTONIC_RELEASE_BROKEN
test<int32_t>(666, 42, [](int32_t val) { return true; }, [](size_t j) { return j; });
#endif
test<int32_t>(666, 2001, [](const int32_t& val) { return val != 2001; },
[](size_t j) { return ((j + 1) % 5 & 2) != 0 ? 2001 : -1 - int32_t(j); });
test<float64_t>(-666.0, 8.5, [](const float64_t& val) { return val != 8.5; },
[](size_t j) { return ((j + 1) % 7 & 2) != 0 ? 8.5 : float64_t(j % 32 + j); });
#if !__PSTL_ICC_17_TEST_MAC_RELEASE_32_BROKEN
test<Number>(Number(-666, OddTag()), Number(42, OddTag()), IsMultiple(3, OddTag()),
[](int32_t j) { return Number(j, OddTag()); });
#endif
test_algo_basic_single<int32_t>(run_for_rnd_fw<test_non_const>());
std::cout << done() << std::endl;
return 0;
}
// -*- C++ -*-
// { dg-options "-std=gnu++17 -ltbb" }
// { dg-do run { target c++17 } }
// { dg-require-effective-target tbb-backend }
//===-- remove_copy.pass.cpp ----------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "pstl/pstl_test_config.h"
#ifdef PSTL_STANDALONE_TESTS
#include "pstl/execution"
#include "pstl/algorithm"
#else
#include <execution>
#include <algorithm>
#endif // PSTL_STANDALONE_TESTS
#include "pstl/test_utils.h"
using namespace TestUtils;
struct run_remove_copy
{
template <typename Policy, typename InputIterator, typename OutputIterator, typename OutputIterator2, typename Size,
typename T>
void
operator()(Policy&& exec, InputIterator first, InputIterator last, OutputIterator out_first,
OutputIterator out_last, OutputIterator2 expected_first, OutputIterator2 expected_last, Size n,
const T& value, T trash)
{
// Cleaning
std::fill_n(expected_first, n, trash);
std::fill_n(out_first, n, trash);
// Run copy_if
auto i = remove_copy(first, last, expected_first, value);
auto k = remove_copy(exec, first, last, out_first, value);
EXPECT_EQ_N(expected_first, out_first, n, "wrong remove_copy effect");
for (size_t j = 0; j < GuardSize; ++j)
{
++k;
}
EXPECT_TRUE(out_last == k, "wrong return value from remove_copy");
}
};
template <typename T, typename Convert>
void
test(T trash, const T& value, Convert convert, bool check_weakness = true)
{
// Try sequences of various lengths.
for (size_t n = 0; n <= 100000; n = n <= 16 ? n + 1 : size_t(3.1415 * n))
{
// count is number of output elements, plus a handful
// more for sake of detecting buffer overruns.
size_t count = GuardSize;
Sequence<T> in(n, [&](size_t k) -> T {
T x = convert(n ^ k);
count += !(x == value) ? 1 : 0;
return x;
});
using namespace std;
Sequence<T> out(count, [=](size_t) { return trash; });
Sequence<T> expected(count, [=](size_t) { return trash; });
if (check_weakness)
{
auto expected_result = remove_copy(in.cfbegin(), in.cfend(), expected.begin(), value);
size_t m = expected_result - expected.begin();
EXPECT_TRUE(n / 4 <= m && m <= 3 * (n + 1) / 4, "weak test for remove_copy");
}
invoke_on_all_policies(run_remove_copy(), in.begin(), in.end(), out.begin(), out.end(), expected.begin(),
expected.end(), count, value, trash);
invoke_on_all_policies(run_remove_copy(), in.cbegin(), in.cend(), out.begin(), out.end(), expected.begin(),
expected.end(), count, value, trash);
}
}
int32_t
main()
{
test<float64_t>(-666.0, 8.5, [](size_t j) { return ((j + 1) % 7 & 2) != 0 ? 8.5 : float64_t(j % 32 + j); });
test<int32_t>(-666, 42, [](size_t j) { return ((j + 1) % 5 & 2) != 0 ? 42 : -1 - int32_t(j); });
test<Number>(Number(42, OddTag()), Number(2001, OddTag()),
[](int32_t j) { return ((j + 1) % 3 & 2) != 0 ? Number(2001, OddTag()) : Number(j, OddTag()); });
std::cout << done() << std::endl;
return 0;
}
// -*- C++ -*-
// { dg-options "-std=gnu++17 -ltbb" }
// { dg-do run { target c++17 } }
// { dg-require-effective-target tbb-backend }
//===-- replace.pass.cpp --------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "pstl/pstl_test_config.h"
#ifdef PSTL_STANDALONE_TESTS
#include "pstl/execution"
#include "pstl/algorithm"
#else
#include <execution>
#include <algorithm>
#endif // PSTL_STANDALONE_TESTS
#include "pstl/test_utils.h"
using namespace TestUtils;
// This class is needed to check the self-copying
struct copy_int
{
int32_t value;
int32_t copied_times = 0;
explicit copy_int(int32_t val = 0) { value = val; }
copy_int&
operator=(const copy_int& other)
{
if (&other == this)
copied_times++;
else
{
value = other.value;
copied_times = other.copied_times;
}
return *this;
}
bool
operator==(const copy_int& other) const
{
return (value == other.value);
}
};
template <typename Iterator>
struct test_one_policy
{
std::size_t len;
Iterator data_b;
Iterator data_e;
test_one_policy(Iterator data_, std::size_t len_)
{
len = len_;
data_b = data_;
data_e = std::next(data_b, len);
}
template <typename ExecutionPolicy, typename Iterator1, typename Iterator2, typename T, typename Predicate>
void
operator()(ExecutionPolicy&& exec, Iterator1 expected_b, Iterator1 expected_e, Iterator2 actual_b,
Iterator2 actual_e, Predicate pred, const T& value, const T& old_value)
{
using namespace std;
copy(data_b, data_e, expected_b);
copy(data_b, data_e, actual_b);
replace(expected_b, expected_e, old_value, value);
replace(exec, actual_b, actual_e, old_value, value);
EXPECT_TRUE((check<T, Iterator2>(actual_b, actual_e)), "wrong result of self assignment check");
EXPECT_TRUE(equal(expected_b, expected_e, actual_b), "wrong result of replace");
copy(data_b, data_e, expected_b);
copy(data_b, data_e, actual_b);
replace_if(expected_b, expected_e, pred, value);
replace_if(exec, actual_b, actual_e, pred, value);
EXPECT_TRUE(equal(expected_b, expected_e, actual_b), "wrong result of replace_if");
}
template <typename T, typename Iterator1>
bool
check(Iterator1 b, Iterator1 e)
{
return true;
}
template <typename T, typename Iterator1>
typename std::enable_if<std::is_same<T, copy_int>::value, bool>::type_t
check(Iterator1 b, Iterator1 e)
{
return std::all_of(b, e, [](const copy_int& elem) { return elem.copied_times == 0; });
}
};
template <typename T1, typename T2, typename Pred>
void
test(Pred pred)
{
typedef typename Sequence<T2>::iterator iterator_type;
const std::size_t max_len = 100000;
const T1 value = T1(0);
const T1 new_value = T1(666);
Sequence<T2> expected(max_len);
Sequence<T2> actual(max_len);
Sequence<T2> data(max_len, [&value](std::size_t i) {
if (i % 3 == 2)
{
return T1(i);
}
else
{
return value;
}
});
for (std::size_t len = 0; len < max_len; len = len <= 16 ? len + 1 : std::size_t(3.1415 * len))
{
test_one_policy<iterator_type> temp(data.begin(), len);
invoke_on_all_policies(temp, expected.begin(), expected.begin() + len, actual.begin(), actual.begin() + len,
pred, new_value, value);
}
}
template <typename T>
struct test_non_const
{
template <typename Policy, typename Iterator>
void
operator()(Policy&& exec, Iterator iter)
{
auto is_even = [&](float64_t v) {
uint32_t i = (uint32_t)v;
return i % 2 == 0;
};
invoke_if(exec, [&]() { replace_if(exec, iter, iter, non_const(is_even), T(0)); });
}
};
int32_t
main()
{
test<int32_t, float32_t>(__pstl::__internal::__equal_value<int32_t>(666));
test<uint16_t, uint8_t>([](const uint16_t& elem) { return elem % 3 < 2; });
test<float64_t, int64_t>([](const float64_t& elem) { return elem * elem - 3.5 * elem > 10; });
test<copy_int, copy_int>([](const copy_int& val) { return val.value / 5 > 2; });
test_algo_basic_single<int32_t>(run_for_rnd_fw<test_non_const<int32_t>>());
std::cout << done() << std::endl;
return 0;
}
// -*- C++ -*-
// { dg-options "-std=gnu++17 -ltbb" }
// { dg-do run { target c++17 } }
// { dg-require-effective-target tbb-backend }
//===-- replace_copy.pass.cpp ---------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
// Tests for replace_copy and replace_copy_if
#include "pstl/pstl_test_config.h"
#ifdef PSTL_STANDALONE_TESTS
#include "pstl/execution"
#include "pstl/algorithm"
#else
#include <execution>
#include <algorithm>
#endif // PSTL_STANDALONE_TESTS
#include "pstl/test_utils.h"
using namespace TestUtils;
struct test_replace_copy
{
template <typename Policy, typename InputIterator, typename OutputIterator, typename OutputIterator2, typename Size,
typename Predicate, typename T>
void
operator()(Policy&& exec, InputIterator first, InputIterator last, OutputIterator out_first,
OutputIterator out_last, OutputIterator2 expected_first, OutputIterator2 expected_last, Size n,
Predicate pred, const T& old_value, const T& new_value, T trash)
{
// Cleaning
std::fill_n(expected_first, n, trash);
std::fill_n(out_first, n, trash);
// Run replace_copy
auto i = std::replace_copy(first, last, expected_first, old_value, new_value);
auto k = std::replace_copy(exec, first, last, out_first, old_value, new_value);
EXPECT_EQ_N(expected_first, out_first, n, "wrong replace_copy effect");
EXPECT_TRUE(out_last == k, "wrong return value from replace_copy");
// Cleaning
std::fill_n(expected_first, n, trash);
std::fill_n(out_first, n, trash);
// Run replace_copy_if
i = replace_copy_if(first, last, expected_first, pred, new_value);
k = replace_copy_if(exec, first, last, out_first, pred, new_value);
EXPECT_EQ_N(expected_first, out_first, n, "wrong replace_copy_if effect");
EXPECT_TRUE(out_last == k, "wrong return value from replace_copy_if");
}
};
template <typename T, typename Convert, typename Predicate>
void
test(T trash, const T& old_value, const T& new_value, Predicate pred, Convert convert)
{
// Try sequences of various lengths.
for (size_t n = 0; n <= 100000; n = n <= 16 ? n + 1 : size_t(3.1415 * n))
{
Sequence<T> in(n, [&](size_t k) -> T { return convert(n ^ k); });
Sequence<T> out(n, [=](size_t) { return trash; });
Sequence<T> expected(n, [=](size_t) { return trash; });
invoke_on_all_policies(test_replace_copy(), in.begin(), in.end(), out.begin(), out.end(), expected.begin(),
expected.end(), out.size(), pred, old_value, new_value, trash);
invoke_on_all_policies(test_replace_copy(), in.cbegin(), in.cend(), out.begin(), out.end(), expected.begin(),
expected.end(), out.size(), pred, old_value, new_value, trash);
}
}
template <typename T>
struct test_non_const
{
template <typename Policy, typename InputIterator, typename OutputInterator>
void
operator()(Policy&& exec, InputIterator input_iter, OutputInterator out_iter)
{
auto is_even = [&](float64_t v) {
uint32_t i = (uint32_t)v;
return i % 2 == 0;
};
invoke_if(exec, [&]() { replace_copy_if(exec, input_iter, input_iter, out_iter, non_const(is_even), T(0)); });
}
};
int32_t
main()
{
test<float64_t>(-666.0, 8.5, 0.33, [](const float64_t& x) { return x * x <= 1024; },
[](size_t j) { return ((j + 1) % 7 & 2) != 0 ? 8.5 : float64_t(j % 32 + j); });
test<int32_t>(-666, 42, 99, [](const int32_t& x) { return x != 42; },
[](size_t j) { return ((j + 1) % 5 & 2) != 0 ? 42 : -1 - int32_t(j); });
#if !__PSTL_ICC_17_TEST_MAC_RELEASE_32_BROKEN
test<Number>(Number(42, OddTag()), Number(2001, OddTag()), Number(2017, OddTag()), IsMultiple(3, OddTag()),
[](int32_t j) { return ((j + 1) % 3 & 2) != 0 ? Number(2001, OddTag()) : Number(j, OddTag()); });
#endif
test_algo_basic_double<int32_t>(run_for_rnd_fw<test_non_const<int32_t>>());
std::cout << done() << std::endl;
return 0;
}
// -*- C++ -*-
// { dg-options "-std=gnu++17 -ltbb" }
// { dg-do run { target c++17 } }
// { dg-require-effective-target tbb-backend }
//===-- rotate.pass.cpp ---------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "pstl/pstl_test_config.h"
#ifdef PSTL_STANDALONE_TESTS
#include <iterator>
#include "pstl/execution"
#include "pstl/algorithm"
#else
#include <execution>
#include <algorithm>
#endif // PSTL_STANDALONE_TESTS
#include "pstl/test_utils.h"
using namespace TestUtils;
template <typename T>
struct wrapper
{
T t;
int move_count;
explicit wrapper(T t_) : t(t_), move_count(0) {}
wrapper&
operator=(const T& t_)
{
t = t_;
return *this;
}
wrapper(const wrapper<T>& a) : move_count(0) { t = a.t; }
wrapper<T>&
operator=(wrapper<T>& a)
{
t = a.t;
return *this;
}
wrapper<T>&
operator=(wrapper<T>&& a)
{
t = a.t;
move_count += 1;
return *this;
}
};
template <typename T>
struct compare
{
bool
operator()(const T& a, const T& b)
{
return a == b;
}
};
template <typename T>
struct compare<wrapper<T>>
{
bool
operator()(const wrapper<T>& a, const wrapper<T>& b)
{
return a.t == b.t;
}
};
#include <typeinfo>
struct test_one_policy
{
#if __PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN || \
__PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN // dummy specializations to skip testing in case of broken configuration
template <typename Iterator, typename Size>
void
operator()(__pstl::execution::unsequenced_policy, Iterator data_b, Iterator data_e, Iterator actual_b,
Iterator actual_e, Size shift)
{
}
template <typename Iterator, typename Size>
void
operator()(__pstl::execution::parallel_unsequenced_policy, Iterator data_b, Iterator data_e, Iterator actual_b,
Iterator actual_e, Size shift)
{
}
#endif
template <typename ExecutionPolicy, typename Iterator, typename Size>
void
operator()(ExecutionPolicy&& exec, Iterator data_b, Iterator data_e, Iterator actual_b, Iterator actual_e,
Size shift)
{
using namespace std;
using T = typename iterator_traits<Iterator>::value_type;
Iterator actual_m = std::next(actual_b, shift);
copy(data_b, data_e, actual_b);
Iterator actual_return = rotate(exec, actual_b, actual_m, actual_e);
EXPECT_TRUE(actual_return == std::next(actual_b, std::distance(actual_m, actual_e)), "wrong result of rotate");
auto comparator = compare<T>();
bool check = std::equal(actual_return, actual_e, data_b, comparator);
check = check && std::equal(actual_b, actual_return, std::next(data_b, shift), comparator);
EXPECT_TRUE(check, "wrong effect of rotate");
EXPECT_TRUE(check_move(exec, actual_b, actual_e, shift), "wrong move test of rotate");
}
template <typename ExecutionPolicy, typename Iterator, typename Size>
typename std::enable_if<
is_same_iterator_category<Iterator, std::random_access_iterator_tag>::value &&
!std::is_same<ExecutionPolicy, __pstl::execution::sequenced_policy>::value &&
std::is_same<typename std::iterator_traits<Iterator>::value_type, wrapper<float32_t>>::value,
bool>::type
check_move(ExecutionPolicy&& exec, Iterator b, Iterator e, Size shift)
{
bool result = all_of(b, e, [](wrapper<float32_t>& a) {
bool temp = a.move_count > 0;
a.move_count = 0;
return temp;
});
return shift == 0 || result;
}
template <typename ExecutionPolicy, typename Iterator, typename Size>
typename std::enable_if<
!(is_same_iterator_category<Iterator, std::random_access_iterator_tag>::value &&
!std::is_same<ExecutionPolicy, __pstl::execution::sequenced_policy>::value &&
std::is_same<typename std::iterator_traits<Iterator>::value_type, wrapper<float32_t>>::value),
bool>::type
check_move(ExecutionPolicy&& exec, Iterator b, Iterator e, Size shift)
{
return true;
}
};
template <typename T>
void
test()
{
const int32_t max_len = 100000;
Sequence<T> actual(max_len, [](std::size_t i) { return T(i); });
Sequence<T> data(max_len, [](std::size_t i) { return T(i); });
for (int32_t len = 0; len < max_len; len = len <= 16 ? len + 1 : int32_t(3.1415 * len))
{
int32_t shifts[] = {0, 1, 2, len / 3, (2 * len) / 3, len - 1};
for (auto shift : shifts)
{
if (shift >= 0 && shift < len)
{
invoke_on_all_policies(test_one_policy(), data.begin(), data.begin() + len, actual.begin(),
actual.begin() + len, shift);
}
}
}
}
int32_t
main()
{
test<int32_t>();
test<wrapper<float64_t>>();
std::cout << done() << std::endl;
return 0;
}
// -*- C++ -*-
// { dg-options "-std=gnu++17 -ltbb" }
// { dg-do run { target c++17 } }
// { dg-require-effective-target tbb-backend }
//===-- rotate_copy.pass.cpp ----------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "pstl/pstl_test_config.h"
#ifdef PSTL_STANDALONE_TESTS
#include <iterator>
#include "pstl/execution"
#include "pstl/algorithm"
#else
#include <execution>
#include <algorithm>
#endif // PSTL_STANDALONE_TESTS
#include "pstl/test_utils.h"
using namespace TestUtils;
template <typename T>
struct wrapper;
template <typename T>
bool
compare(const wrapper<T>& a, const wrapper<T>& b)
{
return a.t == b.t;
}
template <typename T>
bool
compare(const T& a, const T& b)
{
return a == b;
}
template <typename T>
struct wrapper
{
explicit wrapper(T t_) : t(t_) {}
wrapper&
operator=(const T& t_)
{
t = t_;
return *this;
}
friend bool
compare<T>(const wrapper<T>& a, const wrapper<T>& b);
private:
T t;
};
template <typename T, typename It1, typename It2>
struct comparator
{
using T1 = typename std::iterator_traits<It1>::value_type;
using T2 = typename std::iterator_traits<It2>::value_type;
bool
operator()(T1 a, T2 b)
{
T temp = a;
return compare(temp, b);
}
};
struct test_one_policy
{
#if __PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN || \
__PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN // dummy specialization by policy type, in case of broken configuration
template <typename Iterator1, typename Iterator2>
typename std::enable_if<is_same_iterator_category<Iterator1, std::random_access_iterator_tag>::value, void>::type
operator()(pstl::execution::unsequenced_policy, Iterator1 data_b, Iterator1 data_e, Iterator2 actual_b,
Iterator2 actual_e, std::size_t shift)
{
}
template <typename Iterator1, typename Iterator2>
typename std::enable_if<is_same_iterator_category<Iterator1, std::random_access_iterator_tag>::value, void>::type
operator()(pstl::execution::parallel_unsequenced_policy, Iterator1 data_b, Iterator1 data_e, Iterator2 actual_b,
Iterator2 actual_e, std::size_t shift)
{
}
#endif
template <typename ExecutionPolicy, typename Iterator1, typename Iterator2>
void
operator()(ExecutionPolicy&& exec, Iterator1 data_b, Iterator1 data_e, Iterator2 actual_b, Iterator2 actual_e,
std::size_t shift)
{
using namespace std;
using T = typename iterator_traits<Iterator2>::value_type;
Iterator1 data_m = std::next(data_b, shift);
fill(actual_b, actual_e, T(-123));
Iterator2 actual_return = rotate_copy(exec, data_b, data_m, data_e, actual_b);
EXPECT_TRUE(actual_return == actual_e, "wrong result of rotate_copy");
auto comparer = comparator<T, Iterator1, Iterator2>();
bool check = std::equal(data_m, data_e, actual_b, comparer);
check = check && std::equal(data_b, data_m, std::next(actual_b, std::distance(data_m, data_e)), comparer);
EXPECT_TRUE(check, "wrong effect of rotate_copy");
}
};
template <typename T1, typename T2>
void
test()
{
const std::size_t max_len = 100000;
Sequence<T2> actual(max_len, [](std::size_t i) { return T1(i); });
Sequence<T1> data(max_len, [](std::size_t i) { return T1(i); });
for (std::size_t len = 0; len < max_len; len = len <= 16 ? len + 1 : std::size_t(3.1415 * len))
{
std::size_t shifts[] = {0, 1, 2, len / 3, (2 * len) / 3, len - 1};
for (std::size_t shift : shifts)
{
if (shift > 0 && shift < len)
{
invoke_on_all_policies(test_one_policy(), data.begin(), data.begin() + len, actual.begin(),
actual.begin() + len, shift);
invoke_on_all_policies(test_one_policy(), data.cbegin(), data.cbegin() + len, actual.begin(),
actual.begin() + len, shift);
}
}
}
}
int32_t
main()
{
test<int32_t, int8_t>();
test<uint16_t, float32_t>();
test<float64_t, int64_t>();
test<wrapper<float64_t>, wrapper<float64_t>>();
std::cout << done() << std::endl;
return 0;
}
// -*- C++ -*-
// { dg-options "-std=gnu++17 -ltbb" }
// { dg-do run { target c++17 } }
// { dg-require-effective-target tbb-backend }
//===-- swap_ranges.pass.cpp ----------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "pstl/pstl_test_config.h"
#ifdef PSTL_STANDALONE_TESTS
#include <iterator>
#include "pstl/execution"
#include "pstl/algorithm"
#else
#include <execution>
#include <algorithm>
#endif // PSTL_STANDALONE_TESTS
#include "pstl/test_utils.h"
using namespace TestUtils;
template <typename T>
struct wrapper
{
T t;
std::size_t number_of_swaps = 0;
wrapper() {}
explicit wrapper(T t_) : t(t_) {}
template <typename U>
void
operator=(const U& b)
{
t = b;
}
bool
operator==(const wrapper<T>& a) const
{
return t == a.t;
}
};
template <typename T>
void
swap(wrapper<T>& a, wrapper<T>& b)
{
std::swap(a.t, b.t);
a.number_of_swaps++;
b.number_of_swaps++;
}
template <typename T>
struct check_swap
{
bool
operator()(T& a)
{
return true;
}
};
template <typename T>
struct check_swap<wrapper<T>>
{
bool
operator()(wrapper<T>& a)
{
bool temp = (a.number_of_swaps == 1);
a.number_of_swaps = 0;
return temp;
}
};
struct test_one_policy
{
template <typename ExecutionPolicy, typename Iterator1, typename Iterator2>
void
operator()(ExecutionPolicy&& exec, Iterator1 data_b, Iterator1 data_e, Iterator2 actual_b, Iterator2 actual_e)
{
using namespace std;
using T_ref = typename iterator_traits<Iterator1>::reference;
using T = typename iterator_traits<Iterator1>::value_type;
iota(data_b, data_e, 0);
iota(actual_b, actual_e, std::distance(data_b, data_e));
Iterator2 actual_return = swap_ranges(exec, data_b, data_e, actual_b);
bool check_return = (actual_return == actual_e);
EXPECT_TRUE(check_return, "wrong result of swap_ranges");
if (check_return)
{
std::size_t i = 0;
bool check = all_of(actual_b, actual_e, [&i](T_ref a) { return a == T(i++); }) &&
all_of(data_b, data_e, [&i](T_ref a) { return a == T(i++); });
EXPECT_TRUE(check, "wrong effect of swap_ranges");
if (check)
{
bool swap_check =
all_of(data_b, data_e, check_swap<T>()) && all_of(actual_b, actual_e, check_swap<T>());
EXPECT_TRUE(swap_check, "wrong effect of swap_ranges swap check");
}
}
}
};
template <typename T>
void
test()
{
const std::size_t max_len = 100000;
Sequence<T> data(max_len);
Sequence<T> actual(max_len);
for (std::size_t len = 0; len < max_len; len = len <= 16 ? len + 1 : std::size_t(3.1415 * len))
{
invoke_on_all_policies(test_one_policy(), data.begin(), data.begin() + len, actual.begin(),
actual.begin() + len);
}
}
int32_t
main()
{
test<wrapper<uint16_t>>();
test<wrapper<float64_t>>();
test<int32_t>();
test<float32_t>();
std::cout << done() << std::endl;
return 0;
}
// -*- C++ -*-
// { dg-options "-std=gnu++17 -ltbb" }
// { dg-do run { target c++17 } }
// { dg-require-effective-target tbb-backend }
//===-- transform_binary.pass.cpp -----------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "pstl/pstl_test_config.h"
#ifdef PSTL_STANDALONE_TESTS
#include "pstl/execution"
#include "pstl/algorithm"
#else
#include <execution>
#include <algorithm>
#endif // PSTL_STANDALONE_TESTS
#include "pstl/test_utils.h"
using namespace TestUtils;
template <typename In1, typename In2, typename Out>
class TheOperation
{
Out val;
public:
TheOperation(Out v) : val(v) {}
Out
operator()(const In1& x, const In2& y) const
{
return Out(val + x - y);
}
};
template <typename InputIterator1, typename InputIterator2, typename OutputIterator>
void
check_and_reset(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, OutputIterator out_first)
{
typedef typename std::iterator_traits<OutputIterator>::value_type Out;
typename std::iterator_traits<OutputIterator>::difference_type k = 0;
for (; first1 != last1; ++first1, ++first2, ++out_first, ++k)
{
// check
Out expected = Out(1.5) + *first1 - *first2;
Out actual = *out_first;
if (std::is_floating_point<Out>::value)
{
EXPECT_TRUE((expected > actual ? expected - actual : actual - expected) < 1e7,
"wrong value in output sequence");
}
else
{
EXPECT_EQ(expected, actual, "wrong value in output sequence");
}
// reset
*out_first = k % 7 != 4 ? 7 * k - 5 : 0;
}
}
struct test_one_policy
{
template <typename Policy, typename InputIterator1, typename InputIterator2, typename OutputIterator,
typename BinaryOp>
void
operator()(Policy&& exec, InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2,
OutputIterator out_first, OutputIterator out_last, BinaryOp op)
{
auto orrr = std::transform(exec, first1, last1, first2, out_first, op);
check_and_reset(first1, last1, first2, out_first);
}
};
template <typename In1, typename In2, typename Out, typename Predicate>
void
test(Predicate pred)
{
for (size_t n = 0; n <= 100000; n = n <= 16 ? n + 1 : size_t(3.1415 * n))
{
Sequence<In1> in1(n, [](size_t k) { return k % 5 != 1 ? 3 * k - 7 : 0; });
Sequence<In2> in2(n, [](size_t k) { return k % 7 != 2 ? 5 * k - 5 : 0; });
Sequence<Out> out(n, [](size_t k) { return -1; });
invoke_on_all_policies(test_one_policy(), in1.begin(), in1.end(), in2.begin(), in2.end(), out.begin(),
out.end(), pred);
invoke_on_all_policies(test_one_policy(), in1.cbegin(), in1.cend(), in2.cbegin(), in2.cend(), out.begin(),
out.end(), pred);
}
}
template <typename T>
struct test_non_const
{
template <typename Policy, typename InputIterator, typename OutputInterator>
void
operator()(Policy&& exec, InputIterator input_iter, OutputInterator out_iter)
{
invoke_if(exec, [&]() {
InputIterator input_iter2 = input_iter;
transform(exec, input_iter, input_iter, input_iter2, out_iter, non_const(std::plus<T>()));
});
}
};
int32_t
main()
{
//const operator()
test<int32_t, int32_t, int32_t>(TheOperation<int32_t, int32_t, int32_t>(1));
test<float32_t, float32_t, float32_t>(TheOperation<float32_t, float32_t, float32_t>(1.5));
//non-const operator()
test<int32_t, float32_t, float32_t>(non_const(TheOperation<int32_t, float32_t, float32_t>(1.5)));
test<int64_t, float64_t, float32_t>(non_const(TheOperation<int64_t, float64_t, float32_t>(1.5)));
//lambda
test<int8_t, float64_t, int8_t>([](const int8_t& x, const float64_t& y) { return int8_t(int8_t(1.5) + x - y); });
test_algo_basic_double<int32_t>(run_for_rnd_fw<test_non_const<int32_t>>());
std::cout << done() << std::endl;
return 0;
}
// -*- C++ -*-
// { dg-options "-std=gnu++17 -ltbb" }
// { dg-do run { target c++17 } }
// { dg-require-effective-target tbb-backend }
//===-- transform_unary.pass.cpp ------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "pstl/pstl_test_config.h"
#ifdef PSTL_STANDALONE_TESTS
#include "pstl/execution"
#include "pstl/algorithm"
#else
#include <execution>
#include <algorithm>
#endif // PSTL_STANDALONE_TESTS
#include "pstl/test_utils.h"
using namespace TestUtils;
template <typename InputIterator, typename OutputIterator>
void
check_and_reset(InputIterator first, InputIterator last, OutputIterator out_first)
{
typedef typename std::iterator_traits<OutputIterator>::value_type Out;
typename std::iterator_traits<OutputIterator>::difference_type k = 0;
for (; first != last; ++first, ++out_first, ++k)
{
// check
Out expected = 1 - *first;
Out actual = *out_first;
EXPECT_EQ(expected, actual, "wrong value in output sequence");
// reset
*out_first = k % 7 != 4 ? 7 * k - 5 : 0;
}
}
struct test_one_policy
{
template <typename Policy, typename InputIterator, typename OutputIterator, typename UnaryOp>
void
operator()(Policy&& exec, InputIterator first, InputIterator last, OutputIterator out_first,
OutputIterator out_last, UnaryOp op)
{
auto orr = std::transform(exec, first, last, out_first, op);
EXPECT_TRUE(out_last == orr, "transform returned wrong iterator");
check_and_reset(first, last, out_first);
}
};
template <typename Tin, typename Tout>
void
test()
{
for (size_t n = 0; n <= 100000; n = n <= 16 ? n + 1 : size_t(3.1415 * n))
{
Sequence<Tin> in(n, [](int32_t k) { return k % 5 != 1 ? 3 * k - 7 : 0; });
Sequence<Tout> out(n);
const auto flip = Complement<Tin, Tout>(1);
invoke_on_all_policies(test_one_policy(), in.begin(), in.end(), out.begin(), out.end(), flip);
invoke_on_all_policies(test_one_policy(), in.cbegin(), in.cend(), out.begin(), out.end(), flip);
}
}
template <typename T>
struct test_non_const
{
template <typename Policy, typename InputIterator, typename OutputInterator>
void
operator()(Policy&& exec, InputIterator input_iter, OutputInterator out_iter)
{
invoke_if(exec, [&]() { transform(exec, input_iter, input_iter, out_iter, non_const(std::negate<T>())); });
}
};
int32_t
main()
{
test<int32_t, int32_t>();
test<int32_t, float32_t>();
test<uint16_t, float32_t>();
test<float32_t, float64_t>();
test<float64_t, float64_t>();
test_algo_basic_double<int32_t>(run_for_rnd_fw<test_non_const<int32_t>>());
std::cout << done() << std::endl;
return 0;
}
// -*- C++ -*-
// { dg-options "-std=gnu++17 -ltbb" }
// { dg-do run { target c++17 } }
// { dg-require-effective-target tbb-backend }
//===-- unique.pass.cpp ---------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
// Test for unique
#include "pstl/pstl_test_config.h"
#ifdef PSTL_STANDALONE_TESTS
#include "pstl/execution"
#include "pstl/algorithm"
#else
#include <execution>
#include <algorithm>
#endif // PSTL_STANDALONE_TESTS
#include "pstl/test_utils.h"
using namespace TestUtils;
struct run_unique
{
#if __PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN || \
__PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN //dummy specialization by policy type, in case of broken configuration
template <typename ForwardIt, typename Generator>
void
operator()(pstl::execution::unsequenced_policy, ForwardIt first1, ForwardIt last1, ForwardIt first2,
ForwardIt last2, Generator generator)
{
}
template <typename ForwardIt, typename Generator>
void
operator()(pstl::execution::parallel_unsequenced_policy, ForwardIt first1, ForwardIt last1, ForwardIt first2,
ForwardIt last2, Generator generator)
{
}
template <typename ForwardIt, typename BinaryPred, typename Generator>
void
operator()(pstl::execution::unsequenced_policy, ForwardIt first1, ForwardIt last1, ForwardIt first2,
ForwardIt last2, BinaryPred pred, Generator generator)
{
}
template <typename ForwardIt, typename BinaryPred, typename Generator>
void
operator()(pstl::execution::parallel_unsequenced_policy, ForwardIt first1, ForwardIt last1, ForwardIt first2,
ForwardIt last2, BinaryPred pred, Generator generator)
{
}
#endif
template <typename Policy, typename ForwardIt, typename Generator>
void
operator()(Policy&& exec, ForwardIt first1, ForwardIt last1, ForwardIt first2, ForwardIt last2, Generator generator)
{
using namespace std;
// Preparation
fill_data(first1, last1, generator);
fill_data(first2, last2, generator);
ForwardIt i = unique(first1, last1);
ForwardIt k = unique(exec, first2, last2);
auto n = std::distance(first1, i);
EXPECT_TRUE(std::distance(first2, k) == n, "wrong return value from unique without predicate");
EXPECT_EQ_N(first1, first2, n, "wrong effect from unique without predicate");
}
template <typename Policy, typename ForwardIt, typename BinaryPred, typename Generator>
void
operator()(Policy&& exec, ForwardIt first1, ForwardIt last1, ForwardIt first2, ForwardIt last2, BinaryPred pred,
Generator generator)
{
using namespace std;
// Preparation
fill_data(first1, last1, generator);
fill_data(first2, last2, generator);
ForwardIt i = unique(first1, last1, pred);
ForwardIt k = unique(exec, first2, last2, pred);
auto n = std::distance(first1, i);
EXPECT_TRUE(std::distance(first2, k) == n, "wrong return value from unique with predicate");
EXPECT_EQ_N(first1, first2, n, "wrong effect from unique with predicate");
}
};
template <typename T, typename Generator, typename Predicate>
void
test(Generator generator, Predicate pred)
{
const std::size_t max_size = 1000000;
Sequence<T> in(max_size, [](size_t v) { return T(v); });
Sequence<T> exp(max_size, [](size_t v) { return T(v); });
for (size_t n = 0; n <= max_size; n = n <= 16 ? n + 1 : size_t(3.1415 * n))
{
invoke_on_all_policies(run_unique(), exp.begin(), exp.begin() + n, in.begin(), in.begin() + n, generator);
invoke_on_all_policies(run_unique(), exp.begin(), exp.begin() + n, in.begin(), in.begin() + n, pred, generator);
}
}
template <typename T>
struct LocalWrapper
{
T my_val;
explicit LocalWrapper(T k) : my_val(k) {}
LocalWrapper(LocalWrapper&& input) : my_val(std::move(input.my_val)) {}
LocalWrapper&
operator=(LocalWrapper&& input)
{
my_val = std::move(input.my_val);
return *this;
}
friend bool
operator==(const LocalWrapper<T>& x, const LocalWrapper<T>& y)
{
return x.my_val == y.my_val;
}
};
template <typename T>
struct test_non_const
{
template <typename Policy, typename Iterator>
void
operator()(Policy&& exec, Iterator iter)
{
invoke_if(exec, [&]() { unique(exec, iter, iter, non_const(std::equal_to<T>())); });
}
};
int32_t
main()
{
#if !__PSTL_ICC_16_17_18_TEST_UNIQUE_MASK_RELEASE_BROKEN
test<int32_t>([](size_t j) { return j / 3; },
[](const int32_t& val1, const int32_t& val2) { return val1 * val1 == val2 * val2; });
test<float64_t>([](size_t) { return float64_t(1); },
[](const float64_t& val1, const float64_t& val2) { return val1 != val2; });
#endif
test<LocalWrapper<uint32_t>>([](size_t j) { return LocalWrapper<uint32_t>(j); },
[](const LocalWrapper<uint32_t>& val1, const LocalWrapper<uint32_t>& val2) {
return val1.my_val != val2.my_val;
});
test_algo_basic_single<int32_t>(run_for_rnd_fw<test_non_const<int32_t>>());
std::cout << done() << std::endl;
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment