Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dev/vossmjp/new examples #1519

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
4ee36b2
fixed cancellation 3, added all intro examples
Sep 16, 2024
993ed32
added intro_pi
Sep 17, 2024
c823ce5
adjusted function names to no longer name figure numbers from prior book
Sep 17, 2024
106abe8
added timing version for pi
Sep 17, 2024
51f4f83
completed files needed for algorithms chapter of new book
Sep 20, 2024
4d64f51
Merge branch 'oneapi-src:dev/vossmjp/new_examples' into dev/vossmjp/n…
jamesreinders Sep 20, 2024
6fd8f4d
add containers directory for chapter 3
Sep 23, 2024
7ed75c6
finished up needs for chapter 4
Sep 24, 2024
11bee12
finished for chatper 7
Sep 25, 2024
34d4a7b
synchronization chapter 8 done
Oct 1, 2024
2a06ab4
minor edit to align to book
Oct 1, 2024
87af567
tidy up chapter 8
Oct 2, 2024
b5d2cd1
minor touch-up for book
Oct 4, 2024
9c78697
chapter 11 cleanup
Oct 8, 2024
83addb6
chapter 10 files
Oct 9, 2024
0313a22
chapter 12 done for now - missing some examples
Oct 9, 2024
45e2e18
up to date with book draft for now
Oct 9, 2024
aa66b70
drop dpl dependency
Oct 16, 2024
485bae9
Merge branch 'dev/vossmjp/new_examples' into dev/vossmjp/new_examples
jamesreinders Oct 24, 2024
e638ee3
add const
Nov 4, 2024
3ae57c1
typo fix
Nov 8, 2024
5736754
drop oneapi in include - oops
Nov 11, 2024
38979fe
adding figure 2-24 code now that it is a figure
Nov 14, 2024
4ef5839
crude but useful - requires human judgement before using in table 8-13
Nov 17, 2024
687732e
sampe output in comments
Nov 17, 2024
43787fa
call out box code
Nov 17, 2024
8db7762
exception handling code in right place and in CMake now
Nov 17, 2024
d78ceeb
fixed names
Nov 17, 2024
321e0f9
Update concurrent_vectors.cpp
jamesreinders Dec 2, 2024
800f77b
Update histogram_02_unsafe_parallel.cpp
jamesreinders Dec 2, 2024
fbdf277
Update histogram_10_6th_safe_parallel_private.cpp
jamesreinders Dec 2, 2024
3e7a280
Update histogram_11_7th_safe_parallel_combine.cpp
jamesreinders Dec 2, 2024
2dd6547
Update histogram_11_7th_safe_parallel_combine.cpp
jamesreinders Dec 2, 2024
47a24a2
Update histogram_11_7th_safe_parallel_combine.cpp
jamesreinders Dec 2, 2024
aadcb55
Update histogram_12_8th_safe_parallel_combine.cpp
jamesreinders Dec 2, 2024
34fae40
Update histogram_11_7th_safe_parallel_combine.cpp
jamesreinders Dec 2, 2024
3b5e2a3
Update histogram_10_6th_safe_parallel_private.cpp
jamesreinders Dec 2, 2024
3d46081
Update histogram_12_8th_safe_parallel_combine.cpp
jamesreinders Dec 2, 2024
bcab38f
revised figure 3-1 code
Dec 2, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions new_examples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,13 @@ if (BUILD_TESTING)
add_subdirectory(algorithms)
add_subdirectory(cancellation)
add_subdirectory(exception)
add_subdirectory(containers)
add_subdirectory(graph)
add_subdirectory(intro)
add_subdirectory(memalloc)
add_subdirectory(migration)
add_subdirectory(performance_tuning)
add_subdirectory(synchronization)
add_subdirectory(tasks)
endif (BUILD_TESTING)

193 changes: 193 additions & 0 deletions new_examples/algorithms/3Dstereo_parallel_pipeline.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
/*
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.
*/

#define NOMINMAX

#include <iostream>
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "lodepng.h"
#include <tbb/tbb.h>

class PNGImage {
public:
uint64_t frameNumber = -1;
unsigned int width = 0, height = 0;
std::shared_ptr<std::vector<unsigned char>> buffer;
static const int numChannels = 4;
static const int redOffset = 0;
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() {}
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);

void parallel3DStereo() {
using Image = PNGImage;
using ImagePair = std::pair<PNGImage, PNGImage>;
tbb::parallel_pipeline(
/* tokens */ 8,
/* make the left image filter */
tbb::make_filter<void, Image>(
/* filter type */ tbb::filter_mode::serial_in_order,
[&](tbb::flow_control& fc) -> Image {
if (uint64_t frame_number = getNextFrameNumber()) {
return getLeftImage(frame_number);
} else {
fc.stop();
return Image{};
}
}) &
tbb::make_filter<Image, ImagePair>(
/* filter type */ tbb::filter_mode::serial_in_order,
[&](Image left) -> ImagePair {
return ImagePair(left, getRightImage(left.frameNumber));
}) &
tbb::make_filter<ImagePair, ImagePair>(
/* filter type */ tbb::filter_mode::parallel,
[&](ImagePair p) -> ImagePair {
increasePNGChannel(p.first, Image::redOffset, 10);
return p;
}) &
tbb::make_filter<ImagePair, ImagePair>(
/* filter type */ tbb::filter_mode::parallel,
[&](ImagePair p) -> ImagePair {
increasePNGChannel(p.second, Image::blueOffset, 10);
return p;
}) &
tbb::make_filter<ImagePair, Image>(
/* filter type */ tbb::filter_mode::parallel,
[&](ImagePair p) -> Image {
mergePNGImages(p.second, p.first);
return p.second;
}) &
tbb::make_filter<Image, void>(
/* filter type */ tbb::filter_mode::parallel,
[&](Image img) {
img.write();
})
);
}

