Skip to content

Commit

Permalink
Merged from new_examples
Browse files Browse the repository at this point in the history
  • Loading branch information
vossmjp committed Dec 6, 2024
2 parents bcab38f + faf88cb commit 2ba2c23
Show file tree
Hide file tree
Showing 42 changed files with 1,816 additions and 261 deletions.
13 changes: 11 additions & 2 deletions new_examples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,17 @@ cmake_minimum_required (VERSION 3.4)

project(tbb_tutorials LANGUAGES CXX)

set(CMAKE_CXX_COMPILER "icpx")
set(CMAKE_LINKER "icpx")
if (WIN32)
set(CMAKE_CXX_COMPILER "icx-cl")
set(CMAKE_LINKER "icpx")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Qtbb")
set(CMAKE_CXX_LINKER_FLAGS "-Qtbb")
else()
set(CMAKE_CXX_COMPILER "icpx")
set(CMAKE_LINKER "icpx")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -tbb")
set(CMAKE_CXX_LINKER_FLAGS "-tbb -lpthread")
endif()
set(CMAKE_CXX_STANDARD 20)

include (CTest)
Expand Down
3 changes: 0 additions & 3 deletions new_examples/algorithms/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -tbb")
set(CMAKE_CXX_LINKER_FLAGS "-tbb")

foreach(tpp parallel_invoke_recursive_quicksort.cpp parallel_invoke_two_quicksorts.cpp
parallel_for_trivial.cpp parallel_for_unoptimized_mxm.cpp
parallel_reduce_max.cpp parallel_reduce_pi.cpp
Expand Down
3 changes: 3 additions & 0 deletions new_examples/algorithms/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Chapter 2: Algorithms

This directory contains the examples for Chapter 2.
3 changes: 0 additions & 3 deletions new_examples/cancellation/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -tbb")
set(CMAKE_CXX_LINKER_FLAGS "-tbb")

foreach(tpp cancel_group_execution1.cpp
cancel_group_execution2.cpp
cancel_group_execution3.cpp
Expand Down
9 changes: 3 additions & 6 deletions new_examples/exception/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -tbb")
set(CMAKE_CXX_LINKER_FLAGS "-tbb")

foreach(tpp cpp_exceptions.cpp
exception_catch1.cpp
exception_catch2.cpp)
foreach(tpp exception_catch1.cpp
exception_catch2.cpp
exception_catch3.cpp)
string(REPLACE ".cpp" "" texe ${tpp})
add_executable(${texe} ${tpp})
target_include_directories(${texe} PUBLIC
Expand Down
4 changes: 1 addition & 3 deletions new_examples/graph/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -tbb")
set(CMAKE_CXX_LINKER_FLAGS "-tbb")

foreach(tpp graph_composite_node.cpp
graph_execute_while_building.cpp
graph_fwd_substitution.cpp
Expand All @@ -10,6 +7,7 @@ foreach(tpp graph_composite_node.cpp
graph_node_priorities.cpp
graph_reestablish_order.cpp
graph_small_nodes.cpp
graph_stereoscopic_3d.cpp
graph_two_nodes.cpp
graph_two_nodes_deduced.cpp
graph_with_join.cpp)
Expand Down
26 changes: 16 additions & 10 deletions new_examples/graph/graph_execute_while_building.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,23 +16,25 @@

#include <iostream>
#include <memory>
#include <vector>
#include <tbb/tbb.h>

struct config_t {
int id;
int predecessor;
};

config_t configuration[] = { { 0, 3 },
{ 1, 4 },
{ 2, 5 },
{ 3, -1 },
{ 4, -1 },
{ 5, 3 },
{ 6, 4 },
{ 7, 1 } };
// each element defines a node and what other node it must wait for
std::vector<config_t> configuration = { { 0, 3 },
{ 1, 4 },
{ 2, 5 },
{ 3, -1 },
{ 4, -1 },
{ 5, 3 },
{ 6, 4 },
{ 7, 1 } };

int num_nodes = sizeof(configuration) / sizeof(config_t);
const int num_nodes = configuration.size();

int main() {
tbb::flow::graph g;
Expand All @@ -57,14 +59,18 @@ int main() {
return m;
}
});
// connect the new node to its future
// connect the new node to its "future"
tbb::flow::make_edge(*work_nodes[c.id], future_nodes[c.id]);

// start the node or link it to predecessor's promise
if (c.predecessor != -1) {
// must connect to predecessor's "future"
// if the future is already written to this will start the node
// otherwise it will be started when the future is written
std::printf("new %d with %d -> %d\n", c.id, c.predecessor, c.id);
tbb::flow::make_edge(future_nodes[c.predecessor], *work_nodes[c.id]);
} else {
// does not need to wait and can be started immediately
std::printf("starting %d from main\n", c.id);
work_nodes[c.id]->try_put(tbb::flow::continue_msg{});
}
Expand Down
3 changes: 1 addition & 2 deletions new_examples/graph/graph_loops.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,7 @@ void tryPutLoop() {
}
};
for (int count = 0; count < limit; ++count) {
int value = count;
my_node.try_put(value);
my_node.try_put(count);
}
g.wait_for_all();
}
Expand Down
6 changes: 3 additions & 3 deletions new_examples/graph/graph_small_nodes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,9 @@ void small_nodes_lightweight() {
tbb::flow::function_node< int, int > add( g, tbb::flow::unlimited,
[](const int &v) { return v+1; } );
tbb::flow::function_node< int, int, tbb::flow::lightweight > multiply( g, tbb::flow::unlimited,
[](const int &v) { return v*2; } );
[](const int &v) noexcept { return v*2; } );
tbb::flow::function_node< int, int, tbb::flow::lightweight > cube( g, tbb::flow::unlimited,
[](const int &v) { return v*v*v; } );
[](const int &v) noexcept { return v*v*v; } );

