From 24efa990fb4b66d6a7188b8ad61d3aa23dc96c1b Mon Sep 17 00:00:00 2001 From: nanmiaowu Date: Tue, 8 Jun 2021 15:11:38 -0500 Subject: [PATCH] adding tutorial for shad array, unordered_set, unordered_map using gmt backend --- examples/CMakeLists.txt | 1 + examples/tutorial/CMakeLists.txt | 6 ++ examples/tutorial/array.cc | 161 +++++++++++++++++++++++++++++ examples/tutorial/unordered_map.cc | 149 ++++++++++++++++++++++++++ examples/tutorial/unordered_set.cc | 146 ++++++++++++++++++++++++++ 5 files changed, 463 insertions(+) create mode 100644 examples/tutorial/CMakeLists.txt create mode 100644 examples/tutorial/array.cc create mode 100644 examples/tutorial/unordered_map.cc create mode 100644 examples/tutorial/unordered_set.cc diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 5d43c4c9..c10846d0 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(tutorial) diff --git a/examples/tutorial/CMakeLists.txt b/examples/tutorial/CMakeLists.txt new file mode 100644 index 00000000..4bf3b856 --- /dev/null +++ b/examples/tutorial/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/tutorial/array.cc b/examples/tutorial/array.cc new file mode 100644 index 00000000..75cd7638 --- /dev/null +++ b/examples/tutorial/array.cc @@ -0,0 +1,161 @@ +//===------------------------------------------------------------*- 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/array.h" +#include "shad/core/algorithm.h" +#include "shad/util/measure.h" + + +constexpr static size_t kArraySize = 1024; +using iterator = shad::impl::array::array_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 [min, max] = shad::minmax_element( + shad::distributed_parallel_tag{}, + in.begin(), in.end()); + return {min, max}; +} + +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 \ No newline at end of file diff --git a/examples/tutorial/unordered_map.cc b/examples/tutorial/unordered_map.cc new file mode 100644 index 00000000..cb1ba9f5 --- /dev/null +++ b/examples/tutorial/unordered_map.cc @@ -0,0 +1,149 @@ +//===------------------------------------------------------------*- 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/util/measure.h" +#include "shad/core/unordered_map.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 [min, max] = shad::minmax_element( + shad::distributed_parallel_tag{}, + in.begin(), in.end()); + return {min, max}; +} + + +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/tutorial/unordered_set.cc b/examples/tutorial/unordered_set.cc new file mode 100644 index 00000000..0659a0ce --- /dev/null +++ b/examples/tutorial/unordered_set.cc @@ -0,0 +1,146 @@ +//===------------------------------------------------------------*- 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/util/measure.h" +#include "shad/core/unordered_set.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 [min, max] = shad::minmax_element( + shad::distributed_parallel_tag{}, + in.begin(), in.end()); + return {min, max}; +} + +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