diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 5d43c4c9..959ed4c1 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -2,3 +2,4 @@ add_subdirectory(array) add_subdirectory(edge_index_graph) add_subdirectory(blackscholes) add_subdirectory(pi) +add_subdirectory(stl_algorithm) diff --git a/examples/stl_algorithm/CMakeLists.txt b/examples/stl_algorithm/CMakeLists.txt new file mode 100644 index 00000000..4bf3b856 --- /dev/null +++ b/examples/stl_algorithm/CMakeLists.txt @@ -0,0 +1,6 @@ +set(program array unordered_set unordered_map) + +foreach(p ${program}) + add_executable(${p} ${p}.cc) + target_link_libraries(${p} ${SHAD_RUNTIME_LIB} runtime) +endforeach(p) diff --git a/examples/stl_algorithm/array.cc b/examples/stl_algorithm/array.cc new file mode 100644 index 00000000..80a0847e --- /dev/null +++ b/examples/stl_algorithm/array.cc @@ -0,0 +1,143 @@ +//===------------------------------------------------------------*- C++ -*-===// +// +// SHAD +// +// The Scalable High-performance Algorithms and Data Structure Library +// +//===----------------------------------------------------------------------===// +// +// Copyright 2018 Battelle Memorial Institute +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy +// of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. +// +//===----------------------------------------------------------------------===/ + +#include +#include +#include + +#include "shad/core/algorithm.h" +#include "shad/core/array.h" +#include "shad/util/measure.h" + +constexpr static size_t kArraySize = 1024; +using array_t = shad::impl::array; +using iterator = array_t::iterator; + +void shad_generate_algorithm(shad::array &in) { + shad::generate(shad::distributed_parallel_tag{}, in.begin(), in.end(), [=]() { + std::random_device rd; + std::default_random_engine G(rd()); + std::uniform_int_distribution dist(1, 10); + return dist(G); + }); +} + +void shad_fill_algorithm(shad::array &in) { + shad::fill(shad::distributed_parallel_tag{}, in.begin(), in.end(), 42); +} + +size_t shad_count_algorithm(shad::array &in) { + auto counter = + shad::count(shad::distributed_parallel_tag{}, in.begin(), in.end(), 1); + return counter; +} + +iterator shad_find_if_algorithm(shad::array &in) { + auto iter = shad::find_if(shad::distributed_parallel_tag{}, in.begin(), + in.end(), [](int i) { return i % 2 == 0; }); + return iter; +} + +void shad_for_each_algorithm(shad::array &in) { + shad::for_each(shad::distributed_parallel_tag{}, in.begin(), in.end(), + [](int &i) { i++; }); +} + +std::pair shad_minmax_algorithm( + shad::array &in) { + auto res = shad::minmax_element(shad::distributed_parallel_tag{}, in.begin(), + in.end()); + return res; +} + +void shad_transform_algorithm(shad::array &in) { + shad::transform(shad::distributed_parallel_tag{}, in.begin(), in.end(), + in.begin(), [](int i) { return i + 2; }); +} + +namespace shad { + +int main(int argc, char *argv[]) { + // array + shad::array in; + + // shad fill algorithm + auto execute_time = shad::measure::duration( + [&]() { shad_fill_algorithm(in); }); + std::cout << "Array, using " << shad::rt::numLocalities() + << " localities, shad::fill took " << execute_time.count() + << " seconds" << std::endl; + + // shad generate algorithm + execute_time = shad::measure::duration( + [&]() { shad_generate_algorithm(in); }); + std::cout << "Array, using " << shad::rt::numLocalities() + << " localities, shad::generate took " << execute_time.count() + << " seconds" << std::endl; + + // shad count algorithm + size_t counter; + execute_time = shad::measure::duration( + [&]() { counter = shad_count_algorithm(in); }); + std::cout << "Array, using " << shad::rt::numLocalities() + << " localities, shad::count took " << execute_time.count() + << " seconds (numbers of 0 = " << counter << " )" << std::endl; + + // shad find_if algorithm + iterator iter; + execute_time = shad::measure::duration( + [&]() { iter = shad_find_if_algorithm(in); }); + std::cout << "Array, using " << shad::rt::numLocalities() + << " localities, shad::find_if took " << execute_time.count() + << " seconds, "; + (iter != in.end()) + ? std::cout << "array contains an even number" << std::endl + : std::cout << "array does not contain even numbers" << std::endl; + + // shad for_each algorithm + execute_time = shad::measure::duration( + [&]() { shad_for_each_algorithm(in); }); + std::cout << "Array, using " << shad::rt::numLocalities() + << " localities, shad::for_each took " << execute_time.count() + << " seconds" << std::endl; + + // shad minmax algorithm + std::pair min_max; + execute_time = shad::measure::duration( + [&]() { min_max = shad_minmax_algorithm(in); }); + std::cout << "Array, using " << shad::rt::numLocalities() + << " localities, shad::minmax took " << execute_time.count() + << " seconds" << std::endl; + + // shad transform algorithm + execute_time = shad::measure::duration( + [&]() { shad_transform_algorithm(in); }); + std::cout << "Array, using " << shad::rt::numLocalities() + << " localities, shad::transform took " << execute_time.count() + << " seconds" << std::endl; + + return 0; +} + +} // namespace shad diff --git a/examples/stl_algorithm/unordered_map.cc b/examples/stl_algorithm/unordered_map.cc new file mode 100644 index 00000000..30fb021f --- /dev/null +++ b/examples/stl_algorithm/unordered_map.cc @@ -0,0 +1,145 @@ +//===------------------------------------------------------------*- C++ -*-===// +// +// SHAD +// +// The Scalable High-performance Algorithms and Data Structure Library +// +//===----------------------------------------------------------------------===// +// +// Copyright 2018 Battelle Memorial Institute +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy +// of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. +// +//===----------------------------------------------------------------------===/ + +#include + +#include "shad/core/algorithm.h" +#include "shad/core/unordered_map.h" +#include "shad/util/measure.h" + +constexpr static size_t kSize = 1024; +using hashmap_t = + shad::Hashmap, shad::Updater>; +using iterator = hashmap_t::iterator; +using value_type = hashmap_t::value_type; +using shad_inserter_t = shad::insert_iterator>; +using shad_buffered_inserter_t = + shad::buffered_insert_iterator>; + +std::pair shad_minmax_algorithm( + shad::unordered_map &in) { + auto res = shad::minmax_element(shad::distributed_parallel_tag{}, in.begin(), + in.end()); + return res; +} + +iterator shad_find_if_algorithm(shad::unordered_map &in) { + auto iter = + shad::find_if(shad::distributed_parallel_tag{}, in.begin(), in.end(), + [](const value_type &i) { return i.second % 2 == 0; }); + return iter; +} + +bool shad_any_of_algorithm(shad::unordered_map &in) { + auto res = + shad::any_of(shad::distributed_parallel_tag{}, in.begin(), in.end(), + [](const value_type &i) { return i.second % 7 == 0; }); + return res; +} + +size_t shad_count_if_algorithm(shad::unordered_map &in) { + auto counter = + shad::count_if(shad::distributed_parallel_tag{}, in.begin(), in.end(), + [](const value_type &i) { return i.second % 4 == 0; }); + return counter; +} + +template +void shad_transform_algorithm(shad::unordered_map &in) { + shad::unordered_map out; + shad::transform(shad::distributed_parallel_tag{}, in.begin(), in.end(), + shad_inserter(out, out.begin()), + [](const value_type &i) { return i; }); +} + +namespace shad { + +int main(int argc, char *argv[]) { + // unordered_map + shad::unordered_map map_; + + // create map + shad_buffered_inserter_t ins(map_, map_.begin()); + for (size_t i = 0; i < kSize; ++i) { + ins = std::make_pair(i, 3 * (i + 1)); + } + ins.wait(); + ins.flush(); + + // shad minmax algorithm + std::pair min_max; + auto execute_time = shad::measure::duration( + [&]() { min_max = shad_minmax_algorithm(map_); }); + std::cout << "Unordered map, using " << shad::rt::numLocalities() + << " localities, shad::count took " << execute_time.count() + << " seconds (min = " << (*min_max.first).second + << ", max = " << (*min_max.second).second << " )" << std::endl; + + // shad find_if algorithm + iterator iter; + execute_time = shad::measure::duration( + [&]() { iter = shad_find_if_algorithm(map_); }); + std::cout << "Unordered map, using " << shad::rt::numLocalities() + << " localities, shad::find_if took " << execute_time.count() + << " seconds, "; + (iter != map_.end()) + ? std::cout << "and this unordered map contains an even number" + << std::endl + : std::cout << "and this unordered map does not contain even numbers" + << std::endl; + + // shad any_of algorithm + bool res; + execute_time = shad::measure::duration( + [&]() { res = shad_any_of_algorithm(map_); }); + std::cout << "Unordered map, using " << shad::rt::numLocalities() + << " localities, shad::any_of took " << execute_time.count() + << " seconds, "; + (res == true) ? std::cout << "and this unordered map contains at least one " + "number that is divisible by 7" + << std::endl + : std::cout << "and this unordered map does not contain any " + "number that is divisible by 7" + << std::endl; + + // shad count_if algorithm + size_t counter; + execute_time = shad::measure::duration( + [&]() { counter = shad_count_if_algorithm(map_); }); + std::cout << "Unordered map, using " << shad::rt::numLocalities() + << " localities, shad::count_if took " << execute_time.count() + << " seconds, " + << "and number divisible by 4: " << counter << std::endl; + + // shad transform algorithm + execute_time = shad::measure::duration( + [&]() { shad_transform_algorithm(map_); }); + std::cout << "Unordered map, using " << shad::rt::numLocalities() + << " localities, shad::transform took " << execute_time.count() + << " seconds" << std::endl; + + return 0; +} + +} // namespace shad \ No newline at end of file diff --git a/examples/stl_algorithm/unordered_set.cc b/examples/stl_algorithm/unordered_set.cc new file mode 100644 index 00000000..79002915 --- /dev/null +++ b/examples/stl_algorithm/unordered_set.cc @@ -0,0 +1,144 @@ +//===------------------------------------------------------------*- C++ -*-===// +// +// SHAD +// +// The Scalable High-performance Algorithms and Data Structure Library +// +//===----------------------------------------------------------------------===// +// +// Copyright 2018 Battelle Memorial Institute +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy +// of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. +// +//===----------------------------------------------------------------------===/ + +#include + +#include "shad/core/algorithm.h" +#include "shad/core/unordered_set.h" +#include "shad/util/measure.h" + +constexpr static size_t kSize = 1024; +using set_t = shad::Set; +using iterator = set_t::iterator; +using value_type = set_t::value_type; +using shad_inserter_t = shad::insert_iterator>; +using shad_buffered_inserter_t = + shad::buffered_insert_iterator>; + +std::pair shad_minmax_algorithm( + shad::unordered_set &in) { + auto res = shad::minmax_element(shad::distributed_parallel_tag{}, in.begin(), + in.end()); + return res; +} + +iterator shad_find_if_algorithm(shad::unordered_set &in) { + auto iter = + shad::find_if(shad::distributed_parallel_tag{}, in.begin(), in.end(), + [](const value_type &i) { return i % 2 == 0; }); + return iter; +} + +bool shad_any_of_algorithm(shad::unordered_set &in) { + auto res = + shad::any_of(shad::distributed_parallel_tag{}, in.begin(), in.end(), + [](const value_type &i) { return i % 7 == 0; }); + return res; +} + +size_t shad_count_if_algorithm(shad::unordered_set &in) { + auto counter = + shad::count_if(shad::distributed_parallel_tag{}, in.begin(), in.end(), + [](const value_type &i) { return i % 3 == 0; }); + return counter; +} + +template +void shad_transform_algorithm(shad::unordered_set &in) { + shad::unordered_set out; + shad::transform(shad::distributed_parallel_tag{}, in.begin(), in.end(), + shad_inserter(out, out.begin()), + [](const value_type &i) { return i; }); +} + +namespace shad { + +int main(int argc, char *argv[]) { + // unordered_set + shad::unordered_set set_; + + // create set + shad_buffered_inserter_t ins(set_, set_.begin()); + for (size_t i = 0; i < kSize; ++i) { + ins = 2 * (i + 1); + } + ins.wait(); + ins.flush(); + + // shad minmax algorithm + std::pair min_max; + auto execute_time = shad::measure::duration( + [&]() { min_max = shad_minmax_algorithm(set_); }); + std::cout << "Unordered set, using " << shad::rt::numLocalities() + << " localities, shad::count took " << execute_time.count() + << " seconds (min = " << *min_max.first + << ", max = " << *min_max.second << " )" << std::endl; + + // shad find_if algorithm + iterator iter; + execute_time = shad::measure::duration( + [&]() { iter = shad_find_if_algorithm(set_); }); + std::cout << "Unordered set, using " << shad::rt::numLocalities() + << " localities, shad::find_if took " << execute_time.count() + << " seconds, "; + (iter != set_.end()) + ? std::cout << "and this unordered set contains an even number" + << std::endl + : std::cout << "and this unordered set does not contain even numbers" + << std::endl; + + // shad any_of algorithm + bool res; + execute_time = shad::measure::duration( + [&]() { res = shad_any_of_algorithm(set_); }); + std::cout << "Unordered set, using " << shad::rt::numLocalities() + << " localities, shad::any_of took " << execute_time.count() + << " seconds, "; + (res == true) ? std::cout << "and this unordered set contains at least one " + "number that is divisible by 7" + << std::endl + : std::cout << "and this unordered set does not contain any " + "number that is divisible by 7" + << std::endl; + + // shad count_if algorithm + size_t counter; + execute_time = shad::measure::duration( + [&]() { counter = shad_count_if_algorithm(set_); }); + std::cout << "Unordered set, using " << shad::rt::numLocalities() + << " localities, shad::count_if took " << execute_time.count() + << " seconds, " + << "and number divisible by 3: " << counter << std::endl; + + // shad transform algorithm + execute_time = shad::measure::duration( + [&]() { shad_transform_algorithm(set_); }); + std::cout << "Unordered set, using " << shad::rt::numLocalities() + << " localities, shad::transform took " << execute_time.count() + << " seconds" << std::endl; + + return 0; +} + +} // namespace shad