tbb::flow::make_edge(add, multiply);
tbb::flow::make_edge(multiply, cube);
Expand All @@ -73,7 +73,7 @@ void small_nodes_combined_lightweight() {
tbb::flow::graph g;

tbb::flow::function_node< int, int, tbb::flow::lightweight > combined_node( g, tbb::flow::unlimited,
[](const int &v) {
[](const int &v) noexcept {
auto v2 = (v+1)*2;
return v2*v2*v2;
});
Expand Down
52 changes: 26 additions & 26 deletions new_examples/graph/graph_stereoscopic_3d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@
#include <string>
#include <utility>
#include <vector>
#include "../algorithms/lodepng.h"
#include "../common/lodepng.h"
#include <tbb/tbb.h>

class PNGImage {
class Image {
public:
uint64_t frameNumber = -1;
unsigned int width = 0, height = 0;
Expand All @@ -34,26 +34,26 @@ class PNGImage {
static const int greenOffset = 1;
static const int blueOffset = 2;

PNGImage() {}
PNGImage(uint64_t frame_number, const std::string& file_name);
PNGImage(const PNGImage& p);
virtual ~PNGImage() {}
Image() {}
Image(uint64_t frame_number, const std::string& file_name);
Image(const Image& p);
virtual ~Image() {}
void write() const;
};

int getNextFrameNumber();
PNGImage getLeftImage(uint64_t frameNumber);
PNGImage getRightImage(uint64_t frameNumber);
void increasePNGChannel(PNGImage& image, int channel_offset, int increase);
void mergePNGImages(PNGImage& right, const PNGImage& left);
Image getLeftImage(uint64_t frameNumber);
Image getRightImage(uint64_t frameNumber);
void increasePNGChannel(Image& image, int channel_offset, int increase);
void mergeImages(Image& right, const Image& left);

void stereo3D() {
using Image = PNGImage;
using Image = Image;
// step 1: create graph object
tbb::flow::graph g;

// step 2: create nodes
tbb::flow::input_node<uint64_t> frame_no_node{g,
tbb::flow::input_node frame_no_node{g,
[]( tbb::flow_control &fc ) -> uint64_t {
uint64_t frame_number = getNextFrameNumber();
if (frame_number)
Expand Down Expand Up @@ -99,7 +99,7 @@ void stereo3D() {
[] (std::tuple<Image, Image> t) -> Image {
auto& l = std::get<0>(t);
auto& r = std::get<1>(t);
mergePNGImages(r, l);
mergeImages(r, l);
return r;
}
};
Expand Down Expand Up @@ -128,19 +128,19 @@ void stereo3D() {
g.wait_for_all();
}

PNGImage::PNGImage(uint64_t frame_number, const std::string& file_name) :
Image::Image(uint64_t frame_number, const std::string& file_name) :
frameNumber{frame_number}, buffer{std::make_shared< std::vector<unsigned char> >()} {
if (lodepng::decode(*buffer, width, height, file_name)) {
std::cerr << "Error: could not read PNG file!" << std::endl;
width = height = 0;
}
};

PNGImage::PNGImage(const PNGImage& p) : frameNumber{p.frameNumber},
Image::Image(const Image& p) : frameNumber{p.frameNumber},
width{p.width}, height{p.height},
buffer{p.buffer} {}

void PNGImage::write() const {
void Image::write() const {
std::string file_name = std::string("out") + std::to_string(frameNumber) + ".png";
if (lodepng::encode(file_name, *buffer, width, height)) {
std::cerr << "Error: could not write PNG file!" << std::endl;
Expand All @@ -163,30 +163,30 @@ int getNextFrameNumber() {
}
}

PNGImage getLeftImage(uint64_t frameNumber) {
return PNGImage(frameNumber, "input1.png");
Image getLeftImage(uint64_t frameNumber) {
return Image(frameNumber, "input1.png");
}

PNGImage getRightImage(uint64_t frameNumber) {
return PNGImage(frameNumber, "input2.png");
Image getRightImage(uint64_t frameNumber) {
return Image(frameNumber, "input2.png");
}

void increasePNGChannel(PNGImage& image, int channel_offset, int increase) {
const int height_base = PNGImage::numChannels * image.width;
void increasePNGChannel(Image& image, int channel_offset, int increase) {
const int height_base = Image::numChannels * image.width;
std::vector<unsigned char>& buffer = *image.buffer;

// Increase selected color channel by a predefined value
for (unsigned int y = 0; y < image.height; y++) {
const int height_offset = height_base * y;
for (unsigned int x = 0; x < image.width; x++) {
int pixel_offset = height_offset + PNGImage::numChannels * x + channel_offset;
int pixel_offset = height_offset + Image::numChannels * x + channel_offset;
buffer[pixel_offset] = static_cast<uint8_t>(std::min(buffer[pixel_offset] + increase, 255));
}
}
}

void mergePNGImages(PNGImage& right, const PNGImage& left) {
const int channels_per_pixel = PNGImage::numChannels;
void mergeImages(Image& right, const Image& left) {
const int channels_per_pixel = Image::numChannels;
const int height_base = channels_per_pixel * right.width;
std::vector<unsigned char>& left_buffer = *left.buffer;
std::vector<unsigned char>& right_buffer = *right.buffer;
Expand All @@ -195,7 +195,7 @@ void mergePNGImages(PNGImage& right, const PNGImage& left) {
const int height_offset = height_base * y;
for (unsigned int x = 0; x < right.width; x++) {
const int pixel_offset = height_offset + channels_per_pixel * x;
const int red_index = pixel_offset + PNGImage::redOffset;
const int red_index = pixel_offset + Image::redOffset;
right_buffer[red_index] = left_buffer[red_index];
}
}
Expand Down
2 changes: 1 addition & 1 deletion new_examples/graph/graph_two_nodes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ void graphTwoNodes() {
// step 3: add edges
tbb::flow::make_edge(my_first_node, my_second_node);

// step 4: send messages
// step 4: send message that eagerly starts graph execution
my_first_node.try_put(10);

// step 5: wait for graph to complete
Expand Down
2 changes: 1 addition & 1 deletion new_examples/graph/graph_with_join.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ void graphJoin() {
make_edge(my_other_node, tbb::flow::input_port<1>(my_join_node));
make_edge(my_join_node, my_final_node);

// step 4: send messages
// step 4: send messages that eagerly start graph execution
my_node.try_put(1);
my_other_node.try_put(2);
// step 5: wait for the graph to complete
Expand Down
3 changes: 0 additions & 3 deletions new_examples/intro/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -tbb")
set(CMAKE_CXX_LINKER_FLAGS "-tbb")

foreach(tpp intro_pi.cpp
intro_pi_timing.cpp
intro_flowgraph.cpp
Expand Down
6 changes: 2 additions & 4 deletions new_examples/migration/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -tbb -pthread")
set(CMAKE_CXX_LINKER_FLAGS "-tbb -pthread")

foreach(tpp migrate_task_scheduler_init.cpp
foreach(tpp migrate_atomics.cpp
migrate_task_scheduler_init.cpp
migrate_parallel_do.cpp
migrate_priorities.cpp
migrate_task_blocking.cpp
Expand Down
80 changes: 80 additions & 0 deletions new_examples/migration/migrate_atomics.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/*
Copyright (c) 2024 Intel Corporation
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 <vector>
#include <iostream>
#include <algorithm>
#include <random>

#include <tbb/tick_count.h>
#include <tbb/parallel_for.h>

#if TBB_VERSION_MAJOR > 2020
#include <atomic>
#else
#include <tbb/atomic.h>
#endif

int main(int argc, char** argv) {
long int n = 1000000000;
constexpr int num_bins = 256;

// Initialize random number generator
std::random_device seed; // Random device seed
std::mt19937 mte{seed()}; // mersenne_twister_engine
std::uniform_int_distribution<> uniform{0,num_bins};
// Initialize image
std::vector<uint8_t> image; // empty vector
image.reserve(n); // image vector prealocated
std::generate_n(std::back_inserter(image), n,
[&] { return uniform(mte); }
);
// Initialize histogram
std::vector<int> hist(num_bins);

// Serial execution
tbb::tick_count t0 = tbb::tick_count::now();
std::for_each(image.begin(), image.end(),
[&](uint8_t i){hist[i]++;});
tbb::tick_count t1 = tbb::tick_count::now();
double t_serial = (t1 - t0).seconds();

// Parallel execution
#if TBB_VERSION_MAJOR > 2020
std::vector<std::atomic<int>> hist_p(num_bins);
#else
#warning Using tbb::atomic instead of std::atomic
std::vector<tbb::atomic<int>> hist_p(num_bins);
#endif

t0 = tbb::tick_count::now();
parallel_for(tbb::blocked_range<size_t>{0, image.size()},
[&](const tbb::blocked_range<size_t>& r)
{
for (size_t i = r.begin(); i < r.end(); ++i)
hist_p[image[i]]++;
});
t1 = tbb::tick_count::now();
double t_parallel = (t1 - t0).seconds();

std::cout << "Serial: " << t_serial << ", ";
std::cout << "Parallel: " << t_parallel << ", ";
std::cout << "Speed-up: " << t_serial/t_parallel << std::endl;

if (!std::equal(hist.begin(),hist.end(),hist_p.begin()))
std::cerr << "Parallel computation failed!!" << std::endl;
return 0;
}
Loading

0 comments on commit 2ba2c23

Please sign in to comment.