PNGImage::PNGImage(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},
width{p.width}, height{p.height},
buffer{p.buffer} {}

void PNGImage::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;
}
}

static int stereo3DFrameCounter = 0;
static int stero3DNumImages = 0;

void initStereo3D(int num_images) {
stereo3DFrameCounter = 0;
stero3DNumImages = num_images;
}

int getNextFrameNumber() {
if ( stereo3DFrameCounter < stero3DNumImages ) {
return ++stereo3DFrameCounter;
} else {
return 0;
}
}

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

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

void increasePNGChannel(PNGImage& image, int channel_offset, int increase) {
const int height_base = PNGImage::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;
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;
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;

for (unsigned int y = 0; y < right.height; y++) {
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;
right_buffer[red_index] = left_buffer[red_index];
}
}
}

static void warmupTBB() {
tbb::parallel_for(0, tbb::this_task_arena::max_concurrency(), [](int) {
tbb::tick_count t0 = tbb::tick_count::now();
while ((tbb::tick_count::now() - t0).seconds() < 0.01);
});
}


int main() {
int num_images = 3;

initStereo3D(num_images);

warmupTBB();
double parallel_time = 0.0;
{
tbb::tick_count t0 = tbb::tick_count::now();
parallel3DStereo();
parallel_time = (tbb::tick_count::now() - t0).seconds();
}
std::cout << "parallel_time == " << parallel_time << " seconds" << std::endl;
return 0;
}

147 changes: 147 additions & 0 deletions new_examples/algorithms/3Dstereo_serial_no_pipeline.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
/*
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.
*/

#define NOMINMAX

#include <iostream>
#include <memory>
#include <string>
#include <vector>
#include "lodepng.h"
#include <tbb/tbb.h>

class PNGImage {
public:
uint64_t frameNumber = -1;
unsigned int width = 0, height = 0;
std::shared_ptr<std::vector<unsigned char>> buffer;
static const int numChannels = 4;
static const int redOffset = 0;
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() {}
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);

void serial3DStereo() {
while (uint64_t frameNumber = getNextFrameNumber()) {
auto left = getLeftImage(frameNumber);
auto right = getRightImage(frameNumber);
increasePNGChannel(left, PNGImage::redOffset, 10);
increasePNGChannel(right, PNGImage::blueOffset, 10);
mergePNGImages(right, left);
right.write();
}
}

PNGImage::PNGImage(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},
width{p.width}, height{p.height},
buffer{p.buffer} {}

void PNGImage::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;
}
}

static int stereo3DFrameCounter = 0;
static int stero3DNumImages = 0;

void initStereo3D(int num_images) {
stereo3DFrameCounter = 0;
stero3DNumImages = num_images;
}

int getNextFrameNumber() {
if ( stereo3DFrameCounter < stero3DNumImages ) {
return ++stereo3DFrameCounter;
} else {
return 0;
}
}

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

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

void increasePNGChannel(PNGImage& image, int channel_offset, int increase) {
const int height_base = PNGImage::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;
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;
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;

for (unsigned int y = 0; y < right.height; y++) {
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;
right_buffer[red_index] = left_buffer[red_index];
}
}
}

int main() {
int num_images = 3;

initStereo3D(num_images);

double serial_time = 0.0;
{
tbb::tick_count t0 = tbb::tick_count::now();
serial3DStereo();
serial_time = (tbb::tick_count::now() - t0).seconds();
}
std::cout << "serial_time == " << serial_time << " seconds" << std::endl;
return 0;
}

4 changes: 3 additions & 1 deletion new_examples/algorithms/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ foreach(tpp parallel_invoke_recursive_quicksort.cpp parallel_invoke_two_quicksor
parallel_reduce_max.cpp parallel_reduce_pi.cpp
parallel_scan_running_sum.cpp parallel_scan_line_of_sight.cpp
parallel_for_each_primes.cpp parallel_for_each_fwd_substition.cpp
parallel_pipeline_case.cpp)
parallel_pipeline_case.cpp parallel_sort.cpp
3Dstereo_parallel_pipeline.cpp 3Dstereo_serial_no_pipeline.cpp
serial_running_sum.cpp)
string(REPLACE ".cpp" "" texe ${tpp})
add_executable(${texe} ${tpp})
target_include_directories(${texe} PUBLIC
Expand Down
Binary file added new_examples/algorithms/input1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added new_examples/algorithms/input2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading